自定义的镜像可以通过公有仓库进行管理,也可以搭建一个本地的私有仓库进行管理。
1.运行环境
- OS:centos7
- docker-reistry1.0 下载registry.tar
- nginx1.10.2
- docker1.8.2
2.使用docker-registry搭建私有仓库
将registry.tar上传到安装了docker的centos7中,导入nginx镜像。
1 2 3 4
| [root@localhost ~]# docker load < registry.tar [root@registry ~]# docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE docker.io/registry latest 07d93e41c370 13 months ago 422.8 MB
|
修改所有计算节点的的hosts配置文件,并刷新hostname。
1 2 3 4
| [root@localhost ~]# vi /etc/hosts 192.168.147.130 registry 192.168.147.130 registry_private [root@localhost ~]# hostname -F /etc/hostname(刷新hostname)
|
在docker配置文件中添加允许连接镜像仓库:
1 2
| [root@localhost ~]# vi /etc/sysconfig/docker OPTIONS='--insecure-registry registry:5000 --insecure-registry registry_private:5001
|
重启docker:
1
| [root@localhost ~]# service docker restart
|
运行镜像仓库:
1 2 3 4 5
| [root@localhost ~]# docker run -d -p 5000:5000 --name=registry --restart=always --privileged=true --log-driver=none -v /home/data/registrydata:/tmp/registry registry 03859903eb0322eaa7b29a915737bb22b685c466d020da499d491485c1f67307 [root@registry ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 03859903eb03 registry "docker-registry" About an hour ago Up 45 minutes 0.0.0.0:5000->5000/tcp registry
|
上传镜像到仓库:
1 2 3 4 5 6 7 8 9 10
| [root@localhost ~]# docker tag sshd:centos registry:5000/sshd:centos [root@localhost ~]# docker push registry:5000/sshd:centos The push refers to a repository [registry:5000/sshd] (len: 1) Sending image list Pushing repository registry:5000/sshd (1 tags) 9509659cbefb: Image successfully pushed f0efe62f33e4: Image successfully pushed Pushing tag for rev [f0efe62f33e4] on {http://registry:5000/v1/repositories/sshd/tags/centos} [root@localhost ~]# curl registry:5000/v1/search {"num_results": 1, "query": "", "results": [{"description": "", "name": "library/sshd"}]}
|
下载镜像到本地:
1 2 3 4
| [root@registry ~]# docker pull registry:5000/sshd:centos f0efe62f33e4: Download complete 9509659cbefb: Download complete Status: Image is up to date for registry:5000/sshd:centos
|
3.为私有仓库添加用户认证
registry没有安全权限的设置,除非防火墙限制,否则任何人都可以pull、push镜像到registry。更安全的做法是在外层加入登录认证机制。可以使用nginx做反向代理,为私有仓库添加用户认证。
3.1安装及配置nginx
安装nginx
1
| [root@registry ~]# yum install nginx
|
安装htpasswd工具,生成加密后的密码,并将用户名和密码存储在本地指定路径的文件中。
1 2 3 4 5 6 7
| [root@registry ~]# git clone git://github.com/http-auth/htpasswd.git [root@registry ~]# npm install -g htpasswd [root@registry ~]# npm install -g htpasswd [root@registry ~]# htpasswd -c /etc/nginx/docker-registry.htpasswd usr1 New password: Re-type new password: Adding password for user usr1.
|
配置nginx:在/etc/nginx/sites-enabled/目录下添加新的站点配置文件docker-registry:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| [root@registry nginx]# mkdir /etc/nginx/sites-enabled/ [root@registry nginx]# vi /etc/nginx/sites-enabled/docker-registry upstream docker-registry { server localhost:5000; } server { listen 5001; server_name registry_private; 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://github.com/dotcloud/docker/issues/1486) chunked_transfer_encoding on; location / { # let Nginx know about 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; } }
|
建立配置文件软连接,放在/etc/nginx/conf.d/下,让nginx启用它,然后重启nginx服务:
1 2
| [root@registry sites-enabled]# sudo ln -s /etc/nginx/sites-enabled/docker-registry /etc/nginx/conf.d/docker-registry.conf [root@registry sites-enabled]# service nginx restart
|
如果这一步遇到这个问题:
1 2 3 4 5 6 7 8 9 10 11 12 13
| [root@registry sites-enabled]# systemctl status nginx.service nginx.service - The nginx HTTP and reverse proxy server Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled) Active: failed (Result: exit-code) since Thu 2017-03-02 11:08:27 CST; 14s ago Process: 39831 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=1/FAILURE) Process: 39830 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS) Mar 02 11:08:27 registry systemd[1]: Starting The nginx HTTP and reverse proxy server... Mar 02 11:08:27 registry nginx[39831]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok **Mar 02 11:08:27 registry nginx[39831]: nginx: [emerg] bind() to 0.0.0.0:5001 failed (13: Permission denied)** Mar 02 11:08:27 registry nginx[39831]: nginx: configuration file /etc/nginx/nginx.conf test failed Mar 02 11:08:27 registry systemd[1]: nginx.service: control process exited, code=exited status=1 Mar 02 11:08:27 registry systemd[1]: Failed to start The nginx HTTP and reverse proxy server. Mar 02 11:08:27 registry systemd[1]: Unit nginx.service entered failed state.
|
可能是是开启了selinux导致的,查看是否开启了selinux,”Enforecing”代表开启了selinux,”disabled”或者”permissive”则是关闭了。
1 2 3 4 5
| [root@registry sites-enabled]# getenforce Enforcing [root@registry sites-enabled]# setenforce 0 (临时关闭selinux) [root@registry sites-enabled]# getenforce Permissive
|
这时访问registry_private:5001,则被禁止:
1 2
| [root@registry sites-enabled]# getenforce Permissive
|
临时修改重启电脑后再重启nginx,每次均需要修改,可以永久关闭,修改/etc/selinux/config 文件,将SELINUX=enforcing改为SELINUX=disabled,重启电脑生效。
通过用户名和密码登录:
1 2
| [root@registry sites-enabled]# curl usr1:123456@registry_private:5001/v1/search {"num_results": 1, "query": "", "results": [{"description": "", "name": "library/sshd"}]}
|
如果用浏览器登录,则会出现要求填写用户名和密码的对话框。
3.2为nginx安装ssl证书
此时登录registry_private下载镜像,会无法下载:
1 2 3 4 5 6 7 8 9
| [root@registry sites-enabled]# docker login registry_private:5001 Username: usr1 Password: Email: WARNING: login credentials saved in /root/.docker/config.json Login Succeeded [root@registry sites-enabled]# docker pull registry_private:5001/sshd:centos Trying to pull repository registry_private:5001/sshd ... failed Could not reach any registry endpoint
|
这是因为docker-registry不允许http明文传输,此时可以安装SSL证书,使用HTTPS传输。
首先在nginx配置文件中添加:
1 2 3 4 5 6 7 8 9
| [root@registry sites-enabled]# vi /etc/nginx/conf.d/docker-registry.conf ...... server { listen 5001; server_name registry_private; ssl on; ssl_certificate /etc/nginx/ssl/nginx.crt; ssl_certificate_key /etc/nginx/ssl/nginx.key; ......
|
创建相关证书:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| [root@registry sites-enabled]# mkdir /etc/nginx/ssl (创建配置目录) [root@registry sites-enabled]# cd /etc/pki/CA [root@registry CA]# openssl genrsa -out private/cakey.pem 2048 (生成秘钥) [root@registry CA]# cd /etc/pki/CA/private/ y.pem [root@registry private]# chmod 400 cakey.pem (修改私钥文件权限)[root@registry private]# cd /etc/pki/CA/ [root@registry CA]# openssl req -new -x509 -key private/cakey.pem -out cacert.pem (生成根证书) 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]:CN State or Province Name (full name) []:BJ Locality Name (eg, city) [Default City]:BJ Organization Name (eg, company) [Default Company Ltd]: Organizational Unit Name (eg, section) []: Common Name (eg, your name or your server's hostname) []: Email Address []:
|
生成根证书的时候会提示输入一些内容,可以随便输入,也可直接回车。如果有入,最好与后续为nginx生成证书签署请求的填写内容保持一致。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| [root@registry private]# cd /etc/pki/CA/ [root@registry CA]# openssl req -new -x509 -key private/cakey.pem -out cacert.pem (生成根证书) [root@registry CA]# cd /etc/nginx/ssl [root@registry ssl]# openssl genrsa -out nginx.key 2048 (为nginx web服务器生成ssl密钥) [root@registry ssl]# openssl req -new -key nginx.key -out nginx.csr (为nginx生成证书请求) 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]:CN State or Province Name (full name) []:BJ Locality Name (eg, city) [Default City]:BJ Organization Name (eg, company) [Default Company Ltd]: Organizational Unit Name (eg, section) []: Common Name (eg, your name or your server's hostname) []:regstry_private(**此处一定要填写需要授予证书的服务器域名或主机名**) Email Address []: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: [root@registry ssl]# touch /etc/pki/CA/index.txt [root@registry ssl]# touch /etc/pki/CA/serial [root@registry ssl]# echo "00" > /etc/pki/CA/serial [root@registry ssl]# openssl ca -in nginx.csr -out nginx.crt (私有CA根据请求来签发证书) Using configuration from /etc/pki/tls/openssl.cnf Check that the request matches the signature Signature ok The commonName field needed to be supplied and was missing (生成证书请求是没有填写任何信息,所以有这一句话的提示。)
|
让根证书起作用:
1 2
| [root@registry ssl]# cp /etc/pki/tls/certs/ca-bundle.crt{,.bak} (备份,以防出错) [root@registry ssl]# cat /etc/pki/CA/cacert.pem >> /etc/pki/tls/certs/ca-bundle.crt
|
此时再下载私有仓库的镜像:
1 2 3 4
| [root@registry certs]# docker pull registry_private:5001/sshd:centos f0efe62f33e4: Download complete 9509659cbefb: Download complete Status: Image is up to date for registry_private:5001/sshd:centos
|
用网页登录时,需要注意是https协议。

注意:下载不在同一主机上的私有仓库时,需要在docker的配置文件中添加 –insecurity-registry 参数。
参考博客:
https://segmentfault.com/a/1190000000801162
http://cloud.51cto.com/art/201412/458680_all.htm