Docker intranet: Docker-registry with Nginx & SSL on CentOS
Since Docker-registry is also a software application, the easiest way to do this is to use the officially provided image registry that has been deployed. The official documentation also gives suggestions for running sudo docker run -p 5000:5000 registry
commands directly. This can really start a registry server, but all uploaded images are actually managed by the Docker container and placed in the/var/lib/docker/.... Under a directory. And once the container is deleted, the image will be deleted as well. So we need to find a way to tell where the Docker container image should be stored. The default location of mirroring in registry mirroring is /tmp/registry
, so map this location directly, such as to the local /opt/data/registry
directory.
2. Build a Docker 2.1 installation on CentOS
docker-registry
There are several ways to run the following command directly:
# docker run -d -e SETTINGS_FLAVOR=dev -e STORAGE_PATH=/tmp/registry -v /opt/data/registry:/tmp/registry -p 5000:5000 registry
If the docker-registry is not pulled locally, the first run will pull registry, the runtime will map the path and port, and in the future you can /opt/data/registry
find out which mirrors are in the private repository and which ports on the host can be accessed.
You can also clone the project Https://github.com/docker/docker-registry.git to local and then use Dockerfile to build the image:
# git clone https://github.com/docker/docker-registry.git# cd docker-registry && mkdir -p /opt/data/registry# docker build -t "local-sean" .build完成后,就可以运行这个docker-registry我们先配置自己的config.yml文件,第一种方法是直接在run的时候指定变量# cp config/config_sample.yml /opt/data/registry/config.yml# vi /opt/data/registry/config.yml##这里可以设置本地存储SETTINGS_FLAVOR=dev,local STORAGE_PATH:/tmp/registry等待# docker run -d -v /opt/data/registry:/tmp/registry -p 5000:5000 -e DOCKER_REGISTRY_CONFIG=/tmp/registry/config.yml registry或docker run -d -e SETTINGS_FLAVOR=dev -e STORAGE_PATH=/tmp/registry -v /db/docker-images:/tmp/registry -p 5000:5000 registry
2.2 Client Use
Getting a mirror or submitting a mirror to a small file is now a simple matter of adding an address and port to the front of the warehouse 172.29.88.222:5000/centos6
. Note that you can choose not to use IP, but to use hostname, such as registry.domain.com:5000, but not only with .
the hostname Registry,docker will think registry is the user name, It is recommended to use hostname plus port with a domain name.
You can pull and push the image on another host to use Docker via this server:
从私服上搜索存在哪些可用镜像# curl -X GET http://sean.domain.com:5000/v1/search{"num_results": 2, "query": "", "results": [{"description": "", "name": "library/centos6"}, {"description": "", "name": "library/nginx"}]}按条件搜索nginx# curl -X GET http://sean.domain.com:5000/v1/search?q=centos6拉取image到本地docker pull library/centos6## 本地对份镜像启动起来,形成container## 给container去另外一个名字# docker tag 68edf809afe7 registry.domain.com:5000/centos6-test## 最后将新的docker images推送到私服上docker push registry.domain.com:5000/centos6-test
The user name, password, and mailbox are prompted for the first push to be created. You can also add a certification mechanism to the Docker server.
3. Join the NGINX Certification
(Before you actually do this, read this section before you decide if you want to add nginx to the front end)
3.1 Installing and configuring Nginx
As you can see from the above procedure, unless the firewall is restricted, any host can create an account and want to push the image, it is safer to join the login authentication mechanism in the outer layer.
最好安装1.4.x版本,不然下面的有些配置可能会不兼容# yum install nginx创建两个登录用户# htpasswd -c /etc/nginx/docker-registry.htpasswd seanNew password: Re-type new password: Adding password for user sean# htpasswd -c /etc/nginx/docker-registry.htpasswd itsection
In order for Nginx to use this password file, and forward 8080 port request to Docker Registry, add nginx config file
vi /etc/nginx/sites-enabled/docker-registry
:
# for versions of Nginx > 1.3.9 so include chunked transfer encoding support# Replace with appropriate values where n Ecessaryupstream docker-registry {server localhost:5000;} server {listen 8080; server_name sean.domain.com; --Your registry server_name # SSL on; # ssl_certificate/etc/ssl/certs/docker-registry; # ssl_certificate_key/etc/ssl/private/docker-registry; Proxy_set_header Host $http _host; # Required for Docker client sake Proxy_set_header x-real-ip $remote _addr; # Pass on real client IP client_max_body_size 0; # Disable any limits to avoid HTTP 413 for large image uploads # required to avoid HTTP 411:see Issue #1486 (https://gith ub.com/dotcloud/docker/issues/1486) chunked_transfer_encoding on; Location/{# Let Nginx know on our auth file auth_basic "Restricted"; Auth_basic_user_file docker-registry.htpasswd; Proxy_pass Http://docker-registry; } location/_ping {auth_basic off; Proxy_pass Http://docker-registry;} location/v1/_ping {auth_basic off; Proxy_pass Http://docker-registry; }}
让nginx来使用这个virtual-host# ln -s /etc/nginx/sites-enabled/docker-registry /etc/nginx/conf.d/docker-registry.conf重启nginx来激活虚拟主机的配置# service nginx restart
3.2 Using Docker-registry after joining the certification
At this point, port 5000 of the host should be disabled through the firewall (or docker run
only the IP of the loopback interface when the port is mapped -p 127.0.0.1:5000:5000
).
# curl localhost:5000"docker-registry server (dev) (v0.8.1)"
If direct access access will get unauthorized information:
# curl localhost:8080
Docker-registry with user authentication:
# curl http://sean:[email protected]:8080/v1/search{"num_results": 2, "query": "", "results": [{"description": "", "name": "library/centos6"}, {"description": "", "name": "library/nginx"}]}# docker login registry.domain.com:8080Username: seanPassword: Email: [email protected]n.comLogin Succeeded# docker pull registry.domain.com:8080/library/centos6
Without an accident, the above docker pull
will fail:
# Docker pull registry.domain.com:8080/library/centos6pulling repository registry.domain.com:8080/ LIBRARY/CENTOS62014/11/11 21:00:25 Could not reach any registry endpoint# Docker push Registry.domain.com:8080/ubuntu: Seanthe push refers to a repository [Registry.domain.com:8080/ubuntu] (len:1) sending image listpushing repository Registr Y.domain.com:8080/ubuntu (1 tags) 2014/11/12 08:11:32 HTTP Code 401, Docker won't send auth headers over Http.nginx log 201 4/11/12 07:03:49 [ERROR] 14898#0: *193 No User/password is provided for basic Authenticatget/v1/repositories/library/cen Tos6/tags http/1.1 ", Host:" registry.domain.com:8080 "
This issue is not seen in the 1th reference document after this article, but is mentioned in the comments.
Some people say that is backend storage
the problem, here is the local storage image, should not. After a lot of data, and repeated operation verification, is the docker-registry version of the problem. From the v0.10.0
beginning, docker login
Although succeeded, however pull
, the push
~/.dockercfg
user login information will not be allowed to be transmitted through HTTP in plaintext. (If you would like to be able to view v0.10.0
the source Registry.go, in the branch v0.9.1
and before it is not HTTP code 401, Docker will not send auth headers over HTTP的
)
The current approach is three:
- Retreat, that's why we're looking at the front of the operation.
- Replace with
v0.9.1
the following version. v1.3.1
I guess you're not going to do it.
- Modify the source Session.go, remove the corresponding judgment line, and then git down to reinstall. I guess you wouldn't do that.
- Install the SSL certificate and use HTTPS transport. This is a wise choice, and the new version of Docker also recommends that we do so and look down.
3.3 Installing an SSL certificate for NginxFirst open the three-line comment for SSL in the Nginx configuration file
# vi /etc/nginx/conf.d/docker-registry.conf...server { listen 8000; server_name registry.domain.com; ssl on; ssl_certificate /etc/nginx/ssl/nginx.crt; ssl_certificate_key /etc/nginx/ssl/nginx.key;...
After saving, Nginx will separate from /etc/nginx/ssl/nginx.crt
and /etc/nginx/ssl/nginx.key
read the SSL certificate and the private key. If you are willing to pay for an SSL certificate yourself, it will be very simple to copy the certificate and the private key as above. For SSL and signing SSL certificates, refer to other articles.
Here we self-sign an SSL certificate that takes the current system as a (private) certificate issuing center (CA).
Create a directory where certificates are stored
# mkdir /etc/nginx/ssl
Confirm some of the CA's configuration files
# vi/etc/pki/tls/openssl.cnf ... [Ca_default]dir =/etc/pki/ca # Where everything is keptcerts = $dir/certs # Where the issued certs is keptcrl_dir = $dir/CRL # Where The Issued CRL is Keptdatabase = $d Ir/index.txt # Database index file. #unique_subject = no # Set to "no" to allow creation of # several ctificates with same subject.new_certs_dir = $dir/newcerts # Default Place for new certs.certificate = $dir/cacert.pem # the CA certificateserial = $dir/serial # The current serial numbercrlnumber = $dir/crlnumber # of the current CRL number # must be commented off to leave a V1 crlcrl = $dir/crl.pem # The current Crlprivate_key = $dir/private/cakey.pem # The private keyrandfile = $dir/private/.rand # private random number FILE...DEfault_days = 3650 # How long-certify for ... [Req_distinguished_name]countryname = country name (2 letter code) Countryname_default = Cncountryname_min = 2countryname_max = 2stateOrProvinceName = State or Provinc E name (full name) Stateorprovincename_default = GD ... [Req_distinguished_name] Part of the main is the certificate when some default value, can not move
(1) Generate root key
# cd /etc/pki/CA/# openssl genrsa -out private/cakey.pem 2048
For security reasons, modifying the CAKEY.PEM private key file permission to 600 or 400 can also be generated using a child shell ( umask 077; openssl genrsa -out private/cakey.pem 2048 )
, which is no longer duplicated.
(2) Generate root certificate
# openssl req -new -x509 -key private/cakey.pem -out cacert.pem
Will be prompted to enter some content, because it is private, so you can enter, it is best to remember to be consistent with the back. The above self-visa book cacert.pem
should be generated /etc/pki/CA
below.
(3) Generate an SSL key for our Nginx Web server
# cd /etc/nginx/ssl# openssl genrsa -out nginx.key 2048
Our CA center is the same as the server that is requesting the certificate, otherwise it should be generated on another server that needs to use the certificate.
(4) Signing request for Nginx Generate certificate
# openssl req -new -key nginx.key -out nginx.csr...Country Name (2 letter code) [AU]:CNState or Province Name (full name) [Some-State]:GDLocality Name (eg, city) []:SZOrganization Name (eg, company) [Internet Widgits Pty Ltd]:COMPANYOrganizational Unit Name (eg, section) []:IT_SECTIONCommon Name (e.g. server FQDN or YOUR name) []:your.domain.comEmail Address []:Please enter the following ‘extra‘ attributesto be sent with your certificate requestA challenge password []:An optional company name []:...
Also prompts to enter some content, other casually, except Commone Name
must if you want to grant the certificate of the server domain name or hostname, challenge password not fill.
(5) Private CA to issue certificates on request
# openssl ca -in nginx.csr -out nginx.crt
The above issuance process is used by default -cert cacert.pem -keyfile cakey.pem
, and these two files are the /etc/pki/CA
root keys and root certificates that were generated in the first two steps.
To this we already have all the files required to establish an SSL secure connection, and the server's CRT and key are located in the configured directory, only the root certificate CACERT.PEM
location is not sure where to place under CentOS6.
The following locations are not validated: (Adding Trusted root certificates to the server)
/etc/pki/ca-trust/source/anchors
, /etc/pki/ca-trust/source
, /etc/pki/ca-trust/extracted
,
/etc/pki/ca-trust/ extracted/pem/
, /etc/pki/tls/certs/cacert.crt
will error:
# Docker Login Https://registry.domain.com:8000Username (Sean): SEAN2014/11/14 02:32:48 Error response from Daemon:inval ID Registry endpoint:get https://registry.domain.com:8000/v1/_ping:x509:certificate signed by unknown authority# Curl H Ttps://sean:[email protected]:8000/curl: () Peer certificate cannot be authenticated with known CA Certificatesmore Details Here:http://curl.haxx.se/docs/sslcerts.htmlcurl performs SSL certificate verification by Default, using a "bundle" of Certificate Authority (CA) public keys (ca certs). If The default bundle file isn ' t adequate, you can specify an alternate file using the--cacert option. If This HTTPS server uses a certificate signed by a CA represented in the bundle, the certificate verification probably FA Iled due to a problem with the certificate (it might is expired, or the name might not match the domain name in the the URL). I f you ' d like to turn off Curl's verification of the certificate, use The-k (or--insecure) option.
(6) The only way to get the root certificate to work is to find one:
# cp /etc/pki/tls/certs/ca-bundle.crt{,.bak} 备份以防出错# cat /etc/pki/CA/cacert.pem >> /etc/pki/tls/certs/ca-bundle.crt# curl https://sean:[email protected]:8000"docker-registry server (dev) (v0.8.1)"
cacert.pem
ca-bundle.crt
You must restart the Docker daemon before appending the root certificate to it.
If docker login
the error persists certificate signed by unknown authority
, refer to running Docker with HTTPS to specify the trusted CA root certificate When starting the Docker background process:
The above with "if" is because at the beginning of the general prompt certificate signed by unknown authority
, some people say the root certificate is placed /etc/docker/certs.d
under, others said to start Docker daemon join --insecure-registry ..
but after all because the version difference is unsuccessful. But then miraculously did not need to be --tlscacert
good.
This place struggled for a long time, focusing on the following several issue:
- Https://github.com/docker/docker-registry/issues/82
- https://github.com/docker/docker/pull/2687
- https://github.com/docker/docker/pull/2339
(7) Final FIX:
# docker login https://registry.domain.com:8000Username: seanPassword: Email: [email protected]Login Succeeded# curl https://sean:[email protected]:8000"docker-registry server (dev) (v0.8.1)"# docker push registry.domain.com:8000/centos6:test_privThe push refers to a repository [registry.domain.com:8000/centos6] (len: 1)Sending image listPushing repository registry.domain.com:8000/centos6 (1 tags)511136ea3c5a: Image successfully pushed 5b12ef8fd570: Image successfully pushed 68edf809afe7: Image successfully pushed 40627956f44c: Image successfully pushed Pushing tag for rev [40627956f44c] on {https://registry.domain.com:8000/v1/repositories/centos6/tags/test_priv}
But there is still a small problem not resolved, although it can be used normally, but each request in the Nginx Error.log is still there [error] 8299#0: *27 no user/password was provided for basic authentication
, should be this version of Docker temporarily unresolved bug.
3.3 Other questions(1) After the Docker background process interrupted unexpectedly, re- docker start <container_id>
error
# docker start b36bd796bd3dError: Cannot start container b36bd796bd3d: Error getting container b36bd796bd3d463c4fedb70d98621e7318ec3d5cd14b2f60b1d182ad3cbcc652 from driver devicemapper: Error mounting ‘/dev/mapper/docker-253:0-787676-b36bd796bd3d463c4fedb70d98621e7318ec3d5cd14b2f60b1d182ad3cbcc652‘ on ‘/var/lib/docker/devicemapper/mnt/b36bd796bd3d463c4fedb70d98621e7318ec3d5cd14b2f60b1d182ad3cbcc652‘: device or resource busy2014/11/08 15:14:57 Error: failed to start one or more containers
The reason for this problem is that an operation was made: at the terminal that the Docker daemon started, the log output of the background process will be temporarily exited, and I will use Yum to install the package under this shell, but because the network causes Yum to get stuck, So I started another terminal kill this yum process, and somehow it affects Docker that has already exited the foreground output. The workaround is to umount the container's mount point: (see here)
# umount /var/lib/docker/devicemapper/mnt/b36bd796bd3d463c4fedb70d98621e7318ec3d5cd14b2f60b1d182ad3cbcc652# service docker start 正常
Another way to think of it is to redirect the output docker -d > /dev/null 2>&1
(/var/log/docker has automatically recorded a log) when the Docker daemon is started.
(2) After configuring Nginx docker-registry.conf, start error
# service nginx start[emerg] 14714#0: unknown directive "upstream" in /etc/nginx/conf.d/docker-registry.conf:4
The reason is that the nginx version is too low, some configuration instructions are incompatible, use the yum install nginx
default installation of 1.0.x, uninstall re-download nginx-1.4.7-1.el6.ngx.x86_64.rpm
installation resolution.
(3) Network setup agent problem
pull, push
The Mirror of the official website needs to set up the agent because of the reason of GFW, but it is not http_proxy
HTTP_PROXY
, for Docker to set these two values at the same time, sometimes because the installation package needs to be set http_proxy
, it will cause a conflict. In Docker-registry, if you forget which one is working, find all the questions and find out why, and the error that Docker returns to us is hard to judge. Remember ~
To-do
How to delete a mirror in docker-registry
********************************************************************************************************
Yum installed a pit of docker-registry
Docker-registry depends on the python-backports-lzma-0.0.2-5.el6.x86_64.rpm package that has the problem, less packages described, need to be executed:
#echo-e ' from pkgutil import extend_path\n__path__ = Extend_path (__path__, __name__) ' >/usr/lib64/python2.6/ site-packages/backports/__init__.py
**************************************************************************************
Attention:
It uses the official Docker hub website as a public centralized repository.
However, local access to the Docker hub is often slow, and many times we need a local private warehouse for use only in the network.
The following is a description of installing Docker registy on CentOS.
To install a dependent library:install python-devel libevent-devel python-pip gcc xz-devel
Install Docker-registry:install docker-registry[bugsnag]
RunGunicorn--access-logfile---debug -k gevent -b 0 .0.0.0 : 7030 -w 1 docker_registry.wsgi:applicationorgunicorn -k Span class= "Hljs-tag" >gevent --max-requests + --graceful-timeout 3600 -t 3600 -b localhost :7070 -w 8 docker_registry.wsgi:application
Client usesGetting a mirror or submitting a mirror to a small file is now very simple, with only the address and port of the 172.29.88.222:7030/CENTOS6 in front of the warehouse.
Deploy the Docker intranet under CentOS