Configure a project in an IBM Cloud Red Hat OpenShift cluster to access the IBM Cloud Container Registry

This cheat sheet is about, how to configure a project in an IBM Cloud Red Hat OpenShift to access the IBM Cloud Container Registry. We use an image pull secret to access container images from IBM Cloud Container Registries. The cheat sheet combines different steps, which are available in the IBM Cloud documentation you find here.

We configure a created project in OpenShift to access two different IBM Cloud Container Registries.

The IBM Cloud Red Hat OpenShift cluster is a part of IBM Cloud Account ONE.

The image below shows a simplified architecture overview:

Note: The cheat sheet references to source code, which is available in that example GitHub project. In case you want to follow the steps, you can clone the GitHub project to your local computer.

The blog post is organized in five following sections:

  1. Setup the IBM Cloud Container Registry of IBM Cloud Account TWO
  2. Build and push the container image to the IBM Cloud Container Registry of IBM Cloud Account TWO
  3. Configure the OpenShift project to access the IBM Cloud Container Registry of IBM Cloud Account ONE
  4. Configure the OpenShift project to access the IBM Cloud Container Registry of IBM Cloud Account TWO
  5. Deploy the container image to the OpenShift project

1. Setup the IBM Cloud Container Registry of IBM Cloud Account TWO

On our local computer we use the IBM Cloud CLI and the IBM Cloud "container-registry" CLI plug-in for the configuration of the container registry, and Docker to build and push the image.

Step 1: Log in to IBM Cloud (IBM Cloud Account TWO)

ibmcloud login (-sso)

Step 2: Log in to IBM Cloud Container Registry

ibmcloud cr login

Example output:

Logging in to ''...
Logged in to ''.

Step 3: Create a Namespace inside the IBM Cloud Container Registry

Let us name the Namespacevend-openshift.

ibmcloud cr namespace-add vend-openshift

2. Build and push the container image to the IBM Cloud Container Registry (IBM Cloud Account TWO)

Now we build the container image locally and push the image to the IBM Cloud Container Registry.

Step 1: Build the container image locally

We name our container image close to the naming convention of Red Hat.

Format <Registry[:Port]>/<Namespace>/<image>:<tag>

We use the us region (us) of the container registry, with the newly created namespace called vend-openshift

docker build -t "" -f Dockerfile .

Step 2: Push the container image to the IBM Cloud Container Registry

docker push ""

Step 3: List the existing container images

ibmcloud cr image-list

3. Configure the OpenShift project to access the IBM Cloud Container Registry of IBM Cloud Account ONE

Now we will configure the newly created OpenShift project to access the IBM Cloud Container Registry from IBM Cloud Account ONE. The following image is a simplified architecture overview:

Step 1: Log in to the OpenShift custer

Step 2: Get the existing projects

oc get projects

Step 3: Create a new project

Name the project vend-ibm

oc new-project vend-ibm

Step 3: Get the existing secrect for the IBM Cloud Container Registry (icr-io) from the default project in the OpenShift cluster

The secrect is called all-icr-io. (i[IBM]c[Container].r[Registry].io)

oc get secrets -n default | grep icr-io

Example output:

all-icr-io                        1      5d21h

Step 4: Copy the all-icr-io image pull secret from the default project to our newly created.

oc get secret all-icr-io -n default -o yaml | sed 's/default/vend-ibm/g' | oc create -n vend-ibm -f -  

In the secret content we do rename the namespace value from default to vend-ibm the yaml below.

apiVersion: v1
  .dockerconfigjson: aU5LifX19Q1g
kind: Secret
  annotations: '{"apiVersion":"v1","data":{".dockerconfigjson":"eyJ1TmlJTUo4aVpxnekdzdZKaU5LQ1gifX19"},"kind":"Secret","metadata":{"name":"all-icr-io","namespace":"default"},"type":""}'
  creationTimestamp: "2021-10-29T16:33:57Z"
  - apiVersion: v1
    fieldsType: FieldsV1
        .: {}
        f:.dockerconfigjson: {}
          .: {}
      f:type: {}
    manager: OpenAPI-Generator
    operation: Update
    time: "2021-10-29T16:33:57Z"
  name: all-icr-io
  namespace: default
  resourceVersion: "5381"
  selfLink: /api/v1/namespaces/default/secrets/all-icr-io
  uid: 30defa59-8890-f-a51f-565ee8291c34

Note: In the future we will use following format <project_name>-icr-<region>-io for secret names related to container registries.

Step 5: Verify that the secret is copied/created successfully to the new project.

Now we can use the default associated IBM Cloud Container Registry as an input for our deployments.

oc get secrets -n vend-ibm | grep icr-io

Example output:

all-icr-io               1      87s

4. Configure the OpenShift project to access the IBM Cloud Container Registry of IBM Cloud Account TWO and deploy the container image to OpenShift

The following image shows a simplified architecture overview:

Note: For more details please visit the IBM Cloud documentation Creating an image pull secret with different IAM API key credentials for more control or access to images in other IBM Cloud accounts.

Step 1: Check if an image pull secret already exists for your default service account.

oc describe serviceaccount default -n vend-ibm

Example output:

In our example we have Image pull secrets: default-dockercfg-76z7g.

Name:                default
Namespace:           vend-ibm
Labels:              <none>
Annotations:         <none>
Image pull secrets:  default-dockercfg-76z7g
Mountable secrets:   default-token-7zkd7
Tokens:              default-token-7zkd7
Events:              <none>

Step 2: Log on to IBM Cloud Account TWO

ibmcloud login [-sso]

Step 3: Create an IAM new service id

I like the naming convention <cluster_name>-<project>-id, which is provided by the IBM Cloud documentation. In this our the name of the service id is <roks-gen2-suedbro>-<vend-ibm>-id.

ibmcloud iam service-id-create <cluster_name>-<project>-id --description "Service ID for IBM Cloud Container Registry in cluster <cluster_name> project <project>"

Example command:

ibmcloud iam service-id-create roks-gen2-suedbro-vend-ibm-id --description "Service ID for IBM Cloud Container Registry in cluster roks-gen2-suedbro project vend-ibm"

Example output:

Service ID roks-gen2-suedbro-vend-ibm-id is created successfully
ID            ServiceId-57b78691-24a7-48f1-b263-b1cbad87cbc0   
Name          roks-gen2-suedbro-vend-ibm-id   
Description   Service ID for IBM Cloud Container Registry in cluster roks-gen2-suedbro project vend-ibm   
CRN           crn:v1:bluemix:public:iam-identity::a/641ebfffbac35c8385e1d79b45279e::serviceid:ServiceId-57b78691-24a7-48f1-b263-b1cbad87cbc0   
Version       1-be4cfdb528d201078035b25a81ec7f44   
Locked        false 

Step 4: Create a custom IBM Cloud IAM policy for the newly created cluster service ID that grants access to IBM Cloud Container Registry.

ibmcloud iam service-policy-create <cluster_service_ID> --roles <service_access_role> --service-name container-registry [--region <IAM_region>] [--resource-type namespace --resource <registry_namespace>]

ibmcloud iam service-policy-create roks-gen2-suedbro-vend-ibm-id --roles Manager --service-name container-registry --region us-south --resource-type namespace --resource vend-openshift

Example output:

Creating policy under current account for service ID roks-gen2-suedbro-vend-ibm-id as thomas.suedbroecker@...
Service policy is successfully created
Policy ID:   33748d99-ae5c-ed42-9c-5c7e96e836a3   
Version:     1-c3692a57cc9c45043965c6f44e2eda   
Roles:       Manager   
             Service Name    container-registry      
             Region          us-south      
             Resource Type   namespace      
             Resource        vend-openshift 

Step 5: Create an image pull secret to save the API key credentials in the newly created OpenShift project.

We need following parameters and values for the oc command:

  • <project> : Project name vend-ibm
  • <secret_name> : We reuse service policy name roks-gen2-suedbro-vend-ibm-id.
  • <registry_URL> : That is our URL
  • <api_key_value> : We need to create an new IAM Key.
  • <docker_email> : We should insert an email address.
oc --namespace <project> create secret docker-registry <secret_name> --docker-server=<registry_URL> --docker-username=iamapikey --docker-password=<api_key_value> --docker-email=<docker_email>

  • Create an IAM Key
ibmcloud iam api-key-create ibmapikey-roks-gen2-suedbro-vend-ibm-id 

Example output:

Creating API key ibmapikey-roks-gen2-suedbro-vend-ibm-id under 641ebfffbac35c8385ee21d79b45279e as thomas.suedbroecker@...
API key ibmapikey-roks-gen2-suedbro-vend-ibm-id was created
Please preserve the API key! It cannot be retrieved after it's created.
ID            ApiKey-d79d7054-7e2e-4bea-b718-b58fa956acc7   
Name          ibmapikey-roks-gen2-suedbro-vend-ibm-id   
Created At    2021-11-04T18:33+0000   
API Key       17CcgFyamcB7o3SNZysNoMD4RZNUCUimd2360Y   
Locked        false  

  • Set region <region> to
  • Execute the command
oc --namespace vend-ibm create secret docker-registry roks-gen2-suedbro-vend-ibm-id --docker-username=iamapikey --docker-password=17CcgFyamcB7ysqNoMD4RZNUCUimd2360Y --docker-email=thomas.suedbroecker@

This is our registry secret name “roks-gen2-suedbro-vend-ibm-id” we will use later.

Example output:

secret/roks-gen2-suedbro-vend-ibm-id created

  • Verify created secret in the project
oc get secrets --namespace vend-ibm

Example output:

NAME                            TYPE                                  DATA   AGE
all-icr-io                    1      4h35m
builder-dockercfg-qrksw               1      5h8m
builder-token-9gjlf      4      5h8m
builder-token-dlxrr      4      5h8m
default-dockercfg-76z7g               1      5h8m
default-token-7zkd7      4      5h8m
default-token-hvgg9      4      5h8m
deployer-dockercfg-9l5p9               1      5h8m
deployer-token-6whjj     4      5h8m
deployer-token-wnh5k     4      5h8m
pipeline-dockercfg-6cncv               1      5h8m
pipeline-token-ptk4t     4      5h8m
pipeline-token-sr2x7     4      5h8m
roks-gen2-suedbro-vend-ibm-id        1      2m36s

5. Deploy example container image to the OpenShift project

The example application needs following configurations:

  • Two persistent volume claim to save logs and configurations outside the container
  • Two secrets to secure user and admin information
  • One configmap to map not secured environment information
  • One deployment to define the desired state for the pod
  • One service to access the right pod
  • One route to access the application from the internet

The following image shows a simplified overview of the dependencies of the container deployment configuration in the project:

Step 1: Create two Persistent Volume Claims

oc apply -f pvcs.yaml 

apiVersion: v1
kind: PersistentVolumeClaim
  name: vend-pvc-accesscodes
    - ReadWriteOnce
      storage: 5Gi
apiVersion: v1
kind: PersistentVolumeClaim
  name: vend-pvc-logs
    - ReadWriteOnce
      storage: 5Gi

Step 2: Create secretes for the user and admin

  • User
oc create secret generic vend-user-creds \
oc get secret vend-user-creds -o json

  • Admin
oc create secret generic vend-admin-creds \
oc get secret vend-admin-creds -o json

Note: Useful OpenSource article

Step 3: Create a configmap

oc apply -f configmap.yaml 

kind: ConfigMap
apiVersion: v1
  name: vend-usage
  VEND_USAGE: "vend-demo-secret-openshift"

Step 4: Create a deployment

oc apply -f deployment.yaml 

Here we use the registry secret name “roks-gen2-suedbro-vend-ibm-id“, we defined in step 5.

kind: Deployment
apiVersion: apps/v1
  name: vend
      app: vend
  replicas: 1
        app: vend
        version: v1
      - name: vend-volume-accesscodes
          claimName: vend-pvc-accesscodes
      - name: vend-volume-logs
          claimName: vend-pvc-logs
      - name: vend
            command: ["sh", "-c", "curl http://localhost:3000/"]
          initialDelaySeconds: 20
            command: ["sh", "-c", "curl http://localhost:3000/health"]
          initialDelaySeconds: 40
        - name: VEND_USAGE
              name: vend-usage
              key: VEND_USAGE
        - name: USER
              name: vend-user-creds
              key: VEND_USER
        - name: USERPASSWORD
              name: vend-user-creds
              key: VEND_USER_PASSWORD
        - name: ADMINUSER
              name: vend-admin-creds
              key: VEND_ADMIN
              name: vend-admin-creds
              key: VEND_ADMIN_PASSWORD
          - mountPath: /usr/src/app/accesscodes
            name: vend-volume-accesscodes
          - mountPath: /usr/src/app/logs
            name: vend-volume-logs
        - containerPort: 3000
      restartPolicy: Always
      - name: roks-gen2-suedbro-vend-ibm-id 

Step 5: Apply the service configuration

oc apply -f service.yaml 

kind: Service
apiVersion: v1
  name: vend
    app: vend
    app: vend
    - port: 3000
      name: http
  type: NodePort

(optional) Step 6: Describe the service

oc describe service vend

Example output:

Name:                     vend
Namespace:                vend-ibm
Labels:                   app=vend
Annotations:              <none>
Selector:                 app=vend
Type:                     NodePort
IP Families:              <none>
Port:                     http  3000/TCP
TargetPort:               3000/TCP
NodePort:                 http  30661/TCP
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

Step 7: Expose service

Here is a useful link to the OpenShift routing topic on an IBM Cloud Red Hat OpenShift cluster Traffic flow in a multizone VPC cluster with a public cloud service endpoint.

oc expose svc vend

Step 8: Get newly created route for our service vend

oc get route | grep "vend"

Step 9: Verify the route output in your browser

Now open the route and verify the output in your browser:

"{\"message\":\"vend test - vend-demo-secret-openshift\"}"

Step 10: Verify the vend application log file output, that’s saved in the persistent volume claim

1. Get the running pod

oc get pods | grep "vend"

Example output:

vend-6879fc49cc-fv72d   1/1     Running   0          3d3h

2. Access the running pod on it’s command line

oc exec vend-6879fc49cc-fv72d cat ./logs/log.txt

Example output:

kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
*** INF0: 2021-11-7 (XX:XX:30) [1636XXX130402] VEND_USAGE : vend-demo-secret-openshift
*** INF0: 2021-11-7 (XX:XX:30) [1636XXX30403] USER : user
*** INF0: 2021-11-7 (XX:XX:30) [1636XXX30403] USER_PASSWORD : user
*** INF0: 2021-11-7 (XX:XX:30) [1636XXX30403] ADMINUSER : admin
*** INF0: 2021-11-7 (XX:XX:30) [1636XXX0403] ADMINUSER_PASSWORD : admin
*** INF0: 2021-11-7 (XX:XX:30) [1636XXX0407] Info - envDefined==false
*** INF0: 2021-11-7 (XX:XX:30) [1636XXX1906] VEND_USAGE : vend-demo-secret-openshift


It could be useful to be able to use different container image registries for an OpenShift project, the configuration for the IBM Cloud Container Registry works pretty state forward and is good documented. The example application for my cheat sheet contains serval topics to dig into as an example for a simply container implementation using Node.js.

I hope this was useful for you and let’s see what’s next?



#ibmcloudcontainerregistry, #ibmcloud, #container, #containerregistry, #openshift, #roks, #container

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Blog at

Up ↑

%d bloggers like this: