min read

Configure Kubernetes to pull from private Docker Registry with Pulumi

Intro

Kubernetes pulls Docker containers from a Docker Registry, but if you are for example using Gitlab Container Registry to store your Docker containers, Kubernetes won´t be able to access your registry as it is always private.

If you want to use your private docker registry in Kubernetes, you need to tell Kubernetes specifically how to connect to your registry and Kubernetes needs to know your credentials to log in.

Getting started

Assuming you have already connected to your Gitlab Registry from your local machine, you can keep reading. If you haven´t read about how to configure your local Docker Engine to use your Gitlab Registry.

This step is important so we are getting the credentials generated we later need for Kubernetes.

After you have successfully connected to your registry and can pull images from it, search for this Docker config file on your local machine:

~/.docker/config.json

In case the file looks like this, you cannot simply copy it and pass it to Kubernetes, as the credentials are stored safely in a credential store.

{
    "auths": {
        "registry.gitlab.com": {}
    },
    "HttpHeaders": {
        "User-Agent": "Docker-Client/19.03.5 (windows)"
    },
    "credsStore": "wincred"
}

Instead, we have to use the script below I´ve created to log in to your registry and extract the generated base64 encoded docker config JSON token.

Insert your credentials there and execute it.

Just be aware that after executing this command, your user credentials will be visible in the shell history

kubectl create secret docker-registry regsec_dry \
--docker-server=registry.gitlab.com --docker-username=... \
--docker-email=... --docker-password=... \
--dry-run -o yaml | grep .dockerconfigjson: | sed -e 's/.dockerconfigjson://' | sed -e 's/^[ \t]*//'

The Pulumi Secret Vault

We can now use this command to store the extracted token from above safely in your Pulumi config for later use within your Pulumi code.

pulumi config set docker_token --secret <your_token>

The created config entry will now be populated to the Config object below that can be used anywhere in your infrastructure code to access secrets and other config entries at any time.

  const config = new Config();

Our populated token is now accessible by its key "docker_token"

The Pulumi Secret

We now have to create a Kubernetes Secret with our registry token. The class below fetches the token from the Pulumi Secret Store and creates a new Secret.

import {Secret} from "@pulumi/kubernetes/core/v1";
import {Config} from "@pulumi/pulumi";

/**
 * Required so that Kubernetes can pull images from the registry
 *
 *
 */
export class DockerRegistry {

    constructor(provider: any) {

        const config = new Config();

        const dockerToken = config.require("docker_token");

        new Secret("docker-registry-secret", {
            metadata: {
                name: "docker-registry-secret"
            },
            data: {
                ".dockerconfigjson": dockerToken
            },
            type: "kubernetes.io/dockerconfigjson"
        }, {provider});
    }

}

After creating a new DockerRegistry instance we should then be able to fetch containers from our private Gitlab Registry and therefore be able to deploy our containers that have been built with Gitlab CI with Pulumi.