Setting up private secure docker registry as service with authentication

Setting up private secure docker registry as service with authentication

Its extremely necessary to have a docker registry within your docker/kubernetes eco systems. Commonly we setup insecure docker registry by running registry image as docker container. BUT its recommended to have secure docker registry running as service(which gives you provision to have HA with multiple replica) for production grade environment. This blog will help you to setup secure docker registry running as service quickly.

Step- 1: Generate SSL certificate

Goal is to generate self signed ssl certificate and use it to secure docker registry. We would use openssl in order to generate ssl cert. Please skip this step if you have certificate from trusted authorities already.

 openssl genrsa -out ca.key 2048
 openssl req -new -x509 -days 365 -key ca.key -subj '/C=US/ST=WA/L=Bellevue/O=xyzInc/OU=IoT/CN=' -out ca.crt
 openssl req -newkey rsa:2048 -nodes -keyout server.key -subj '/C=US/ST=WA/L=Bellevue/O=xyzInc/OU=IoT/CN=' -out server.csr
#self sign
 openssl x509 -req -extfile <(printf 'subjectAltName=IP:,IP:,') -days 365 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt
 openssl x509 -in server.crt -text -noout
# please look for DNS entry/IP address.

Step 2: Create htpasswd entry for basic authentication

We will be using basic auth “htpasswd” utility to create a auth entry and use it to password protect the docker registry.

Please install if your environment missing the above htpasswd utility

#RHEL/CentOS based packages. Please modify the below according to your OS distribution 
sudo yum install httpd httpd-tools -y

Generate the auth entry

htpasswd -cB ~/.htpasswd cloud-user
 #enter password: Example - CC@123
 #this will create a .htpasswd file in user's home dir

Add any additional user

htpasswd -cB ~/.htpasswd testuser
 #Please enter the password
 # Its also possible to provide password with the above command $htpasswd -cB ~/.htpasswd testuser password@321

Step 3: Prepare docker node(s) to host the docker registry

Copy the ssl certificate into below location and restart the docker service. This will help docker service to trust the self signed certificate otherwise you might get certificate error.

 sudo mkdir -p /etc/docker/certs.d/
 sudo cp server.crt /etc/docker/certs.d/
 sudo systemctl restart docker

Start a docker swarm. Init manager and add as many nodes as you wish to have.

#Init.. Store the output to additional node joining 
 sudo docker swarm init --advertise-addr
 #List nodes
 sudo docker node ls
 #Label node(s) to host registry
 sudo docker node update --label-add registry=true <hostname>

Step 4: Create Registry docker service

We would create a docker service in this final part of the setup and test the registry.

Create docker secret for key as well as certificate

#sudo docker secret create <<target>> server.crt
sudo docker secret create domain.crt server.crt
sudo docker secret create domain.key server.key
# Please use the below if you wish to delete them
#sudo docker secret rm domain.crt domain.key

Create the below dir to be mounted with the registry

sudo mkdir -p /var/lib/registry/
sudo mkdir -p /mnt/registry

Create the service

sudo docker service create \
   --name cc-registry \
   --secret domain.crt \
   --secret domain.key \
   --constraint 'node.labels.registry==true' \
   --mount type=bind,src=/mnt/registry,dst=/var/lib/registry \
   --mount type=bind,src=~/.htpasswd,dst=/cc-registry.htpasswd \
   -e REGISTRY_HTTP_TLS_CERTIFICATE=/run/secrets/domain.crt \
   -e REGISTRY_HTTP_TLS_KEY=/run/secrets/domain.key \
   -e REGISTRY_AUTH=htpasswd \
   -e REGISTRY_AUTH_HTPASSWD_PATH=/cc-registry.htpasswd \
   --publish published=443,target=443 \
   --replicas 1 \
#Please use the below if you wish to delete them. Also adjust the name, replicas etc as per your need.
 #sudo docker service rm cc-registry

Docker login test

sudo docker login --username cloud-user
 #Provide password
 #You should get a login succ msg otherwise please revisit the above steps.

Image push/pull test

sudo docker pull busybox
 sudo docker tag busybox
 sudo docker push
 sudo docker pull
 #You should able to perform the above operations otherwise please revisit the above steps.