Goglides Dev 🌱

Balkrishna Pandey
Balkrishna Pandey

Posted on • Updated on

Using the OpenShift Internal Registry: Route Exposure to Internal Service Deployment

OpenShift’s internal registry provides a robust and secure way to manage container images. In this blog post, I'll walk through configuring the registry, exposing it as a route, pushing an Nginx image, and deploying the image using the internal service object for efficient and seamless operations.

1. Configure the OpenShift Internal Registry

The OpenShift internal registry is managed by the cluster’s image registry operator. To get started, ensure the registry is properly configured and verify its status.

Run the following command to check the registry configuration:

oc get configs.imageregistry.operator.openshift.io/cluster -o yaml
Enter fullscreen mode Exit fullscreen mode

Ensure the managementState is set to Managed and the registry has a storage backend configured (e.g., Persistent Volume)

apiVersion: imageregistry.operator.openshift.io/v1
kind: Config
metadata:
  name: cluster
spec:
  defaultRoute: true
  logLevel: Normal
  managementState: Managed
  observedConfig: null
  operatorLogLevel: Normal
  proxy: {}
  replicas: 2
  requests:
    read:
      maxWaitInQueue: 0s
    write:
      maxWaitInQueue: 0s
  rolloutStrategy: RollingUpdate
  storage:
    managementState: Unmanaged
    pvc:
      claim: registry-storage-pv-claim
  unsupportedConfigOverrides: null
Enter fullscreen mode Exit fullscreen mode

2. Expose the Registry as a Route

To push images externally, expose the registry using a route. OpenShift automatically creates a default route for the registry if enabled.

Patch the registry configuration to enable the default route, if its not already enabled.

oc patch configs.imageregistry.operator.openshift.io/cluster --type merge -p '{"spec":{"defaultRoute":true}}'
Enter fullscreen mode Exit fullscreen mode

Verify

REGISTRY_ROUTE=$(oc get route -n openshift-image-registry default-route -o jsonpath='{.spec.host}')
echo "Registry Route: $REGISTRY_ROUTE"
Enter fullscreen mode Exit fullscreen mode

The registry will be accessible at https://<REGISTRY_ROUTE>.

3. Push an Nginx Image to the Internal Registry

Now that the registry is exposed, let’s push the Nginx image to a project in OpenShift.

Step 1: Create and Configure a Service Account

First, create a dedicated service account for pushing images and assign the necessary roles:

# oc new-project demo # Assuming we are using this project to operate
# Create a service account
oc create serviceaccount image-pusher -n demo

# Grant the system:image-pusher and edit roles to the service account
oc policy add-role-to-user edit system:serviceaccount:demo:image-pusher -n demo
Enter fullscreen mode Exit fullscreen mode

Step 2: Get the Registry Route

Retrieve the OpenShift internal registry route dynamically:

REGISTRY_ROUTE=$(oc get route -n openshift-image-registry default-route -o jsonpath='{.spec.host}')
echo "Registry Route: $REGISTRY_ROUTE"
Enter fullscreen mode Exit fullscreen mode

Step 3: Authenticate Using the Service Account

Log in to the registry using the service account token:

podman login --tls-verify=false $REGISTRY_ROUTE \
  --username image-pusher \
  --password $(oc create token image-pusher -n demo)
Enter fullscreen mode Exit fullscreen mode

You should see:

Login Succeeded!
Enter fullscreen mode Exit fullscreen mode

Step 4: Tag the Image

Pull the Nginx image locally and tag it for the OpenShift internal registry:

podman pull nginxinc/nginx-unprivileged:latest
podman tag nginxinc/nginx-unprivileged:latest $REGISTRY_ROUTE/demo/nginx-unprivileged:latest
Enter fullscreen mode Exit fullscreen mode

Step 5: Push the Image

Push the tagged image to the OpenShift internal registry:

podman push --tls-verify=false $REGISTRY_ROUTE/demo/nginx-unprivileged:latest
Enter fullscreen mode Exit fullscreen mode

Step 6: Verify the Push

Confirm the image is successfully pushed by listing the image streams in the project:

oc get imagestreams -n demo
Enter fullscreen mode Exit fullscreen mode

You should see the nginx image listed with the appropriate tags.

4. Deploy the Nginx Image Using the Internal Service Object

Using the internal service object avoids the need for external routes and automatically manages certificates.

Step 1: Reference the Internal Service

The internal service for the registry is available at:

image-registry.openshift-image-registry.svc.cluster.local:5000
Enter fullscreen mode Exit fullscreen mode

You can directly reference your image in this format:

image-registry.openshift-image-registry.svc.cluster.local:5000/<PROJECT>/nginx:latest
Enter fullscreen mode Exit fullscreen mode

Step 2: Grant Image Pull Access

Service accounts require an image pull secret to access the OpenShift internal registry. Follow these steps:

  • Create an ImagePullSecret: Generate a pull secret for the internal registry using your credentials or service account token:
oc create secret docker-registry image-pull-secret \
  --docker-server=image-registry.openshift-image-registry.svc.cluster.local:5000 \
  --docker-username=serviceaccount \
  --docker-password=$(oc whoami -t) \
  --docker-email=unused \
  -n demo
Enter fullscreen mode Exit fullscreen mode
  • Link the Secret to the Service Account: Attach the image-pull-secret to the service account used by your pod (e.g., default):
oc secrets link default image-pull-secret --for=pull -n demo
Enter fullscreen mode Exit fullscreen mode
  • Grant Image Pull Permissions Ensure that the service account pulling the image has permission to access it. Grant the system:image-puller role to the service account:
oc policy add-role-to-user system:image-puller system:serviceaccount:demo:default -n demo
Enter fullscreen mode Exit fullscreen mode

Replace default with the service account name if you use a custom service account.

Step 3: Create a Deployment

Deploy the Nginx container using the internal service object:

cat <<EOF | oc apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: demo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: image-registry.openshift-image-registry.svc.cluster.local:5000/demo/nginx-unprivileged:latest
        ports:
        - containerPort: 80
EOF
Enter fullscreen mode Exit fullscreen mode

Verify pod is running.

oc get pods -n demo
Enter fullscreen mode Exit fullscreen mode

5. Configure OpenShift to Trust the Registry Certificate

Configure OpenShift to Trust the Registry Certificate
To ensure secure communication with the OpenShift internal registry, it is essential to configure the cluster to trust the registry's certificate. Here’s how to generate the required certificate and integrate it into OpenShift:

Step 1: Extract the Certificate from the Registry Route

openssl s_client -connect <route-registry-name>:443 -showcerts </dev/null 2>/dev/null | openssl x509 -outform PEM > ca.crt
Enter fullscreen mode Exit fullscreen mode

Replace <route-registry-name> with the name of your registry route (e.g., default-route-openshift-image-registry.apps.cloud.domain.dfw.ocp.run).

Step 2: Create a ConfigMap with the Certificate

oc create configmap registry-cas -n openshift-config --from-file=<route-registry-name>=/etc/docker/certs.d/<route-registry-name>/ca.crt
Enter fullscreen mode Exit fullscreen mode

Ensure the <route-registry-name> matches the hostname of the registry route used in the previous step.

Step 3: Update the Cluster’s Trusted CA

Patch the cluster’s image configuration to include the ConfigMap created above:

oc patch image.config.openshift.io/cluster --patch '{"spec":{"additionalTrustedCA":{"name":"registry-cas"}}}' --type=merge
Enter fullscreen mode Exit fullscreen mode

Top comments (0)