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.

Log in to the Harbor UI by clicking the “Log in with SSO” button on the registry login page. Harbor will redirect you to the Rackspace KaaS Control Panel, where you will use your OpenStack username and password to authenticate.

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_OS_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 Rackspace KaaS Control Panel credentials.
  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.

Add users to a Harbor project#

You can create public and private Harbor projects. While public projects are visible to all users, only members can see and use private projects. You can add and remove your OpenStack users to your Harbor project as well as assign privileges to them by using the Harbor UI. Harbor does not receive any role-based access control (RBAC) information from the OpenStack Identity service. Therefore, you do not need to configure users on the OpenStack side. However, before you can add an OpenStack user to a Harbor project, you need to log in using that user to the Harbor UI at least once.

You can assign one of the following roles to a user in a Harbor project:

  • Guest—enables users to pull Docker images from the Harbor registry.
  • Developer—enables users to pull and push Docker images to and from the Harbor registry.
  • Project Admin—enables users to perform any actions with Docker images, as well as add and remove members from the project.

For more information, see the Harbor User Guide.

To add users to a Harbor project, complete the following steps:

  1. Verify that the user exists in OpenStack by viewing the list of users in the OpenStack Dashboard or using the OpenStackClient commands.

    • If the user has not yet generated a token in the KaaS Control panel:
      1. Log in to the KaaS Control Panel with that user account.
      2. Generate and save a token.
  2. Log in to and log out from the Harbor UI using the user account that you want to add to the Harbor project.

  3. Log in to the Harbor UI as the Harbor project administrator or as a Rackspace KaaS cluster administrator.

  4. Select the project.

  5. Click Members > +New Member.

  6. Type the OpenStack username and select a role.

  7. Click OK.

    Note

    If you get the Username does not exist error message, verify that the user exists in OpenStack. Then, log in to and log out from the Harbor UI with that user.

Examples of usage#

This section provides examples about how to use the Docker registry. When you work with a Docker registry, you use the push and pull commands to upload and download 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:

    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