How to Set Up a Private Docker Registry in Kubernetes (k8s)

Secure and streamline your container deployment by setting up a private Docker registry in Kubernetes with this step-by-step guide.

A private Docker registry allows you to securely store and manage your Docker images, ensuring that only authorized users have access to your containerized applications. Setting up a private Docker registry within a Kubernetes (k8s) cluster enhances security and efficiency in your development and deployment processes. This guide will walk you through the steps needed to set up a private Docker registry in Kubernetes, including configuration, deployment, and testing.

Table of Contents

  1. Introduction
  2. Prerequisites
  3. Step 1: Prepare Your Environment
  4. Step 2: Deploy the Docker Registry
  5. Step 3: Expose the Registry Service
  6. Step 4: Secure the Docker Registry with TLS
  7. Step 5: Configure Authentication
  8. Step 6: Access and Test the Private Registry
  9. Step 7: Integrate with Kubernetes
  10. Conclusion
  11. References

Introduction

A private Docker registry within your Kubernetes cluster provides several benefits, including improved security, better performance, and more control over your container images. This guide covers the end-to-end process of setting up a private Docker registry, from initial deployment to securing and accessing it.

Prerequisites

Before you start, ensure you have the following:

  • A running Kubernetes cluster.
  • kubectl command-line tool configured to interact with your cluster.
  • Basic knowledge of Kubernetes concepts like Pods, Services, and Deployments.
  • Administrative access to your Kubernetes cluster.

Step 1: Prepare Your Environment

Ensure your Kubernetes cluster is up and running. You can verify the status of your nodes with:

bash

Copy code

kubectl get nodes

Create a namespace for the Docker registry to keep it organized:

bash

Copy code

kubectl create namespace docker-registry

Step 2: Deploy the Docker Registry

Use a deployment YAML file to deploy the Docker registry. Create a file named docker-registry-deployment.yaml with the following content:

yaml

Copy code

apiVersion: apps/v1 kind: Deployment metadata:  name: docker-registry  namespace: docker-registry spec:  replicas: 1  selector:    matchLabels:      app: docker-registry  template:    metadata:      labels:        app: docker-registry    spec:      containers:      - name: registry        image: registry:2        ports:        - containerPort: 5000        volumeMounts:        - name: registry-storage          mountPath: /var/lib/registry      volumes:      - name: registry-storage        emptyDir: {}

Apply the deployment:

bash

Copy code

kubectl apply -f docker-registry-deployment.yaml

Step 3: Expose the Registry Service

Create a service to expose the Docker registry. Create a file named docker-registry-service.yaml with the following content:

yaml

Copy code

apiVersion: v1 kind: Service metadata:  name: docker-registry  namespace: docker-registry spec:  ports:  - port: 5000    targetPort: 5000  selector:    app: docker-registry

Apply the service:

bash

Copy code

kubectl apply -f docker-registry-service.yaml

Step 4: Secure the Docker Registry with TLS

To secure your Docker registry, you need to configure TLS. Follow these steps:

  1. Create TLS certificates:

    Generate a self-signed certificate using OpenSSL or use a certificate from a trusted Certificate Authority (CA). For a self-signed certificate:

    bash

    Copy code

    openssl req -newkey rsa:4096 -nodes -sha256 -keyout domain.key -x509 -days 365 -out domain.crt

  2. Create a Kubernetes secret to store the certificates:

    bash

    Copy code

    kubectl create secret tls registry-tls \  --cert=domain.crt \  --key=domain.key \  --namespace=docker-registry

  3. Modify the deployment to use the certificates:

    Update docker-registry-deployment.yaml to include the secret:

    yaml

    Copy code

    apiVersion: apps/v1 kind: Deployment metadata:  name: docker-registry  namespace: docker-registry spec:  replicas: 1  selector:    matchLabels:      app: docker-registry  template:    metadata:      labels:        app: docker-registry    spec:      containers:      - name: registry        image: registry:2        ports:        - containerPort: 5000        volumeMounts:        - name: registry-storage          mountPath: /var/lib/registry        - name: tls-secret          mountPath: /certs          readOnly: true        env:        - name: REGISTRY_HTTP_TLS_CERTIFICATE          value: /certs/tls.crt        - name: REGISTRY_HTTP_TLS_KEY          value: /certs/tls.key      volumes:      - name: registry-storage        emptyDir: {}      - name: tls-secret        secret:          secretName: registry-tls

Apply the updated deployment:

bash

Copy code

kubectl apply -f docker-registry-deployment.yaml

Step 5: Configure Authentication

To further secure your registry, you can enable basic authentication.

  1. Create a password file:

    bash

    Copy code

    docker run --entrypoint htpasswd registry:2 -Bbn username password > auth/htpasswd

  2. Create a Kubernetes secret to store the password file:

    bash

    Copy code

    kubectl create secret generic registry-auth \  --from-file=htpasswd=auth/htpasswd \  --namespace=docker-registry

  3. Update the deployment to use the authentication file:

    Modify docker-registry-deployment.yaml to include the auth secret:

    yaml

    Copy code

    apiVersion: apps/v1 kind: Deployment metadata:  name: docker-registry  namespace: docker-registry spec:  replicas: 1  selector:    matchLabels:      app: docker-registry  template:    metadata:      labels:        app: docker-registry    spec:      containers:      - name: registry        image: registry:2        ports:        - containerPort: 5000        volumeMounts:        - name: registry-storage          mountPath: /var/lib/registry        - name: tls-secret          mountPath: /certs          readOnly: true        - name: auth-secret          mountPath: /auth          readOnly: true        env:        - name: REGISTRY_HTTP_TLS_CERTIFICATE          value: /certs/tls.crt        - name: REGISTRY_HTTP_TLS_KEY          value: /certs/tls.key        - name: REGISTRY_AUTH          value: "htpasswd"        - name: REGISTRY_AUTH_HTPASSWD_REALM          value: "Registry Realm"        - name: REGISTRY_AUTH_HTPASSWD_PATH          value: /auth/htpasswd      volumes:      - name: registry-storage        emptyDir: {}      - name: tls-secret        secret:          secretName: registry-tls      - name: auth-secret        secret:          secretName: registry-auth

Apply the updated deployment:

bash

Copy code

kubectl apply -f docker-registry-deployment.yaml

Step 6: Access and Test the Private Registry

Now, you need to configure your local Docker client to trust the self-signed certificate and authenticate with the registry.

  1. Trust the self-signed certificate:

    Copy the domain.crt file to your Docker client's trusted certificates directory. On a Linux machine, it typically is:

    bash

    Copy code

    sudo cp domain.crt /etc/docker/certs.d/<registry-domain>/ca.crt

  2. Log in to the registry:

    bash

    Copy code

    docker login <registry-domain>:5000

  3. Push an image to the registry:

    bash

    Copy code

    docker tag ubuntu <registry-domain>:5000/ubuntu docker push <registry-domain>:5000/ubuntu

Step 7: Integrate with Kubernetes

To use the private registry in your Kubernetes cluster, you need to create a Kubernetes secret for pulling images.

  1. Create a Docker registry secret:

    bash

    Copy code

    kubectl create secret docker-registry regcred \  --docker-server=<registry-domain>:5000 \  --docker-username=username \  --docker-password=password \  [email protected] \  --namespace=default

  2. Use the secret in your pod specifications:

    Add the following to your pod YAML files:

    yaml

    Copy code

    spec:  imagePullSecrets:  - name: regcred

Conclusion

Setting up a private Docker registry in Kubernetes enhances security and control over your containerized applications. By following this guide, you have deployed a secure and authenticated private registry, tested its functionality, and integrated it with your Kubernetes cluster.

Compelling Summary: Secure and streamline your container deployment by setting up a private Docker registry in Kubernetes with this step-by-step guide.

References

By following these steps, you can efficiently manage your Docker images, ensuring secure and streamlined container deployments within your Kubernetes environment.