You may face a permission issue when deploying a Pod to your Kubernetes cluster which refers to a Docker image hosted in a private Docker registry, and we will see how to deal with that in this blog article.
Typically your build script will have a build
stage, which will login to the Gitlab registry, using the docker login
command and pushing the image :
1
2
3
4
docker login -u "$CI_REGISTRY_USER" \
-p "$CI_REGISTRY_PASSWORD" \
"$CI_REGISTRY"
docker push registry.gitlab.com/nickname/projet:latest
All is working fine as you get the credentials from Gitlab.
Let’s assume the next stage is to run the tests in the Kubernetes cluster, you will have to deploy the services (database and so on) and finally this image where you’ll run your tests. But deploying this to Kubernetes fails due to a permission error because Kubernetes isn’t aware of the Gitlab credentials.
To solve this issue, you need to create a Kubernetes docker-registry
secrete and tell Kubernetes to use it in order to pull the image.
Create/Update a docker-registry secret
Let’s create the docker-registry
secret using the Gitlab credentials :
1
2
3
4
5
6
7
kubectl create secret --namespace=$KUBERNETES_NAMESPACE \
docker-registry gitlab-registry \
--docker-server=$CI_REGISTRY \
--docker-username=$CI_REGISTRY_USER \
--docker-password=$CI_BUILD_TOKEN \
--docker-email=$GITLAB_USER_EMAIL \
--output yaml --dry-run | kubectl apply -n $KUBERNETES_NAMESPACE -f -
As I described in my previous blog article kubectl : Use multiple account accesses, I have a ci
ServiceAccount and a ci
Namespace so the KUBERNETES_NAMESPACE
variable is equal to ci
in my case.
The other variables are the one from Gitlab, nothing specials.
What is important here is the secret name which is gitlab-registry
. You will need the secret name in order to refer to it.
Pull image using the Kubernetes secret
Now let see how to use this k8s secret.
You have two options to do so :
- Use the
imagePullSecrets
in all your pods giving thegitlab-registry
name - Assign the
gitlab-registry
secret to the ServiceAccount
Assigning the secret to the ServiceAccount will allow you to link it to your pod and the imagePullSecrets
will be automatically assigned.
Assigning the secret to the ServiceAccount
Given the ci
ServiceAccount exists in your Kubernetes cluster, in order to assign the secret to it, run the following command :
1
2
$ kubectl patch serviceaccount ci -p '{"imagePullSecrets": [{"name": "gitlab-registry"}]}'
Finally use the --serviceaccount=ci
when running your pod and Kubernetes will be able to fetch the image from the Gitlab registry :
1
2
3
4
5
6
$ kubectl run myPod --image=registry.gitlab.com/zedtux/k8s-demo:latest \
--namespace=ci \
--restart=Never \
--rm \
--serviceaccount=ci \
demo.sh