Using private docker registry inside kubernetes
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-password> --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, you can remove imagePullsecrets
part from the pod definition and 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.
kubectl get pod <pod name> -o=jsonpath='{.spec.imagePullSecrets[0].name}{"\n"}'
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
References:
Pull an Image from a Private Registry
Add image pull secret to service account