TheKoguryo's Tech Blog

 Version 2023.11.20

Warning

This content has been generated by machine translation. The translations are automated and have not undergone human review or validation.

1.5 Deploying the app using the OCIR image

Register image to OCIR

Oracle Cloud Infrastructure Registry (OCIR) is a managed container registry provided by Oracle that supports the Docker V2 API and is an Open Container Initiate compliant container registry. You can push and pull images through the docker cli and use them in a Kubernetes cluster.

To use an image for OCIR, registration is required first, and try to register the nginx image used in the previous example by following the procedure below.

Create OCIR Repository

  1. Log in to the OCI console.

  2. From the top left hamburger menu, go to Developer Services > Containers & Artifacts : Container Registry.

  3. In List Scope, select the target Compartment (eg oke-labs).

  4. Before pushing an image, you need to create a repository in OCIR first.

    Click Create repository to create the nginx repository as shown below. Select Access mode as Private for both push and pull authentication tests.

    image-20211109173748014

  5. Complete creation

    image-20211109174409016

  6. Copy the Namespace from the Repository screen. tenancy-namespace representing the tenant in the region: cnrlxx3w0wgq, which is required for subsequent logins.

Create OCI Auth Token

Register an image in docker hub with docker cli, or log in through docker login with username/password when importing. OCIR also requires a login, and uses an Auth Token for security instead of a password.

  1. Go to User Settings by clicking the user’s Profile icon in the upper right corner.

    • The user in the figure below is an OCI local user and the username is oke-admin.
    • If your username starts with oracleidentitycloudservice/~~~, you are a user of Oracle Identity Cloud Service.

    image-20211109175044623

  2. Go to Resources > Auth Token in the lower left.

  3. Click Generate Token to generate Auth Token.

  4. Enter and create a description. The Auth Token can only be seen when it is created, so make a copy of it.

    image-20211109175405289

    image-20211109175414210

OCIR login and image push

  1. Log in with the docker cli in Cloud Shell or the connection environment through the Auth Token you created earlier.

    • OCIR address: <region-key>.ocir.io
    • username:
      • <tenancy-namespace>/<username> format
      • Username: The user name shown in the user profile in the OCI service console is used.
        1. User on Oracle Identity Cloud Service: <tenancy-namespace>/oracleidentitycloudservice/<username>
        2. OCI Local user: <tenancy-namespace>/<username>
      • tenancy-namespace: You can check the tenancy-namespace you checked when creating the Repository or oci os ns get in Cloud Shell.
    • Password: Auth Token of the user to log in created earlier
    oke_admin@cloudshell:~ (ap-seoul-1)$ oci os ns get
    {
      "data": "cnrlxx3w0wgq"
    }
    oke_admin@cloudshell:~ (ap-seoul-1)$ docker login ap-seoul-1.ocir.io
    Username: cnrlxx3w0wgq/oke-admin
    Password:
    WARNING! Your password will be stored unencrypted in /home/oke_admin/.docker/config.json.
    Configure a credential helper to remove this warning. See
    https://docs.docker.com/engine/reference/commandline/login/#credentials-store
    
    Login Succeeded
    
  2. Image Push

    • To push to the Repository created in OCIR, tag in the format below and then push.
      • <region-key>.ocir.io/<tenancy-namespace>/<repo-name>:<tag>
    • nginx:latest example
    docker pull nginx:latest
    docker tag nginx:latest ap-seoul-1.ocir.io/cnrlxx3w0wgq/nginx:latest
    docker push ap-seoul-1.ocir.io/cnrlxx3w0wgq/nginx:latest
    
  3. Check OCIR

    Returning to the OCI service console again, you can see that the pushed image has been successfully registered based on the target compartment.

    image-20211109220755364

A note to avoid mistakes

What happens when you do docker push in the following situation?

  • If the OCIR Repository has not been created before the push

  • If there is an additional path in front of the image name, such as dev/nginx:latest (or bitnami/nginx:latest), if the OCIR Repository is created only as dev

    => If you do not create an OCIR Repository in advance, it is pushed to the root compartment by default.

    => Even dev/nginx should be the repository name. If you don’t do that, it will be pushed to the root compartment in the same way.

If you click Settings in the upper right corner of Container Registry to view the setting information, as shown below, if there is no target repository, automatically creating a new private repository in the root compartment and pushing it is checked by default.

image-20211109221903416

Deploy to OKE cluster as OCIR image

OCIR image deployment test

  1. Try deploying the image to the OKE cluster by pulling the image to the most common form, Public Container Registry.

    kubectl create deployment nginx-ocir --image=ap-seoul-1.ocir.io/cnrlxx3w0wgq/nginx:latest
    
  2. As a result of the deployment, you can see that an error has occurred in importing the image to the private repository due to an authentication problem as shown below.

    oke_admin@cloudshell:~ (ap-seoul-1)$ kubectl create deployment nginx-ocir --image=ap-seoul-1.ocir.io/cnrlxx3w0wgq/nginx:latest
    deployment.apps/nginx-ocir created
    oke_admin@cloudshell:~ (ap-seoul-1)$ kubectl get pod
    NAME                          READY   STATUS         RESTARTS   AGE
    nginx-ocir-6c9d554866-nqgjg   0/1     ErrImagePull   0          10s
    oke_admin@cloudshell:~ (ap-seoul-1)$ kubectl describe pod nginx-ocir-6c9d554866-nqgjg
    Name:         nginx-ocir-6c9d554866-nqgjg
    ...
    Events:
      Type     Reason     Age                From               Message
      ----     ------     ----               ----               -------
    ...
      Warning  Failed     11s (x2 over 23s)  kubelet            Failed to pull image "ap-seoul-1.ocir.io/cnrlxx3w0wgq/nginx:latest": rpc error: code = Unknown desc = Error reading manifest latest in ap-seoul-1.ocir.io/cnrlxx3w0wgq/nginx: denied: Anonymous users are only allowed read access on public repos
      Warning  Failed     11s (x2 over 23s)  kubelet            Error: ErrImagePull
    

OCIR Private Repository image deployment test - imagepullsecret

In order to use an image by importing from the Private Repository, you must register and use a secret for authentication. Follow the procedure below to create and use a secret.

  1. I did docker login using the Auth Token earlier. After logging in, authentication information is saved in .docker/config.json under the user’s home.

    oke_admin@cloudshell:~ (ap-seoul-1)$ docker login ap-seoul-1.ocir.io
    Username: cnrlxx3w0wgq/oke-admin
    Password:
    WARNING! Your password will be stored unencrypted in /home/oke_admin/.docker/config.json.
    Configure a credential helper to remove this warning. See
    https://docs.docker.com/engine/reference/commandline/login/#credentials-store
    
    Login Succeeded
    
  2. Log in using the above authentication information.

    kubectl create secret generic ocir-secret \
        --from-file=.dockerconfigjson=$HOME/.docker/config.json \
        --type=kubernetes.io/dockerconfigjson
    
  3. Alternatively, you can create a secret directly without docker login information.

    kubectl create secret docker-registry <secret-name> --docker-server=<region-key>.ocir.io --docker-username='<tenancy-namespace>/<oci-username>' --docker-password='<oci-auth-token>' --docker-email='<email-address>'
    
  4. Redeploy using imagepullsecret as shown below.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: nginx-ocir
      name: nginx-ocir
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: nginx-ocir
      template:
        metadata:
          labels:
            app: nginx-ocir
        spec:
          containers:
          - name: nginx
            image: ap-seoul-1.ocir.io/cnrlxx3w0wgq/nginx:latest
          imagePullSecrets:
          - name: ocir-secret
    
  5. You can see that it is normally distributed as shown below.

    oke_admin@cloudshell:~ (ap-seoul-1)$ kubectl create secret generic ocir-secret \
    >     --from-file=.dockerconfigjson=/home/oke_admin/.docker/config.json \
    >     --type=kubernetes.io/dockerconfigjson
    secret/ocir-secret created
    oke_admin@cloudshell:~ (ap-seoul-1)$ kubectl get secret
    NAME                  TYPE                                  DATA   AGE
    default-token-2tvwr   kubernetes.io/service-account-token   3      24h
    ocir-secret           kubernetes.io/dockerconfigjson        1      13s
    oke_admin@cloudshell:~ (ap-seoul-1)$ kubectl apply -f nginx-ocir-deployment.yaml 
    deployment.apps/nginx-ocir created
    oke_admin@cloudshell:~ (ap-seoul-1)$ kubectl get all
    NAME                              READY   STATUS    RESTARTS   AGE
    pod/nginx-ocir-798957d964-9rddt   1/1     Running   0          7s
    
    NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
    service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   24h
    
    NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/nginx-ocir   1/1     1            1           8s
    
    NAME                                    DESIRED   CURRENT   READY   AGE
    replicaset.apps/nginx-ocir-798957d964   1         1         1       7s
    

OCIR Private Repository image deployment test - default imagepullsecret

If it is inconvenient to specify the imagepullsecret every time, you can also use it by saving the authentication for the Container Repository to be used as the default.

  1. There is a default serviceaccount in the namespace, and add imagepullsecret to it as shown below.

    kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "ocir-secret"}]}'
    
  2. As a result, imagesecret to be used by default is added to the default serviceaccount as shown below

    oke_admin@cloudshell:~ (ap-seoul-1)$ kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "ocir-secret"}]}'
    serviceaccount/default patched
    oke_admin@cloudshell:~ (ap-seoul-1)$ kubectl get sa default -o yaml
    apiVersion: v1
    imagePullSecrets:
    - name: ocir-secret
    kind: ServiceAccount
    metadata:
      creationTimestamp: "2021-11-08T13:51:17Z"
      name: default
      namespace: default
      resourceVersion: "277559"
      uid: f72718f9-135c-46d2-b0ac-a1ea1b990863
    secrets:
    - name: default-token-2tvwr
    
  3. Delete the previously deployed yaml and redeploy the first failed command because there is no authentication information.

    kubectl create deployment nginx-ocir --image=ap-seoul-1.ocir.io/cnrlxx3w0wgq/nginx:latest
    
  4. If you check the result, you can see that it is normally deployed using the default imagepullsecret.

    oke_admin@cloudshell:~ (ap-seoul-1)$ kubectl create deployment nginx-ocir --image=ap-seoul-1.ocir.io/cnrlxx3w0wgq/nginx:latest
    deployment.apps/nginx-ocir created
    oke_admin@cloudshell:~ (ap-seoul-1)$ kubectl get all
    NAME                              READY   STATUS    RESTARTS   AGE
    pod/nginx-ocir-6c9d554866-vmjtb   1/1     Running   0          5s
    
    NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
    service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   24h
    
    NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/nginx-ocir   1/1     1            1           5s
    
    NAME                                    DESIRED   CURRENT   READY   AGE
    replicaset.apps/nginx-ocir-6c9d554866   1         1         1       5s
    


As an individual, this article was written with my personal time. There may be errors in the content of the article, and the opinions in the article are personal opinions.

Last updated on 8 Nov 2021