Using private docker registry inside kubernetes

Using private docker registry inside kubernetes

Configure a customer k8s cluster with Digital Ocean Container Registry

Requirements

  • Kubernetes cluster (Access to the cluster via kubectl)
  • Private docker registry (I use Digital Ocean for demo)
  • Docker image

Accessing public images in a public docker registry like Dockerhub is the default behaviour of a kubernetes cluster, unless you want to integrate your own private registry to access private docker images for obvious security reasons. Cloud service providers like AWS, Digital Ocean provides easy integration between own docker registry to managed kubernetes.
But configuring a baremetal kubernetes cluster to access your private registry comes with couple of steps including updating the deployment/pod yaml. I am using digital ocean docker registry for the reference. But steps are same for most of the providers.

If you don't have a cluster for demo. Check out Kind. Kind helps you to run a kubernetes cluster locally in minutes. Or else you can use Katacoda or Play with kubernetes

Step 1

Dockerconfig.json

First we have to get the cluster configured to authenticate to the private registry. A Kubernetes cluster uses the Secret of kubernetes.io/dockerconfigjson type to authenticate with a container registry to pull a private image. We can do it in two methods. First method is to use the config.json file and the second method requires your username, password and email. In digital ocean container registry you can download a read-only config file at container registry home Actions button. The same file can be found in ~/.docker/config.json when you login in to docker registry in your local machine.

Using config.json

kubectl create secret generic registry-credential \
    --from-file=.dockerconfigjson=<path/to/.docker/config.json> \
    --type=kubernetes.io/dockerconfigjson

or

Using docker credentials

kubectl create secret docker-registry registry-credential --docker-server=<your-registry-server> --docker-username=<your-name> --docker-password=<your-pword> --docker-email=<your-email>

Inspect created secret

kubectl get secret registry-credential --output=yaml

The output is similar to this:

apiVersion: v1
kind: Secret
metadata:
  ...
  name: registry-credential
  ...
data:
  .dockerconfigjson: eyJodHRwczovL2luZGV4...
type: kubernetes.io/dockerconfigjson

The value of the .dockerconfigjson field is a base64 representation of your Docker credentials. To convert the data into readable format use the following command.

kubectl get secret registry-credential --output="jsonpath={.data.\.dockerconfigjson}" | base64 --decode

Step 2

Editing the pod

Once the secret is created we can update our pod config to use the created secret to pull images. Update the spec session of your pod as follows.

spec:
  containers:
  - name: private-reg-container
    image: <your-private-image>
  imagePullSecrets:
  - name: registry-credential

To pull the image from the private registry, Kubernetes needs credentials. The imagePullSecrets field in the configuration file specifies that Kubernetes should get the credentials from a Secret named registry-credential. Create a Pod that uses your Secret, and verify that the Pod is running

kubectl apply -f pod.yaml
kubectl get pod <pod-name>

If you don't want to add imagePullSecrets to your pod config or need to set different registries per namespace as default then go to step 3.

Step 3

Adding image pull secretes to service account

If you want to get a preview about service accounts checkout this doc To add our new secret to the namespace we have to modify the service account and push our new secret name to the imagePullSecret array inside the service account. We can download the service account manifest by

kubectl get serviceaccounts default -o yaml > ./service-account.yaml

then update it as follows:

apiVersion: v1
kind: ServiceAccount
metadata:
  creationTimestamp: 2015-08-07T22:02:39Z
  name: default
  namespace: default
  uid: 052fb0f4-3d50-11e5-b066-42010af0d7b6
secrets:
- name: default-token-uudge
imagePullSecrets:
- name: registry-credential

Finally replace the service account with updated manifest file

kubectl replace serviceaccount default -f ./service-account.yaml

Now, when a new Pod is created in the current namespace and using the default ServiceAccount, the new Pod has its spec.imagePullSecrets field set automatically.


References:
Pull an Image from a Private Registry
Add image pull secret to service account