Copyright notice: This article is the blogger’s original article, shall not be reproduced without the permission of the blogger. The author can be reached at jishuhui_2015.

Preface,

Build, Ship and Run any App, Anywhere

More concepts about Docker will not be described in this article. As a rising star in the virtualization market, Docker is favored by more and more enterprises, and more and more developers decide to embrace Docker.

The “container” is the design philosophy behind Docker, which makes it much easier for a single physical machine (or virtual machine) to run multiple isolated applications at the same time, thanks to the underlying technologies of Linux and, of course, OS X and Windows.

Docker has enough related tutorials, but due to the rapid development of Docker in recent years, version iteration speed is fast, and there are incompatibility between multiple versions, if you find blog articles on the Internet, you may not be able to solve the problems you encounter.

Of course, there is no problem with the installation of Docker environment, basic commands and other content, and you can basically master the content of the official website by reading through the documents. However, when the author tried to build a set of Docker Registry based on SSL (recommended by the official website), he encountered a lot of trouble. For this part of content, most blog documents directly skipped SSL and adopted HTTP access form.

It is hereby shared that after reading through this article, setting up the Docker Registry is no longer a problem.

> docker --version

Docker version 18.03.1-ce, build 9ee9f40
Copy the code

The above is my Docker environment, it is recommended to install Docker1.6+ version.

In addition, the reader needs to:

1. A host (or VM) with the 64-BIT CENtos_7_os installed.

Apply for a domain name. Otherwise, you can change the HOST file, but success is not guaranteed. The author applied for a personal domain name in Aliyun, which took 5 years and was worth ¥105.

3. If you have applied for a domain name, please obtain a free CA certificate. SSL certificate is required for HTTPS access. Otherwise, you can use OpenSSL to build your own, which is also mentioned in many blog posts, with no guarantee of success;

4, install an nginx proxy, optional.

5. Be familiar with the basic concepts and common commands of Docker, but do not need to know advanced knowledge of Dockerfile, Compose, Swarm, Kubernetes, etc.

First, start with Docker image

Abstract concept elaboration does not say more, the author gives two examples, let everybody feel:

1. The ISO file we download from System Home may have multiple pre-installed software built in besides the basic operating system;

2. When using Maven to manage JAR dependencies, nexus is used as a proxy repository to avoid pulling dependencies from the central repository every time.

It can be considered that a Docker image is a series of software (files) combination, as long as they are placed on the appropriate host, can be done out of the box.

For the Docker image operations required in this article, there are five common commands:

A. Pull the image, followed by the image repository name. If you want to specify a version, you can add a tag.

> docker pull <repo>[:tag]
Copy the code

B. List all mirrors to obtain basic information about mirrors.

> docker images
REPOSITORY                   TAG             IMAGE ID          CREATED        SIZE
redis                       latest          bfcb1f6df2db      3 weeks ago     107MB
registry                      2             d1fd7d86a825      4 months ago    33.3MB
hyper/docker-registry-web   latest          0db5683824d8      19 months ago   599MB
Copy the code

C. Delete the mirror. You can delete the image based on the image ID or the image repository name.

> docker rmi <IMAGE ID>/<repo>
Copy the code

D. Mirror marking. You can compare this to Git marking, which is equivalent to releasing a usable mirrored version.

> docker tag <repo> <new_repo>[:tag]
Copy the code

E. Mirror push. You can also learn from the Push operations in the Git domain to push packaged images to a remote repository (the Docker Registry).

> docker push <new_repo>[:tag]
Copy the code

The above five commands are only a brief introduction and are not the focus of this article. For more mirror operation commands, please refer to it.

Readers are asked to pull down the Registry image before proceeding to the next steps.

> docker pull registry:2
2: Pulling from library/registry
81033e7c1d6a: Pull complete 
b235084c2315: Pull complete 
c692f3a6894b: Pull complete 
ba2177f3a70e: Pull complete 
a8d793620947: Pull complete 
Digest: sha256:672d519d7fd7bbc7a448d17956ebeefe225d5eb27509d8dc5ce67ecb4a0bce54
Status: Downloaded newer image for registry:2
Copy the code

This process will take a few minutes, depending on network conditions, please be patient.

Note: in pull, the author specified a TAG, that is, to use the V2 version of Registry. For the V1 version of Registry, readers need not care about it, it is basically obsolete.

Second, sneak peek

For those eager to see how the Docker Registry works, you can read this section first.

Run the following command:

> docker run -d \
 -p 5000:5000 \
 -v /usr/local/registry:/var/lib/registry \
 --restart=always \
 --name registry \
 registry:2
Copy the code

This is a typical run command, and Registry starts up on port 5000 if nothing goes wrong.

To verify this, the reader can pull a BusyBox image (because of its small size) and experiment.

> docker pull busybox
Copy the code

After pulling the latest BusyBox image, mark it for publication to Registry.

> docker tag busybox localhost: 5000 / bosybox: v1.0Copy the code

Finally, it is pushed to Registry.

> docker push localhost: 5000 / bosybox: v1.0Copy the code

At this point, Registry has busyBox :v1.0 image, which can be pulled from the Docker Hub.

> docker pull localhost: 5000 / bosybox: v1.0Copy the code

To see which images are available in the remote repository, run the following command:

> curl http://localhost:5000/v2/_catalog
Copy the code

From the above commands, we can draw an important conclusion:

Access to Registry is done through a set of REST apis.

So far, we have built a “half-finished” Docker Registry. We say “half-finished” because the Registry only works on this machine, and attempts to push images on other hosts will fail.

In order to achieve this, you must use a CA security certificate.

3. Modify Registry based on SSL certificate

Before proceeding with this section, please confirm that the conditions listed at the beginning of this article are met.

The author applied for a domain name: iwendao. VIP, and mapped out a secondary domain name: Registry.iwendao. VIP, which was specially used to access Docker Registry, and then applied for CA certificate based on this secondary domain name.

If there is no accident, the free certificates applied from Aliyun are issued by Symantec. After downloading the certificates, there are two files in the compressed package: XXXXXXXX. pem and xxxxXXXX.key.

Change the file name to server.key, server.pem, and upload the file to the /usr/local/certs directory.

> ll /usr/local/certs
- rw-r--r-- 1 root root 1678 May 28 13:42 server.key
- rw-r--r-- 1 root root 3662 May 28 13:42 server.pem
Copy the code

Since intermediate certificate is issued, it will be found that there is no CRT file, you can use the following command to obtain:

> cat server.pem > server.crt
Copy the code

Directly input the contents of the PEM file as the CRT file to generate the server. CRT file.

At this point, the domain name and its certificate are ready.

If you want to use nginx as a proxy, you need to change the nginx.conf file.

user root root; worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log logs/access.log main; sendfile on; keepalive_timeout 60; gzip on; server { listen 443; server_name i-wendao; ssl on; root html; index index.html index.htm; ssl_certificate /usr/local/certs/server.pem; ssl_certificate_key /usr/local/certs/server.key; ssl_session_timeout 5m; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:! NULL:! aNULL:! MD5:! ADH:! RC4; Ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; location ~ { proxy_pass_header Server; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Scheme $scheme; proxy_pass https://registry; }} upstream registry {server 127.0.0.1:5000; }}Copy the code

There are two things to note in the nginx.conf configuration file:

1. To enable SSL of nginx, you only need to configure the pem and key files downloaded before. This is the official example given by Ali Cloud.

2. Because the access to Registry is completed through REST API and HTTPS access protocol, proxy_pass is configured as https://registry in the configuration of location node. If it is configured as http://registry, Once SSL is enabled, Docker Registry is inaccessible.

Now that the host configuration is complete, let’s configure the Docker container.

There are two ways to deploy the Docker Registry Server:

First, for the case of few parameters, can be directly specified in the docker run command;

The other is through the YAML configuration file, which allows you to configure multiple parameters at once.

In this section, I will use the first deployment method, and the second deployment method can be found in the attached article.

> docker run -d \
  -p 5000:5000 \
  -v /usr/local/registry:/var/lib/registry \
  -v /usr/local/certs:/certs \
  -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/server.crt \
  -e REGISTRY_HTTP_TLS_KEY=/certs/server.key \
  --restart=always \
  --name registry \
  registry:2
Copy the code

If you do not have nginx installed, run this command:

> docker run -d \
  -p 443:443 \
  -v /usr/local/registry:/var/lib/registry \
  -v /usr/local/certs:/certs \
  -eREGISTRY_HTTP_ADDR = 0.0.0.0: \ 443-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/server.crt \
  -e REGISTRY_HTTP_TLS_KEY=/certs/server.key \
  --restart=always \
  --name registry \
  registry:2
Copy the code

As can be seen, when SSL is enabled for Docker Registry Server, CRT and key certificate files are used.

Now, let’s experiment.

> docker tag busybox registry. Iwendao. VIP/bosybox: v1.0Copy the code

Finally, it is pushed to Registry.

> docker push registry. Iwendao. VIP/bosybox: v1.0Copy the code

See what mirrors the remote repository has.

> curl https://registry.iwendao.vip/v2/_catalog
Copy the code

Repeat the preceding steps on another host. If the system still succeeds, the system is successfully set up.

Four, the support of Authentication

Through the establishment of Registry Server, we can obviously feel that Docker pays enough attention to security control, which is exactly the right approach in the context of HTTPS of the whole network.

This section is an advanced guide to making Docker’s security mechanism more thorough — plus the login verification mechanism.

Obviously, since it is private, it means that not everyone can submit the image, only with the login user and password.

Of course, the login verification mechanism requires HTTPS. Otherwise, the user name and password are transmitted in plain text.

Docker authentication mechanism also has many implementations, which can be directly used by proxy (such as Nginx) to intercept verification before Registry. Some high-end ones have Token servers to guide users to authorize login, which is difficult to implement.

In this paper, the most simple htpasswd in the implementation of login verification mechanism. More information about htpasswd is beyond the scope of this article. Please check it out for yourself.

If the command tool is not installed on the host, run the following command:

> yum install httpd-tools
Copy the code

Since htpasswd is an Apache2 accessory utility command, it should be available if Apache2 is installed.

If you don’t want to install it, you can just use the Registry image, which has HTTPD built in.

Assume that the password file is stored in the /usr/local/auth directory, run the following command

> htpasswd -Bbn admin 123456 > /usr/local/auth/passwd
Copy the code

Use the HTTPD built into the Registry image as follows:

> docker run --entrypoint htpasswd registry:2 -Bbn admin 123456 > /usr/local/auth/passwd
Copy the code

Both methods achieve the same goal: generate the username and password in the /usr/local/auth/passwd file.

In the command, admin is the user name and 123456 is the password.

View the contents of the passwd file:

> cat /usr/local/auth/passwd
admin:$2y$5$/2H8DTcY.1JROHm0MnnK8.UulmbSclib63qTe8FGyWnnE9XWBz3cy
Copy the code

The same command generates different results on different hosts. Therefore, the password file generated on host A cannot be used for authentication on host B.

It is time to start the Registry container:

> docker run -d \
  -p 5000:5000 \
  --restart=always \
  --name registry \
  -v /usr/local/auth:/auth \
  -e REGISTRY_AUTH=htpasswd \
  -e REGISTRY_AUTH_HTPASSWD_REALM=Registry_Realm \
  -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/passwd \
  -v /usr/local/certs:/certs \
  -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/server.crt \
  -e REGISTRY_HTTP_TLS_KEY=/certs/server.key \
  registry:2
Copy the code

If you attempt to view the mirrors in the remote repository, the following information is displayed:

> curl https://registry.iwendao.vip/v2/_catalog
{
	"errors": [{
		"code": "UNAUTHORIZED"."message": "authentication required"."detail": [{
			"Type": "registry"."Class": ""."Name": "catalog"."Action": "*"}}}]]Copy the code

The pull and push operations are also limited. Therefore, before you can do anything, you need to log in.

> docker login https://registry.iwendao.vip
Copy the code

If there is login, of course there is logout.

> docker logout https://registry.iwendao.vip
Copy the code

V. WEB UI for Registry

Once we have Registry Server set up, it is time to manage our image. At this point, you will find that there is no visual tool to help users with image management.

There are many open source WEB UI management tools available:

1, the docker – registry – frontend. As of Now (May 2018), the feature is mainly mirror list view, tag view, image deletion is not open, open source on GitHub, stars 1K +.

2, the docker – registry – web. Compared with the Docker-Registrie-Frontend project, this project provides image deletion function and connects to the role system, which has been further improved. It is open source on GitHub, stars 300+.

3, the Rancher. The positioning of this platform is similar to Kubernetes, not only image management is so simple, but also the whole Docker container management is competent.

4, shipyard. Unfortunately, the author no longer has the energy to maintain it, and judging from the stars on GitHub, it’s not hard to see its former glory.

The installation and deployment of the WEB UI will not be described here, but there are corresponding documents. If you don’t have special requirements for image management, you can skip the WEB UI or use one of the first two.

Six, summarized

This paper details the process of building Docker Registry private server and summarizes learning materials from various blogs and official websites to help readers build Docker Registry private server smoothly.


The attached:

1. Start Registry Server using yamL file

Suppose configuration file storage path is: / usr/local/registry/config. Yml

Edit its contents as follows:

version: 0.1
log:
  fields:
    service: registry
storage:
  cache:
    blobdescriptor: inmemory
  filesystem:
    rootdirectory: /var/lib/registry
    maxthreads: 100
  delete:
    enabled: true
http:
  addr: 0.0. 0. 0: 5000
  host: https://registry.iwendao.vip
  secret: yoogurt-taxi-123! @ #
  headers:
    X-Content-Type-Options: [nosniff]
  tls:
    certificate: /certs/214709594090104.crt
    key: /certs/214709594090104.key
health:
  storagedriver:
    enabled: true
    interval: 10s
    threshold: 3
Copy the code

For more configuration items, visit Configuring a Registry.

The configuration items in the configuration file are the environment variables that can correspond to the -e parameter in the previous section, and their rules are as follows:

1. The variable name consists of uppercase letters;

2, fixed prefix REGISTRY;

3. Change the colon (:) of the configuration item in YAML to underscore (_).

Such as:

REGISTRY_HTTP_TLS_CERTIFICATE, which corresponds to the HTTP: TLS: certificate configuration item;

REGISTRY_AUTH_HTPASSWD_PATH corresponds to the auth: htpasswd: path configuration item.

It is worth noting that the paths involved in the configuration file are in-container, which means that the mount directory needs to be specified with the -v parameter when the Registry image is started.

After saving the configuration file, you can start the container:

> docker run -d -p 5000:5000 --restart=always --name registry \
             -v /usr/local/certs:/certs
             -v /usr/local/registry/config.yml:/etc/docker/registry/config.yml \
             registry:2
Copy the code

2. Introduce books about Docker

  • The First Docker Book (Revised edition), the true Docker primer. Zero-based beginners can focus on the first five chapters of the basic part, master the relevant principles and use of Docker, can be used as a reference book. Reading this book, it is suggested to practice simultaneously with the content. After getting started, you can build up your interest in Docker so that you can continue to learn.
  • Docker Containers and Container Clouds (2nd edition), with advanced knowledge content. The first part is the basics, so you can go through it quickly. The book explains the concept of container clouds in many ways, and it is fascinating enough to absorb. Next comes container choreography and deployment, which you can add to practice and develop a feel for.
  • The definitive Guide to Kubernetes (2nd edition) is a worthy introduction to Kubernetes. After reading the Kubernetes section of Docker Containers and Container Clouds (2nd edition), it will be easier to read this book.