Set up your cluster to use a private Docker image registry#

In addition to using public Docker image registries from Docker, Quay, or others, your Kubernetes cluster is configured to use an internal, secure, and private Docker registry instance implemented by VMware Harbor. Harbor includes many enterprise-class features, including Role Based Access Control (RBAC) and image vulnerability scanning with Clair that provides an additional level of security to your images.

For more information, see the Harbor User Guide.

The username and password combination RS_K8S_USERNAME/RS_K8S_PASSWORD are the administrative credentials for the private Docker registry. The RS_K8S_USERNAME account is not associated with any user in your backend authentication system, such as OpenStack Keystone. When a Kubernetes user submits their token to access the registry for the first time, through the user interface or using the docker login command, the Docker registry user is created automatically. Do not manually create or manage users.

The registry has a default project called library. You might want to store all your base images used by developers and operators in this project. By default, the library project is publicly visible, which enables any user to pull images from it. However, only the RS_K8S_USERNAME user can push images to this project. If you want to enable other users to push images to this project, see Managing Projects.

To set up your cluster to work with VMware Harbor, perform the following steps:

  1. Generate a token as described in Access your Kubernetes cluster.
  2. Log in to the Harbor registry UI at https://registry.${RS_K8S_CLUSTER_NAME}.${RS_K8S_DOMAIN} by using your RS_OS_USERNAME and RS_K8S_TOKEN. For example: https://registry.kubernetes-test.test.mk8s.systems.
  3. Create a registry project for your repositories and images by using the following steps:
    1. In the left-hand navigation panel, click Projects.
    2. Click +Project.
    3. Use the value of RS_OS_USERNAME for your project name.
    4. Select whether the project is public or private.

Examples of usage#

This section provides examples on how to use the Docker registry. When you work with a Docker Registry, you use the push and pull commands to download and upload images. The examples below provide more information about how to pull and push Docker images into the Docker registry.

Example of private Docker registry usage#

This section describes an example of how to use the internal Docker registry with Docker images. This example uses a container of a lightweight general purpose Linux distribution called Alpine Docker. Download the Alpine Linux Docker image from DockerHub, tag it with the internal Docker registry, and upload the tag to the internal registry. Also, create a secret file for the Docker registry and a Deployment for Alpine Linux.

  1. Log in to the Docker registry.

    $ docker login -u ${RS_OS_USERNAME} -p ${RS_K8S_TOKEN} registry.${RS_K8S_CLUSTER_NAME}.${RS_K8S_DOMAIN}
    

    System response:

    Login Succeeded
    
  2. Download the Alpine Linux Docker image from the registry.

    $ docker pull alpine
    

    System response:

    Using default tag: latest
    latest: Pulling from library/alpine
    Digest: sha256:58e1a1bb75db1b5a24a462dd5e2915277ea06438c3f105138f97eb53149673c4
    Status: Image is up to date for alpine:latest
    
  3. Tag the Alpine Linux image with the local Docker registry.

    $ docker tag alpine registry.${RS_K8S_CLUSTER_NAME}.${RS_K8S_DOMAIN}/${RS_OS_USERNAME}/alpine
    
  4. Upload the tag to the local Docker registry.

    $ docker push registry.${RS_K8S_CLUSTER_NAME}.${RS_K8S_DOMAIN}/${RS_OS_USERNAME}/alpine
    

    System response:

    The push refers to a repository [registry.${RS_K8S_CLUSTER_NAME}.${RS_K8S_DOMAIN}/${RS_OS_USERNAME}/alpine]
    404361ced64e: Pushed
    latest: digest: sha256:3de22c9f3a98b60a295781c201f1d7b2cd1c16601c89a9ad5842bdc8462d1fc3 size: 528
    
  5. Create a secrets file for the local Docker registry.

    $ kubectl create secret docker-registry docker-registry-creds \
     --docker-server="registry.${RS_K8S_CLUSTER_NAME}.${RS_K8S_DOMAIN}" \
     --docker-email=this.email.is.unused.but.required@example.com \
     --docker-username=${RS_OS_USERNAME} \
     --docker-password=${RS_K8S_TOKEN}
    

    System response:

    secret "docker-registry-creds" created
    
  6. Create a Deployment called alps.

    $ cat <<EOF | kubectl apply -f -
    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: alps
    spec:
      template:
        metadata:
          labels:
            k8s-app: alps
        spec:
          containers:
          - name: alps
            image: registry.${RS_K8S_CLUSTER_NAME}.${RS_K8S_DOMAIN}/${RS_OS_USERNAME}/alpine
            command: ["/bin/sh","-c","echo 'Napping...' && sleep 10000"]
          imagePullSecrets:
            - name: docker-registry-creds
    EOF
    deployment "alps" created
    
  7. View the Pods created for this Deployment.

    $ kubectl get pods
    

    System response:

    NAME                    READY     STATUS    RESTARTS   AGE
    alps-334303239-njpt3    1/1       Running   0          13s
    
  8. View the logs for the Pod.

      $ kubectl logs alps-334303239-njpt3
    
    **System response:**
    
    .. code-block:: bash
    
       Napping...
    
  9. Use the get events command for this image to view detailed information about the Deployment:

    $ kubectl get events | grep alps | grep image
    

    System response:

    57s        57s         1         alps-1298207271-njpt3   Pod          spec.containers{alps}   Normal    Pulling             kubelet, etoews-worker-1   pulling image "registry.${RS_K8S_CLUSTER_NAME}.${RS_K8S_DOMAIN}/${RS_OS_USERNAME}/alpine"
    56s        56s         1         alps-1298207271-njpt3   Pod          spec.containers{alps}   Normal    Pulled              kubelet, etoews-worker-1   Successfully pulled image "registry.${RS_K8S_CLUSTER_NAME}.${RS_K8S_DOMAIN}/${RS_OS_USERNAME}/alpine"
    
  10. When done testing, delete your Deployment:

    kubectl delete deployment alps
    

    System response:

    deployment "alps" deleted
    

Example of the library project usage#

This example is similar to Example of private Docker registry usage, but because you use the public library project, you do not need to create a secrets file.

  1. Source your credentials.sh file:

    source credentials.sh
    
  2. Log in to the Docker registry.

    $ docker login -u ${RS_OS_USERNAME} -p ${RS_K8S_TOKEN} registry.${RS_K8S_CLUSTER_NAME}.${RS_K8S_DOMAIN}
    

    System response:

    Login Succeeded
    
  3. Download the Alpine Linux Docker image from the registry.

    $ docker pull alpine
    

    System response:

    Using default tag: latest
    latest: Pulling from library/alpine
    Digest: sha256:58e1a1bb75db1b5a24a462dd5e2915277ea06438c3f105138f97eb53149673c4
    Status: Image is up to date for alpine:latest
    
  4. Tag the Alpine Linux image with the local Docker registry.

    $ docker tag alpine registry.${RS_K8S_CLUSTER_NAME}.${RS_K8S_DOMAIN}/library/alpine
    
  5. Upload the tag to the local Docker registry.

    $ docker push registry.${RS_K8S_CLUSTER_NAME}.${RS_K8S_DOMAIN}/library/alpine
    

    System response:

    The push refers to a repository [registry.${RS_K8S_CLUSTER_NAME}.${RS_K8S_DOMAIN}/library/alpine]
    404361ced64e: Pushed
    latest: digest: sha256:3de22c9f3a98b60a295781c201f1d7b2cd1c16601c89a9ad5842bdc8462d1fc3 size: 528
    
  6. Create a Deployment called alps.

    $ cat <<EOF | kubectl apply -f -
    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: alps
    spec:
      template:
        metadata:
          labels:
            k8s-app: alps
        spec:
          containers:
          - name: alps
            image: registry.${RS_K8S_CLUSTER_NAME}.${RS_K8S_DOMAIN}/library/alpine
            command: ["/bin/sh","-c","echo 'Napping...' && sleep 10000"]
          imagePullSecrets:
            - name: docker-registry-creds
    EOF
    deployment "alps" created
    
  7. View the Pods created for this Deployment.

    $ kubectl get pods
    

    System response:

    NAME                    READY     STATUS    RESTARTS   AGE
    alps-334303239-njpt3    1/1       Running   0          13s
    
  8. View the logs for the Pod.

      $ kubectl logs alps-334303239-njpt3
    
    **System response:**
    
    .. code-block:: bash
    
       Napping...
    
  9. Use the get events command for this image to view detailed information about the Deployment:

    $ kubectl get events | grep alps | grep image
    

    System response:

    57s        57s         1         alps-1298207271-njpt3   Pod          spec.containers{alps}   Normal    Pulling             kubelet, etoews-worker-1   pulling image "registry.${RS_K8S_CLUSTER_NAME}.${RS_K8S_DOMAIN}/library/alpine"
    56s        56s         1         alps-1298207271-njpt3   Pod          spec.containers{alps}   Normal    Pulled              kubelet, etoews-worker-1   Successfully pulled image "registry.${RS_K8S_CLUSTER_NAME}.${RS_K8S_DOMAIN}/library/alpine"
    
  10. When done testing, delete your Deployment:

    kubectl delete deployment alps
    

    System response::

    deployment "alps" deleted