Docker tutorials sinhala
DevOps Red hat linux

Deploy a Docker registry server with Authentication

Before you can deploy a registry, you need to install Docker on the host. A registry is an instance of the registry image, and runs within Docker.

Install docker service with bellow commands.

dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo
dnf install -y docker-ce --nobest
systemctl enable --now docker
dockerstatus=`systemctl status docker | grep "active (running)"`
echo "Docker Service Status = $dockerstatus"

Run a local registry

docker pull registry
docker run -d -p 5000:5000 --restart=always --name registry registry:2

Secure Docker Private Registry

By default, Docker node uses a secure connection over TLS to upload or download images to or from the private registry. You can use TLS certificates signed by CA or self-signed on Registry server.

Here, I will use a self-signed certificate for securing Docker Registry. Let’s create a self-signed certificate using the following command.

[root@registry ~]# mkdir -p /certs

[root@registry ~]# openssl req -newkey rsa:4096 -nodes -sha256 -keyout /certs/ca.key -x509 -days 365 -out /certs/ca.crt

Generating a 4096 bit RSA private key
............................................++
.....................................................................................................++
writing new private key to '/certs/ca.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:LK
State or Province Name (full name) []:Western Province
Locality Name (eg, city) [Default City]:Colombo
Organization Name (eg, company) [Default Company Ltd]:Sysadmin.lk
Organizational Unit Name (eg, section) []:IT
Common Name (eg, your name or your server's hostname) []:dockerhub.sysadmin.lk
Email Address []:inbox@sysadmin.lk

Start Docker registry container with certificate information.

docker run -d -p 443:5000 --restart=always --name dockerhub -v docker-registry:/var/lib/registry -v /certs:/certs -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/ca.crt -e REGISTRY_HTTP_TLS_KEY=/certs/ca.key registry:latest

Allow ports on Firewall service
If your Docker Registry is on CentOS 7,8 or 9

[root@registry ~]# firewall-cmd --permanent --add-port=80/tcp
[root@registry ~]# firewall-cmd --permanent --add-port=443/tcp
[root@registry ~]# firewall-cmd --reload

Set up Authentication for a Private Registry
Docker allows us to store the images locally on a centralized server, but sometimes, it’s necessary to protect the images from external abuse. In that case, we’ll need to authenticate the registry with the basic htpasswd authentication.

Let’s first create a separate directory to store the Docker registry credentials and let’s run an httpd container to create a htpasswd protected user with a password:

docker run --entrypoint htpasswd httpd:2 -Bbn Prabath Password@123 > /usr/certs/users

Now, let’s run the same Docker registry container using the auth/htpasswd authentication file:

docker run -d -p 443:5000 --restart=always --name dockerhub -v docker-registry:/var/lib/registry -v /usr/certs:/usr/certs -e REGISTRY_HTTP_TLS_CERTIFICATE=/usr/certs/ca.crt -e REGISTRY_HTTP_TLS_KEY=/usr/certs/ca.key  -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/usr/certs/users registry: latest

Since the Docker registry is running with the basic authentication, we can now test the login using:

$ docker login  localhost-u Prabath -p Password@123
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded

Create and upload a Docker Image to a Private Registry server

NOTE: If the image name does not match with given format then docker push or pull command will try to upload or download the image from the public registry, not from the private registry.

To rename the docker image use docker tag command.

root@build:~# docker tag nginx:v1 dockerhub.sysadmin.lk/nginx:v1

Upload a Docker Image
Depends on the communication mode (Secure or Non-Secure) of Docker Registry, follow any one of the below methods.

Non-Secure (Plain Http Registry)
Edit/Create the file “daemon.json” in “/etc/docker/” directory.

root@build:~# vi /etc/docker/daemon.json

{
  "insecure-registries" : ["dockerhub.sysadmin.lk"]
}

If you are using Secure (Self-signed) certificate, you have to follow below steps.

mkdir /etc/docker/certs.d/dockerhub.sysadmin.lk/ && cd /etc/docker/certs.d/dockerhub.sysadmin.lk/
scp root@dockerhub.sysadmin.lk:/usr/certs/ca.crt .

In both cases, you would need to restart the Docker engine service.

systemctl restart docker

now you can upload a Docker Images as below.

root@build:~# docker push dockerhub.sysadmin.lk/nginx:v1

Download the docker image to private registry server using the following command.

[root@deploy ~]# docker pull dockerhub.sysadmin.lk/nginx:v1

Docker Registry API – Listing
At the time of writing, V2 is the current version of the Registry API. Let’s explore how to use it to list images and tags from a remote registry.

Let’s assume we have a registry deployed at the URL https://my-registry.io. We’ll use curl to execute the HTTP requests.

$ curl -X GET my-registry.io/v2/_catalog
{"repositories":["centos","ubuntu"]}

We should note that authentication may be required to access certain repositories if it has been enabled. In such cases, we can pass in the username and password as parameters to the curl command using the -u option.

$ curl -u user:password -X GET my-registry.io/v2/_catalog 
{"repositories":["centos","ubuntu"]}

Listing Tags

The method to list tags is similar to the v2 API. However, the output is different in this case:

$ curl -X GET https://registry.hub.docker.com/v1/repositories/baeldung/mesos-marathon-demo/tags
[{"layer": "", "name": "32"}, {"layer": "", "name": "33"}, {"layer": "", "name": "34"}]

As we can see, instead of a single array of tags, we have an array of objects. Each object includes the name of the tag and the layer ID of the image.

If needed, we can convert the response to an array. To do so, let’s pipe the output into the jq command and parse the JSON:

$ curl -s GET https://registry.hub.docker.com/v1/repositories/baeldung/mesos-marathon-demo/tags | jq -r '[.[].name]'
[
  "32",
  "33",
  "34"
]

Let’s understand the jq command and expressions used here:

  • The -r flag returns the output as raw text.
  • The expression .[].name returns the name property from each object from the curl output.
  • The square brackets [] around the expression indicate that we want to collect the output in an array.

Finally, the -s flag used with the curl command is required to suppress the progress bar output.

Loading

Leave a Reply

Your email address will not be published. Required fields are marked *