Motivation
In a previous post I summarized how to start a docker container in user mode.
When using multiple PCs (WorkStation, hereafter WS), it is necessary to consider how to realize a mechanism to share containers among multiple WS. In the case of singularity, we could store sif files on an NFS server and use them from other WS.
In case of docker, I decided to build a registry server, thinking that I could set up a private registry in my home network and operate it.
Sources
- Docker Registry server build flow I referred to this page for the server build flow and private key/certificate.
- TLS Authentication with Docker Private Registry Explained I used this page as a reference when I got stuck on authentication.
I thought it would be easy to build a rootless environment as long as I knew where to store the demon.json file. (xxxx.xxx.xxx.xxx.xxx is the IP address in the private registry’s local network environment)
{
"insecure-registries':[xxx.xxx.xxx.xxx:5000]"
}
However, it actually took quite a while to resolve the issue. The two pages above were helpful in resolving the issue.
The following is a summary of the steps to build a private registry in a rootless environment and push/pull it from other WSs. For the purpose of explanation, the WS that will be the private registry is called a server, and other WS are called clients.
Configuration
private registry server configuration
Create private key and certificate
Create a directory named “certs” under your $HOME directory, and create a key and a certificate under “certs”.
$ cd
$ mkdir certs
$ openssl req -newkey rsa:2048 -nodes -sha256 -keyout certs/ca.key -x509 -days 3650 -out certs/ca.crt -addext "subjectAltName = IP:192.168.xxx.yyy"
The point in the above is -addext “subjectAltName = IP:192.168.xxx.yyyy”. Here, 192.168.xxx.yyyy is the IP address of the private registry server.
When you execute the above command (openssl), you will be asked to enter the Country Name, etc. Except for the Common Name, you may enter a new line (do not enter anything). For myself, I used the “servername.com”.
/usr/share/ca-certificates/docker
Create a docker directory under /usr/share/ca-certificates and copy the key (ca.key) and certificate (ca.crt) created above.
$ cd
$ sudo mkdir /usr/share/ca-certificates/docker
$ sudo cp certs/ca.* /usr/share/ca-certificates/docker
$ sudo update-ca-certificates
$ sudo vi /etc/ca-certificates.conf
In the last part above, open /etc/ca-certificates.conf with vi and add docker/ca.crt to the last line.
Restart docker daemon
$ systemctl --user restart docker
Start the registry image
$ docker run -d -p 5000:5000 -v $PWD/certs:/certs \
-v /ext/registry:/var/lib/registry \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/ca.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/ca.key \
--restart=always registry:2
To be able to check the contents of the registry from outside the container, “-v /ext/registry:/var/lib/registry” is specified. As shown above, you can add the “-v” option to each mounted item.
Client-side configuration
Key and Certificate Storage
When configuring the client, the key and certificate created on the server side are required. Here, we assume that /mnt/nfs/tmp/ca.* is it.
# cd /usr/share/ca-certificate
# mkdir docker
# cp /mnt/nfs/tmp/ca.* docker
# vi /etc/ca-certificates.conf
Add docker/ca.crt to the last line of /etc/ca-certificates.conf as you did for the server.
# sudo update-ca-certificates
Restart docker daemon
$ systemctl --user restart docker
push image from client side
image to push
On the client side, there is a jupyterlab image like this.
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
pytorch-lab latest bac68bf54efe 21 hours ago 9.37GB
Tagged with
When pushing to the registry, include the IP address in the registry and tag it as follows
$ docker tag pytorch-lab:latest 192.168.xxx.yyy:5000/pytorch:lab
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.xxx.yyy:5000/pytorch lab bac68bf54efe 21 hours ago 9.37GB
pytorch-lab latest bac68bf54efe 21 hours ago 9.37GB
push image
$ docker push 192.168.xxx.yyy:5000/pytorch:lab
The push refers to repository [192.168.xxx.yyy:5000/pytorch].
(abbreviated below)
pull image from another client
pull image
$ docker pull 192.168.xxx.yyy:5000/pytorch:lab
lab: Pulling from pytorch
Digest: sha256:807b0cd1b8754072940730a02a1d00933b1c6caedbb162de2b98cbeae642838c
Status: Image is up to date for 192.168.xxx.yyy:5000/pytorch:lab
192.168.xxx.yyy:5000/pytorch:lab
startup
Start the pulled jupyterlab image as follows. In the following example, we assume that the current directory is jupyterlab, which contains the notebook.
$ docker run -d --rm --gpus all -v ${PWD}/jupyterlab:/workdir -p 8888:8888 192.168.xxx.yyy:5000/pytorch:lab
Summary
With the above steps, docker images can now be shared by multiple WSs.
The construction of the docker private registry took a long time and was quite difficult, but I learned a lot about keys, certificates, and other authentication issues through this construction.
I have little experience in this field and may have incorrect information. If you notice any errors, please point them out to me. Thank you in advance.
Translated with www.DeepL.com/Translator (free version)