docker configures private warehouses

Keywords: Docker CentOS OpenSSL SELinux

This tutorial uses the operating system CentOS 7.

docker installation configuration

If the docker is not installed on the machine, it can be installed quickly by the following means (for maximum consistency, the version specified here):

yum -y install docker-1.12.6-28.git1398f24.el7.centos.x86_64
#Start docker
systemctl start docker

# Set to Start Up
systemctl enable docker

Check the docker version to confirm the installation results:

[root@localhost ~]#docker -v
Docker version 1.12.6, build 1398f24/1.12.6

1. Use warehouses that do not require authentication

1. Do not use secure links

Without authentication warehouse and without using secure links, it is very simple to pull a registry image on the server side, then run with docker run, and then configure the client simply.

Warehouse configuration

Retrieve the private warehouse image:

docker pull registry:2.5

Start a registry repository container:

docker run -d --restart=always –privileged=true \
--name registry -p 5000:5000 \
-v /opt/data/registry:/var/lib/registry  \
docker.io/registry:2
  • restart=always This pattern container and docker daemon will automatically restore with the restart of the docker service
  • - v/opt/data/registry:/var/lib/registry mounts local disks to container disks/var/lib/registry (by default, the warehouse stores images in the container's/var/lib/registry directory)
  • name myregistry defines container name
  • - p 5000:5000 port mapping, local port 5000 mapping to container port 5000
  • - privileged=true: configure - v/opt/data/registry:/var/lib/registry. If the security module selinux is not closed, the container will not have access to the local directory. Setting this parameter can give the container privileges. If selinux is not turned off and this parameter is not added, permission errors may be reported (OSError: [Errno 13] Permission denied:'/var/lib/registry/repositories/library') or (Received unexpected HTTP status: 500 Internal Server Error)

Firewall opens 5000 ports:

firewall-cmd --zone=public --add-port=2375/tcp --permanent
firewall-cmd --zone=public --add-port=2375/udp --permanent
firewall-cmd --reload

Client Configuration

(ps: The client can be the same machine that runs the warehouse, as follows)
Starting with version 1.3.2 of docker, https connection is used by default, because certificate configuration is not performed at the start-up above, and configuration items must be changed on each client docker host that needs to connect to the private warehouse to enable the client to connect to the request warehouse using using HTTP. Different system configurations may vary. Here are some common system configurations. Please search for the rest of the systems.

CentOS&Ubuntu

Steps:

Modify configuration, CentOS configuration file path: / etc/sysconfig/docker
# vim  /etc/sysconfig/docker
 Add startup options (appended later),.
# OPTIONS='--insecure-registry 10.20.26.52:5000' CentOS 7 system
 # Other_args='--insecure-registry 10.20.26.52:5000'#CentOS 6 system
 Restart docker after adding

Configuration file path under Ubuntu: / etc/init/docker.conf

Redhat7

The Redhat7 system needs to be configured in the file / etc / system D / system / docker. service. D / docker. conf (new if not), as follows:

[Service]
ExecStart=
ExecStart=/usr/bin/docker daemon -H fd:// --insecure-registry=10.20.26.52:5000

After saving the changes, restart

[root@localhost /]# systemctl daemon-reload
[root@localhost /]# service docker restart

Boot2docker (the system installed by default using windows dockertools is applicable)

Steps:

Log in to boot2docker virtual machine using docker ssh
# docker ssh <name>
Use commands to modify configuration files.
# sudo vi /var/lib/boot2docker/profile 
   Add a line at the end of the document:
# EXTRA_ARGS="--insecure-registry 10.20.26.52:5000"
Exit the virtual machine and restart it
# docker-machine restart <name>

Verification

When the configuration is complete, use docker login to verify whether it is accessible (because no user is configured, any input can be logged in successfully when prompted):

[root@server registry]# docker login 127.0.0.1:5000
Username: 2
Password: 
Login Succeeded

Without the above configuration, client login or connection will have the following prompts:

[root@server registry]# docker login 10.20.26.52:5000
Username: 2
Password: 
Error response from daemon: Get https://10.20.26.52:5000/v1/users/: http: server gave HTTP response to HTTPS client

It should be noted here that although Get is prompted in the prompt https://127.0.0.1:5005/v1/users/ It seems to have accessed the link address of the registry v1 repository. In fact, the docker login operation accesses the addresses of v2 and v1 in turn, and the last log information displayed on the command line is the last failed log information.

In order to let you know the login process clearly, the following log information is posted for your reference.
If there is no log information for configuration (logs from system CentOS 7): ____________

8 Month 0214:21:18 server dockerd-current[32106]: time="2018-08-02T14:21:18.811035053+08:00" level=info msg="Error logging in to v2 endpoint, trying next endpoint: Get https://10.20.23.52:5000/v2/: http: server gave HTTP response to HTTPS client"
8 Month 0214:21:18 server dockerd-current[32106]: time="2018-08-02T14:21:18.811306066+08:00" level=info msg="Error logging in to v1 endpoint, trying next endpoint: Get https://10.20.23.52:5000/v1/users/: http: server gave HTTP response to HTTPS client"
8 Month 0214:21:18 server dockerd-current[32106]: time="2018-08-02T14:21:18.811320903+08:00" level=error msg="Handler for POST /v1.26/auth returned error: Get https://10.20.23.52:5000/v1/users/: http: server gave HTTP response to HTTPS client"

If log information is properly configured (log from boot2docker):

time="2018-08-02T09:38:43.975291248Z" level=debug msg="Calling GET /_ping"
time="2018-08-02T09:38:43.975756760Z" level=debug msg="Calling GET /v1.28/info"
time="2018-08-02T09:38:45.603555104Z" level=debug msg="Calling POST /v1.28/auth"
time="2018-08-02T09:38:45.603621065Z" level=debug msg="form data: {\"password\":\"*****\",\"serveraddress\":\"10.20.26.52:5000\",\"username\":\"2\"}"
time="2018-08-02T09:38:45.603676682Z" level=debug msg="attempting v2 login to registry endpoint https://10.20.26.52:5000/v2/"
time="2018-08-02T09:38:45.640464885Z" level=info msg="Error logging in to v2 endpoint, trying next endpoint: Get https://10.20.26.52:5000/v2/: http: server gave HTTP response to HTTPS client"
time="2018-08-02T09:38:45.640546495Z" level=debug msg="attempting v2 login to registry endpoint http://10.20.26.52:5000/v2/"

2. Configuring secure connections

Starting with docker version 1.3.2, TLS is used by default to ensure secure data transmission when registry is used. The following will demonstrate how to install a registry using secure links.

Warehouse configuration

Step 1: Generate certificates

Certificates can be purchased by the certification authority. Here we use openssl to generate certificates.
Generally, certificates only support domain name access. In order to support IP address access, it is necessary to modify the configuration file openssl configuration file, and then generate certificates.
In CentOS7 system, the file storage location is / etc/pki/tls/openssl.cnf. In the [v3_ca] section, add the subjectAltName option (fill in the actual IP of the operator):

[ v3_ca ]
subjectAltName = IP:10.20.26.52

After modifying the configuration, self-signed certificates are generated:

mkdir -p /opt/docker/registry/certs
 
openssl req -x509 -days 3650 -nodes -newkey rsa:2048 \
-keyout /opt/docker/registry/certs/domain.key \
-out /opt/docker/registry/certs/domain.crt
...
Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:10.20.26.52:5000
Email Address []:

When generating, all operations can be returned directly without filling in any information generation. Or filling the warehouse in Common Name will use IP and port "10.20.26.52:5000".

Step 2: Start the container

The startup parameters are different from those above, so it is necessary to specify the container to use certificate-related path information:

mkdir /opt/docker/registry/certs/data
docker run -d \
--name repo  --restart=always \
-v /opt/docker/registry/data:/var/lib/registry \
-u root \
-p 5000:5000 \
-v /opt/docker/registry/certs:/certs \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
registry:2.5

Client Configuration

At this point, the client can connect to the client in two ways. One is to configure an unsafe HTTP connection as in the previous section. The other is to copy the certificate generated in the first step above to the dokcer client host.

Without any configuration, using docker login returns a similar error:

[root@server registry]# docker login 10.20.26.52:5000
Username: 33
Password: 
Error response from daemon: Get https://10.20.26.52:5000/v1/users/: http: server gave HTTP response to HTTPS client

Now we use certificates on the client side and copy the certificate domain.crt generated in the first step above into the corresponding folder of the docker client host. (Certificates used by docker are stored by default in the / etc/docker/cert.d directory, matched by domain name storage)
If it's a native test, you can use the cp command, and if it's a different machine, you can use the scp command.

cp /opt/docker/registry/certs/domain.crt /etc/docker/certs.d/10.20.26.52:5000/domain.crt

If it's a different machine, you can use the scp command

sudo scp -r root@10.20.26.52:/opt/registry/certs/registry.crt /etc/docker/certs.d/xxx.com:5000/domain.crt

At this point, we can use HTTPS (default mode) to use the warehouse, using docker login validation (again, because there is no configuration user at this time, the correct feedback to enter any character can be logged in successfully, if the error information should be returned to the configuration process error, please ensure that the directory and configuration characters are completely correct)

[root@server registry]docker login 10.20.26.230:5000
Username: 233
Password:
Login Succeeded

It is important to note that the client can still operate the warehouse with the same configuration (- insecure-registry) without using secure links in the previous section. This section only adds certificates on the warehouse side to support clients to use secure links, but does not force clients to use secure links (at least in the current version). So here is a warehouse that only adds certificates, and it can not be used as permission control to prevent other people from using the warehouse illegally. If security needs to be guaranteed, other means of security must be added on this basis.

2. Warehouses requiring authorization

Above all, we installed a private repository without permission checking, but many times we need to configure the warehouse permission based on security considerations. The following will explain how to configure the warehouse with permission control.
Registry supports three authentication methods (one can only be used at the same time): silly, token, and htpasswd.
Here we choose to configure using htpasswd + TLS

1. htpasswd + TLS

Warehouse configuration

The first step is to generate certificates

  • Refer to the section "Configuring secure connections" in the previous section.

The second step is to generate password credentials

mkdir /opt/docker/registry/certs/data
docker run --entrypoint htpasswd registry:2.5 -Bbn admin admin123 >> /opt/docker/registry/auth/htpasswd

Step 3 Start Container
Before this comparison, you need to specify the configuration of authentication mode and mount the password directory to the auth directory in the container at startup:

docker run -d --privileged=true \
-u root -p 5000:5000 \
--name repo --restart=always \
-v /opt/docker/registry/data:/var/lib/registry \
-v /opt/docker/registry/auth/:/auth/ \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm"  \
-e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" \
-v /opt/docker/registry/certs:/certs \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
registry:2.5
  • Parameter parsing
- restart=always This pattern container will automatically restore with docker daemon as the docker service restarts
-v /opt/registry/data:/var/lib/registry 
Mount local disks to container disks / var/lib/registry
 (By default, the warehouse stores images in the container's / var/lib/registry directory)
-v /opt/registry/auth/:/auth/ 
Mount Password Folder to Container/auth Folder
--name registry 2
 Define container name for easy startup
-p 5000:5000
 Port Mapping, <Local Port>: <Container Port>, Local Port 5000 Mapping to Container Port 5000
–-privileged=true 
This parameter container adds privileges, previously mounting the local directory to the container.
If the security module selinux is not closed locally, the container will not have permission to access the local directory.
If selinux is not turned off and this parameter is not added, permission errors may be reported when uploading the image.
OSError: [Errno 13] Permission denied: '/var/lib/registry/repositories/library'
perhaps
Received unexpected HTTP status: 500 Internal Server Error
-e "REGISTRY_AUTH=htpasswd" 
Configure authentication mode to htpasswd
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" 
Scope of authentication
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd 
Configure the password file path for htpasswd authentication
-v /opt/registry/certs:/certs
 Mount directory
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/registry.crt
 Specify certificate crt address
-e REGISTRY_HTTP_TLS_KEY=/certs/registry.key
 Specify the certificate key address

At this point, the warehouse service configuration is completed.

Client Configuration

The first step is to obtain a security certificate

Copy the certificate domain.crt generated in the first step above into the corresponding folder of the docker client host. (Certificates used by docker are stored by default in the / etc/docker/cert.d directory, matched by domain name storage)
If it's a native test, you can use the cp command, and if it's a different machine, you can use the scp command.

cp /opt/docker/registry/certs/domain.crt /etc/docker/certs.d/10.20.26.52:5000/domain.crt

If it's a different machine, you can use the scp command

sudo scp -r root@10.20.26.52:/opt/registry/certs/registry.crt /etc/docker/certs.d/xxx.com:5000/domain.crt

Step 2 Log in with the specified account

At this point, we can use HTTPS (default) to use the warehouse. Now we do the docker login verification configuration, because when the warehouse is configured, the authentication mode is specified and the account password is generated. At this time, when docker login is performed, users who use non-configuration will not be able to log in (return 401 Unauthorized), and can only log in through admin users in the above configuration and the correct password.

[root@server registry]# docker login 10.20.26.52:5000
Username (admin): 3
Password:
Error response from daemon: login attempt to https://10.20.26.230:5000/v2/ failed with status: 401 Unauthorized
[root@server registry]# docker login 10.20.26.52:5000
Username (admin): admin
Password:
Login Succeeded

It should be noted that:

At this point, you can still login by configuring (- insecure-registry) without using secure links (of course, you need to use the configurable username and password at this time). When you do not use secure links, the username and password will be transmitted in plaintext, which poses a serious security risk. Safe links should be used in daily use.

Abnormal situation and investigation

Exception 1: If the client does not configure the certificate, the following error will occur:

[root@server registry]# docker login 10.20.26.52:5000
Username (admin): admin
Password: 
Error response from daemon: Get https://10.20.26.52:5000/v1/users/: x509: certificate signed by unknown authority


Exception 2: If the certificate does not match or if openssl.cnf is not configured according to the above operation using the ip certificate, the following error message will appear:

[root@server registry]#docker login 10.20.26.52:5000
Username (admin): admin
Password:
Error response from daemon: Get https://10.20.26.52:5000/v1/users/: x509: certificate signed by unknown authority

[root@server registry]#docker login 10.20.26.230:5000
Username (admin): admin
Password:
Error response from daemon: Get https://10.20.26.230:5000/v1/users/: x509: cannot validate certificate for 10.20.26.230 because it doesn't contain any IP SANs

Exception three:
Container startup failure will result in non-landing, such as connection refused.

[root@d3xtserver registry]# docker login 10.20.26.52:5006
Username: admin
Password: 
Error response from daemon: Get https://10.20.26.52:5006/v1/users/: dial tcp 10.20.26.52:5006: getsockopt: connection refused

If there are abnormal conditions, first exclude whether the container started properly. Use dockers to check the container's condition:

[root@d3xtserver registry]# docker ps
CONTAINER ID        IMAGE                    COMMAND                  CREATED             STATUS                                  PORTS                    NAMES
40a6b1603c1d        docker.io/registry:2.5   "/entrypoint.sh /e..."   7 seconds ago       Restarting (2) Less than a second ago                            registry2
3b29b82a169a        registry:2.5             "/entrypoint.sh /e..."   22 minutes ago      Up 22 minutes                           0.0.0.0:5000->5000/tcp   repo

If status is found to be abnormal (Restarting...) The container starts abnormally.
There are many reasons for container exception, such as container configuration item error (check input), mount file non-existent (check file), etc. Please check each configuration item and associated configuration file item by item (exist and format correctly). You can also determine the scope of the problem by viewing the log

Docker logs < container name >

Use of private libraries

Private libraries have been built, and we can do some operation experience.

Get the hello-world image from the default library

docker pull hello-world

The image tag needs to upload on the client

[root@server ~]# docker tag hello-world 10.20.26.52:5000/hello-world

Push image

[root@server ~]# docker push 10.20.26.52:5000/hello-world

docker push 10.20.26.52:5000/hello-world
The push refers to a repository [10.20.26.64:5000/hello-world]
45761469c965: Pushed 
latest: digest: sha256:f3b3b28a45160805bb16542c9531888519430e9e6d6ffc09d72261b0d26ff74f size: 524

Delete local mirrors

[root@server ~]# docker rmi 10.20.26.52:5000/hello-world

Untagged: 10.20.26.52:5000/hello-world:latest
Untagged: 10.20.26.52:5000/hello-world@sha256:f3b3b28a45160805bb16542c9531888519430e9e6d6ffc09d72261b0d26ff74f
Deleted: sha256:1815c82652c03bfd8644afda26fb184f2ed891d921b20a0703b46768f9755c57
Deleted: sha256:45761469c965421a92a69cc50e92c01e0cfa94fe026cdd1233445ea00e96289a

Getting Mirrors from Private Warehouses

[root@server ~]# docker pull 10.20.26.52:5000/hello-world
Using default tag: latest
Trying to pull repository 10.20.26.64:5000/hello-world ... 
sha256:f3b3b28a45160805bb16542c9531888519430e9e6d6ffc09d72261b0d26ff74f: Pulling from 10.20.26.64:5000/hello-world
b04784fba78d: Pull complete 
Digest: sha256:f3b3b28a45160805bb16542c9531888519430e9e6d6ffc09d72261b0d26ff74f
Status: Downloaded newer image for 10.20.26.64:5000/hello-world:latest

Query Warehouse Mirror

  • View mirror physical files using commands on the server side
tree /opt/docker/registry/data

Access http interface:

  • Query mirror list: http://registy_ip:port/v2/_catalog
  • Query mirror details: http://registy_ip:port/v2/image_name/tags/list

Such as:

curl http://10.20.26.52:5000/v2/_catalog 
{"repositories":["hello-world"]}

curl http://10.20.26.52:5000/v2/image_name/tags/list
{"name":"hello-world","tags":["latest"]}

Reference document

Posted by rafadc on Wed, 08 May 2019 14:45:39 -0700