How to create a secret to deploy container images from the GitLab registry

You know the importance of the security process in Kubernetes and why, we don’t use the hardcode variables such as user and password to any pipeline process.

Sure, you want to pull registries for your containers from different providers such as docker, Github, etc. (not only Gitlab registry).

So, we need to introduce some security concepts known as secrets in Kubernetes, to obtain the adequate method to deploy our images built in the Gitlab repository and the way to authenticate against to registry side.

Gitlab provider, allows you to do this, through using an API or some permission as read-only registry by an access-token which can use when pulling the images whether docker or Kubernetes, by using the user and password.

What is a secret?

As explanation provided by the Kubernetes official page, a secret is:

A Secret is an object that contains a small amount of sensitive data such as a password, a token, or a key. Such information might otherwise be put in a Pod specification or in a container image. Using a Secret means that you don’t need to include confidential data in your application code.

https://kubernetes.io/docs/concepts/configuration

Todo list and let’s try!

  • Create token access in Gitlab.
  • Create a docker credential file.
  • Create a secret YAML file.
  • Add the secret in deployment.YAML file.
  • Deploy and check the logs.
  • Services: An option to deploy images.

Create token access file in Gitlab

The purpose of this token is, allow to the application to access your registry in Gitlab.

Please, do not share the token with anybody.

And my advice ever, for any web application that requires tokens and permissions:

  • Never give this token more access than necessary. This practice reduces the attack vector if exposed.
  • You can now also limit the group to which a deploy token is scoped.

Navigate in User Settings -> Access Token and complete the form with:

Token NameReference name.
Expiration DateCommon uses when you have a project with some place or politics of resources.
Select scopesread-repository

When your navigate and complete, the browser shows like this.

After complete the options, click in the button Create personal access token and please, don’t forget copy and save the token because they wont be able any more ! 😀 😀

Create a docker credential file

If you want the Kubernetes deployments file had the capacity to pull images or maybe the service account that will be used to pull these images, create a file that contained the credential, a way to be as secure as possible.

Let’s create a secret with .dockerconfigjson

In these steps, create a file called .dockerconfigjson , and save it to the user and pass in the username and password fields.

The file look likes this:

{
    "auths": {
        "registry.gitlab.com":{
            "username":"REGISTRY_USERNAME",
            "password":"REGISTRY_PASSWORD",
            "auth":"AUTH_CREDENTIALS"
    	}
    }
}

Complete the file below with:

REGISTRY_USERNAME=username used in gitlab, as usually a service user.
REGISTRY_PASSWORD=a token descripted below.

and complete the field auth:AUTH_CRDENTIALS with the output that the following command show to you in the console.

Please, replace the REGISTRY_USERNAME:REGISTRY_PASSWORD with the correct values or use environment variables.

echo -n "REGISTRY_USERNAME:REGISTRY_PASSWORD" | base64

You will obtain an output as similar to this:

echo -n "pepelepou:glaps-le-NXSIUNSNnsjkasnnASws" | base64
cGVwZWxlcG91OmdsYXBzLWxlLU5YU0lVTlNObnNqa2Fzbm5BU3dz

You complete the file looks like this:

{
    "auths": {
        "registry.gitlab.com":{
            "username":"pepelepou",
            "password":"glaps-le-NXSIUNSNnsjkasnnASw",
            "auth":"cGVwZWxlcG91OmdsYXBzLWxlLU5YU0lVTlNObnNqa2Fzbm5BU3dz"
    	}
    }
} 

Finished completing the last file, you need to run the encoding of the file, to obtain the token for the secret YAML.

cat .dockerconfigjson | base64

I prefer an automated process because I understand what happens at each moment, so this gives me an advantage.

You can find this script in my own repo.

https://github.com/juanmercadoit/argocd-demo/blob/main/secrets/secret-gitlab-generator.sh

Create a secret YAML file

The time has come to create a secret YAML and save in Kubernetes the secrets. As part of the best practice, you can versioned the file, with the secrets and namespaces or services too.

Create a secret-pull-gitlab.yaml and complete with:

kind: Secret
apiVersion: v1
metadata:
  name: gitlab-pull-secret
  namespace: testing
type: kubernetes.io/dockerconfigjson
data:
  .dockerconfigjson: <Complete_with_the_output_obtained_with_base_code64>

In the .dockerconfigjson field, complete with the output obtained below.

Now you are available to deploy into the Kubernetes cluster the secret file.

kubectl apply -f secret-pull-gitlab.yaml 

Add the secret in deployment.YAML file and use

After creating the secrets, we want to deploy the application that needs to pull the registry versioned into the cluster through Argo Continuous Deployment.

Add the secret lines into deployment.yaml or the file that contains the configuration or your applications deployment.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: py-app-log
spec:
  selector:
    matchLabels:
      app: app-log
  template:
    metadata:
      labels:
        app: app-log
    spec:
      containers:
      - name: app-log
        image: registry.gitlab.com/andresmercado/data-ai/dev/docker-dev/ubuntu-py:latest
        resources:
          limits:
            memory: "128Mi"
            cpu: "500m"
        ports:
        - containerPort: 5001
           imagePullPolicy: Always
      imagePullSecrets:
      - name: gitlab-pull-secret

Deploy and check the logs

I have no doubt that you got here, reading my article because you findind a lots in your deployments logs the message:

Error: ImagePullBackOff
Failed to pull image
denied: access forbidden
Error: ErrImagePull

After having change some files and deploy the application, congrats! The application run without problems.

I don’t wanna ending my work without recommending the creation of a service for your deployments.

Services: An option to deploy applications & registrys

Create a yaml file, to have the adventages of:

  • It can be tracked in version control.
  • Observability: It makes it much easier to see, what will break when changing something.

So, by now create a secops.service-account.yml , specify the default service account with imagePullSecrets

apiVersion: v1
kind: ServiceAccount
metadata:
  name: kube-sec-ops
  namespace: kube-sec-ops
imagePullSecrets:
- name: gitlab-pull-secret

Now, the artefact that provides the authentication, allows this and other applications can be called the service, pulling the images from gitlab.

Happy learning and see you in the next deployment! 😉