Configuring a Private Docker Registry

Getting Started

Before starting this lab, you will need:

  1. A private hosted registry and sufficient credentials (username & password) to access the registry.
  2. An image hosted in your private registry that you would like to deploy in your cluster. If you don’t currently have an image hosted in a private registry and you’d like to complete this lab, you can follow the instructions here to host an image privately on Docker Hub.
  3. A Critical Stack deployment with a user account provisioned for you. Make sure to take note of your namespace when you log in.
  4. kubectl configuration for your Critical Stack cluster (if completing this lab through the command line.) See kubectl101 for instructions on how to do this.

Overview

In this lab, you will create a Pod that uses a Secret to pull an image from a private Docker registry or repository. I’ll be using Docker Hub as an example, but you can do this with any private registry that you have credentials to access.

You are welcome to complete these steps through the Critical Stack User Interface or through the command line, depending on what you’re most comfortable with.

Prerequisite: Generating Docker Config

  1. Ensure that Docker is running on your machine.
  2. Login to your docker registry (you can leave registry-server blank for Docker Hub, defaults to https://index.docker.io/v1/)

    $ docker login <registry-server>
    Username:
    Password:
    Login Succeeded
  3. Examine your Docker Config file (by default, located at ~/.docker/config.json). If you run the command cat ~/.docker/config.json the output should appear something like this:

    {
        "auths": {
            "https://index.docker.io/v1/": {
                "auth": "dXNlcm5hbWU6cGFzc3dvcmQ="
            }
        },
        "HttpHeaders": {
            "User-Agent": "Docker-Client/19.03.2 (darwin)"
        }
    }

    or something like this

    {
        "auths": {
            "https://index.docker.io/v1/": {}
        },
        "HttpHeaders": {
            "User-Agent": "Docker-Client/19.03.2 (darwin)"
        },
        "credsStore": "yourcredsstore"
    }

    in the first case, your config is correctly configured to be converted into a usable Kubernetes secret, and you can skip to the next step. In the second case, your credentials are instead being stored in a Credentials Store. While this is a good practice for local security, the config file will not be able to authenticate you to use your private repository. Using your favorite terminal editor, remove the line with "credsStore": "yourcredsstore" as well as the comma on the above line. The end result should look like this:

    {
        "auths": {
            "https://index.docker.io/v1/": {}
        },
        "HttpHeaders": {
            "User-Agent": "Docker-Client/19.03.2 (darwin)"
        }
    }

    Now that you’ve done that, run the command docker login <registry-server>. Once again you can omit the registry server if you’re using Docker Hub. You will now be able to inspect your docker config and see the base64 encoded auth string that represents your username and password. You can read more about the docker login command here. Use best security practices when handling base64 encoded strings as they are not encrypted and can easily be decoded to reveal your username and password.

Command Line Steps

In this section we will be creating a secret from a docker config file. If you’d like to create the secret directly from the command line, you can consult the kubernetes documentation here to see how you could accomplish this.

You will need to modify the path/to/.docker/config.json, depending on your machine.

  1. Use kubectl to create a secret from your docker config.

    $ kubectl create secret generic private-docker-registry \
    --from-file=.dockerconfigjson=<path/to/.docker/config.json> \
    --type=kubernetes.io/dockerconfigjson
  2. Inspect the secret to ensure it was created successfully using the following command:

    $ kubectl get secret private-docker-registry -o yaml
  3. Create a pod that uses the secret You can use the following yaml file as an example pod, save it to a file called private-registry-pod.yaml.

    apiVersion: v1
    kind: Pod
    metadata:
    name: private-reg
    spec:
    containers:
    - name: private-reg-container
    	image: <your-private-image>
    imagePullSecrets:
    - name: private-docker-registry

    The important field here is the imagePullSecrets field in the pod specification that tells Kubernetes to use that secret to authenticate when pulling the image from your private registry.

  4. Create a pod that uses the secret, and verify that it is running.

    $ kubectl apply -f private-registry-pod.yaml
    $ kubectl get pod private-reg

User Interface Steps

  1. Log in to your Critical Stack cluster. Under Data center > Config > Secrets Click Create and choose Upload Docker Config.
  2. Choose your provider as Docker and for Choose File navigate to your docker config directory (By default it is ~/.docker/) and upload config.json. You may need to show hidden files, or manually navigate to the directory if your OS doesn’t show hidden files by default.

    1. If you are on MacOS, when the Finder window opens you can use the key combination CMD+SHIFT+G and then type in ~/.docker to navigate to the directory where config.json is located.

  3. Click Create

  4. Navigate to Data Center > Workloads > Deployments and click Create Deployment > Simple

  5. Enter your app name and configure other fields as necessary, making sure to add your Container Image as the link to your private docker container. At the bottom, toggle the Show Advanced Options switch and under Secrets, select your uploaded Docker config. By default for Docker Hub this is named index-docker-io, but it will depend on the private registry that you are using.

  6. Click Create when you have finished configuring your deployment.

Conclusion

Whether you did it through the UI or the command line, you should now have a pod configured to pull an image from a private docker repository.

If you had to modify your docker config to remove the credsStore field and you don’t want your encoded credentials stored in plain text, you can run docker logout at any time to clear your authentication string.

Resources

This tutorial was adapted from the Kubernetes task found here