How To Setup Docker Registry In Kubernetes Using Traefik v2

More than a year ago I created a tutorial on How To Install A Private Docker Container Registry In Kubernetes:

How To Install A Private Docker Container Registry In Kubernetes
Get full control of where your images are stored

In this tutorial, I was using Traefik for exposing the Docker Registry which will allow to access the registry through HTTPS with a proper TLS certificate.

Unfortunately, the tutorial does not work anymore because the apiVersion of the Kubernetes IngressRoute used by any Traefik yaml file has changed.

Instead of using traefik.containo.us/v1alpha1 all IngressRoutes have to use traefik.io/v1alpha1.

Because of this problem, I recreated setting up the Docker Container Registry tutorial in a simple way. For more information or explanation switch to my previous tutorial.

Prepare For Deployment

Create Kubernetes Namespace

First, we create a namespace that we use for our registry:

kubectl create namespace docker-registry

Add PersistentVolumeClaim

To add the PVC we create a registry-pvc.yaml file and add:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: docker-registry-pv-claim
  namespace: docker-registry
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 60Gi
  storageClassName: csi-cinder-classic

Then let's deploy the file to our Kubernetes using:

kubectl apply -f registry-pvc.yaml

Deploy Docker Registry

Before deploying our Docker Container Registry we should create a secret that we use to authenticate when pushing/pulling. To simplify this step I created a script that can be used for this purpose. Create a new file generate-password-files.sh and add:

export REGISTRY_USER=admin
export REGISTRY_PASS=registryPass
export DESTINATION_FOLDER=./registry-creds
   
# Backup credentials to local files (in case you'll forget them later on)
mkdir -p ${DESTINATION_FOLDER}
echo ${REGISTRY_USER} >> ${DESTINATION_FOLDER}/registry-user.txt
echo ${REGISTRY_PASS} >> ${DESTINATION_FOLDER}/registry-pass.txt
   	
docker run --entrypoint htpasswd registry:2.7.0 \
    -Bbn ${REGISTRY_USER} ${REGISTRY_PASS} \
    > ${DESTINATION_FOLDER}/htpasswd
      
unset REGISTRY_USER REGISTRY_PASS DESTINATION_FOLDER

To generate the files execute:

sh generate-password-files.sh

This will create two files (registry-user.txt and registry-pass.txt) in your destination folder(./registry-creds) with the needed strings.


Now, to Install and Deploy the registry we will use Helm the Kubernetes Package Manager. First, we will add the Helm Repository and create a chart-values.yaml which will contain our specific data.

1. Create chart-values.yaml:

---
replicaCount: 1
persistence:
  enabled: true
  size: 60Gi
  deleteEnabled: true
  storageClass: csi-cinder-classic
  existingClaim: docker-registry-pv-claim
secrets:
  htpasswd: admin:$2y$05$Gh/3ppmkuIXJIVyBBtHf0ug.wnnJvbtSEzlXz6z/7oO7XvF/xq7Ni
💡
Note: Replace the htpasswd string with your username/password combination.

2. Add and Update Helm Repository

helm repo add twuni https://helm.twun.io
helm repo update

3. Install Docker Registry

helm install -f .\chart-values.yaml docker-registry --namespace docker-registry twuni/docker-registry

Add Traefik IngressRoute

Now we can add the Traefik IngressRoute which will expose the Docker Container Registry.

To do this we have to create a file called ingress-route.yaml and add:

---
kind: IngressRoute
apiVersion: traefik.io/v1alpha1
metadata:
  name: docker-registry
  namespace: docker-registry

spec:
  entryPoints:
    - websecure

  routes:
    - match: Host(`YOUR_DOMAIN`)
      kind: Rule
      services:
        - name: docker-registry
          port: 5000
💡
Note: Set YOUR_DOMAIN to the URL you want to use to access your Docker Container Registry

This file can then be easily applied to our Kubernetes cluster by executing:

kubectl apply -f ingress-route.yaml

Test connection

The last step will be to test if the Docker Container Registry is working. To check this we can simply download any Docker image and push it to our newly set upped Container Registry.

First, we pull an image from Docker Hub by executing:

docker pull nginx

Then we tag the image with a custom name and add our Docker Registry domain name as prefix:

docker tag nginx YOUR_DOMAIN/my-personal-nginx

Then we have to login into our Docker Container Registry:

docker login \
   -u $(cat ./registry-creds/registry-user.txt) \
   -p $(cat ./registry-creds/registry-pass.txt) \
   YOUR_DOMAIN

Now, we can try to push our personal NGINX image to our Private Container Registry by executing:

docker push YOUR_DOMAIN/my-personal-nginx

If there are no errors, our Kubernetes Docker Container Registry is working and we can start using it.

Closing Notes

This simple update to my previously written tutorial, "How To Install A Private Docker Container Registry In Kubernetes", should help you to deploy a private Docker Container Registry in your Kubernetes cluster with a newer version of Traefik.

If you need further information on how to apply this tutorial or have any questions, please ask them in the comments. I will try to answer them if possible.

Feel free to connect with me on MediumLinkedInTwitter, and GitHub.