Image Registry Operator

This operator is installed by default with every OpenShift cluster. For it to work you simply need to allocate storage (PV) and a PVC. This can be accomplished with the local storage operator and or ODF or External Storage (NFS).

Configure the storage claim

  1. Change project

    oc project openshift-image-registry
    
  2. Set image registry to Managed by patching the config

    oc patch configs.imageregistry.operator.openshift.io cluster --type merge --patch '{"spec":{"managementState":"Managed"}}'
    
  3. Add the PVC by editing the image registry config

    oc patch configs.imageregistry.operator.openshift.io cluster --type merge --patch '{"spec":{"storage":{"pvc":{"claim":""}}}}'
    
    # Replace the "storage: {}" line with the following
    #
    # spec:
    #   storage:
    #     pvc:
    #       claim:
    
  4. Check pvc STATUS = “Bound”. This step may fail if not using a storage class with RWX (ReadWriteMany) access mode.

    oc get pvc
    
  5. If the pvc is “Pending” due to the default storage class, the pvc will need to be modified. The “accessModes” must match. Block type storage uses RWO (ReadWriteOnce).

    Important

    When using the Local Storage Operator, NOT ODF. This step will need to be taken. The pvc needs to match the pv’s “storageClassName”, “accessModes”, and “storage”.

    1. Copy the current pvc to yaml file.

      oc get -n openshift-image-registry pvc image-registry-storage -o yaml > image-registry-storage.yaml
      
    2. Delete the pvc.

      oc delete -n openshift-image-registry pvc image-registry-storage
      
    3. Edit the previously saved file “image-registry-storage.yaml”.

      apiVersion: v1
      kind: PersistentVolumeClaim
      metadata:
        annotations:
          imageregistry.openshift.io: "true"
          volume.beta.kubernetes.io/storage-provisioner: openshift-storage.rbd.csi.ceph.com
          volume.kubernetes.io/storage-provisioner: openshift-storage.rbd.csi.ceph.com
        finalizers:
        - kubernetes.io/pvc-protection
        name: image-registry-storage
        namespace: openshift-image-registry
      spec:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 100Gi
        storageClassName: lso-fs
        volumeMode: Filesystem
      
    4. Create the new pvc:

      oc create -f image-registry-storage.yaml
      

Set the default route

  1. Set the defaultRoute to true

    oc patch configs.imageregistry.operator.openshift.io/cluster --type=merge --patch '{"spec":{"defaultRoute":true}}'
    
  2. Get the default registry route

    REGROUTE=$(oc get route default-route -n openshift-image-registry --template='{{ .spec.host }}')
    
  3. Get the cluster’s default certificate and add to the clients local ca-trust

    oc get secret -n openshift-ingress router-certs-default -o go-template='{{index .data "tls.crt"}}' | \
      base64 -d | sudo tee /etc/pki/ca-trust/source/anchors/${REGROUTE}.crt  > /dev/null
    
  4. Update the clients local ca-trust

    sudo update-ca-trust
    
  5. Log in with podman using the default route. You’ll need to login to your cluster with “kubeadmin” first in order to receive a user token.

    oc login -u kubeadmin
    
    podman login -u kubeadmin -p $(oc whoami -t) $REGROUTE
    

    Should see the following output:

    Login Succeeded!
    

    Note

    If an error is returned as well, it’s because “oc whoami -t” does not have a token. Try logging into the cluster first.

Upload Image

  1. Log in into OpenShift API with user that has appropriate permissions.

    oc login -u kubeadmin
    
  2. Log into registry via external route.

    REGROUTE=$(oc get route default-route -n openshift-image-registry --template='{{ .spec.host }}')
    
    podman login -u kubeadmin -p $(oc whoami -t) $REGROUTE
    
  3. Upload image to local repo

    podman pull mirror.lab.local:8443/f5devcentral/f5-hello-world
    

    Tip

    To import a tarball

    podman image load -i <tarball>
    
  4. Tag local image for OCP registry

    Attention

    The path must start with the project name. In this example I’m using project “default”.

    podman tag mirror.lab.local:8443/f5devcentral/f5-hello-world:latest $REGROUTE/default/f5-hello-world:latest
    

    Tip

    Tag multiple images

    for image in $(podman images --format "{{.Repository}}:{{.Tag}}" | \
      grep localhost | sed 's/^localhost\///'); \
      do podman tag $image $REGROUTE/default/$image; done
    

    Remove new tags

    for image in $(podman images --format "{{.Repository}}:{{.Tag}}" | \
      grep -v localhost); do podman rmi $image; done
    
  5. Push local image to OCP registry

    Attention

    The project must exist in order to upload the image. In this example I’m using project “default”.

    podman push $REGROUTE/default/f5-hello-world:latest
    

    Tip

    Push multiple images

    for image in $(podman images --format "{{.Repository}}:{{.Tag}}" | \
      grep -v localhost); do podman push $image; done
    
  6. View image on OCP registry

    oc get is -n default
    
    ../_images/imageuploadexample.png
  7. Access the image/registry directly from a cluster node

    ssh core@host11
    
    oc login -u kubeadmin https://api-int.ocp1.lab.local:6443
    
    podman login -u kubeadmin -p $(oc whoami -t) image-registry.openshift-image-registry.svc:5000
    
    podman pull image-registry.openshift-image-registry.svc:5000/default/f5-hello-world
    
  8. Use the internal name for deployments

    spec:
      containers:
      - env:
        - name: service_name
          value: f5-hello-world-web
        #image: mirror.lab.local:8443/f5devcentral/f5-hello-world:latest
        #image: default-route-openshift-image-registry.apps.ocp1.lab.local/default/f5-hello-world:latest
        image: image-registry.openshift-image-registry.svc:5000/default/f5-hello-world:latest
        imagePullPolicy: Always
        name: f5-hello-world-web