Description

Normally, when creating a Kubernetes pod, you will use the image directly from the public dockerhub registry. This works fine because the dockerhub registry does not require any authentication. However, you may also need to create a pod based on a private registry which requires proper credentials. For example, Juniper CSRX is held in Juniper's proprietary registry at hub.juniper.net.

This article demonstrates how to create a CSRX pod using an image located in the Juniper proprietary registry.

Note: This article applies to Contrail version 5 and above

Solution

In Kubernetes, the registry credentials information is stored in an object named "secret". Create a secret object first, then refer this object in our pod definition yaml file. After that, the pod can authenticate itself toward the proprietary registry and pull the image to spawn the docker.

Create the secret

First, manually encode the content of .docker/config.json file:

----
$ cat .docker/config.json | base64

V2xQYVVJM1EyZHJTa05UU21oawpXRkp2U1d0dlowbHNUbkpPVmtaV1lWUkdTQXBaVm1SWFl6RndS
WlhkdlNrbHRSakZrUjJoNlNXdHZaMlYzYjBwRFUwcHZaRmRKZFdGdVZuVmhXRUpzWTJrMWRWcFlV
MVp1Y0dGWFJXdzFWRlpTVGs1c1JYZGxSWFJoVWtWd2VGa3dWWGhsCmJGcDBWRlJXYkdKcmNFTmFS
WXdXVmRPYjFNeVZqVmplVWsyU1VOS2EyUklTbk5NVlVGcFEyNHdQUW89Cg==

----

Then put the Base64 encoded value of .docker/config.json file as 'data' in the yaml file below:

----
#secret-jnpr.yaml
apiVersion: v1
kind: Secret
type: kubernetes.io/dockerconfigjson
metadata:
  name: secret-jnpr3
  namespace: ns-user-1
data:
  .dockerconfigjson:
V2xQYVVJM1EyZHJTa05 ......
----

----
$ kubectl apply -f secret-jnpr.yaml
secret/secret-jnpr3 created

$ kubectl get secrets
NAME                  TYPE                                  DATA   AGE
default-token-hkkzr   kubernetes.io/service-account-token   3      64d
secret-jnpr3          kubernetes.io/dockerconfigjson        1      78s
----


Keep in mind that Base64 is all about "encoding" instead of "encryption". It is considered the same as plain text. Therefore, sharing this file compromised secret.

=== refer `dockerconfigjson` secret in pod: `imagePullSecrets`

After a secret is created, it can be referred by a pod/RC or deployment in order to pull an image from the private registry. There are many ways to refer the secrets. In this section, we'll look at
using `imagePullSecrets` under pod `spec` to refer the secret.

An `imagePullSecret` is a way to pass a secret that contains a Docker (or other) image registry password to the Kubelet so it can pull a private image on behalf of your Pod.

Create a pod pulling Juniper CSRX container from private repository:

----
apiVersion: v1
kind: Pod
metadata:
  name: csrx-jnpr
  labels:
    app: csrx
  annotations:
   k8s.v1.cni.cncf.io/networks: '[
       { "name": "vn-left-1" },
       { "name": "vn-right-1" }
   ]'
spec:
  containers:
  - name: csrx
    image: hub.juniper.net/security/csrx:18.1R1.9
    ports:
    - containerPort: 22
    imagePullPolicy: IfNotPresent
    stdin: true
    tty: true
    securityContext:
      privileged: true
  imagePullSecrets:
  - name: secret-jnpr
----

Generate the pod:

----
$ kubectl apply -f csrx/csrx-with-secret.yaml
pod/csrx-jnpr created
----

The CSRX is up and running:

----
$ kubectl get pod
NAME                   READY   STATUS    RESTARTS   AGE
csrx-jnpr              1/1     Running   0          20h
----

Behind the scene, the pod authenticates itself towards the private registry, pulls the image, and launches the CSRX container.

----
$ kubectl describe pod csrx
......
Events:
19h  Normal  Scheduled  Pod   Successfully assigned ns-user-1/csrx to cent333
19h  Normal  Pulling    Pod   pulling image "hub.juniper.net/security/csrx:18.1R1.9"
19h  Normal  Pulled     Pod   Successfully pulled image "hub.juniper.net/security/csrx:18.1R1.9"
19h  Normal  Created    Pod   Created container
19h  Normal  Started    Pod   Started container
----