搭建 docker 私仓, 可以使用 docker 官方提供的 https://hub.docker.com/r/_/registry/ 镜像. 该镜像目前有 2.0,2.3 和 2.3.1 版本. 它只与 1.6.0 以上版本的 docker 兼容. 搭建私仓的步骤如下:
一: 无代理, 无认证的 registry
1: 下载 registry 镜像:
docker pull registry:2
这里必须加上标签 ":2", 否则的话, 不加标签的 registry, 实际上下载的是标签为 "latest" 的 registry 镜像, 则不能使用下面的 nginx 代理镜像: containersol/docker-registry-proxy
2: 创建 registry 容器:
在 registry:2 创建的私有仓库中, 上传的镜像保存在容器的 / var/lib/registry 目录下. 创建 registry:2 的容器时, 会自动创建一个数据卷(Data Volumes), 数据卷对应的宿主机下的目录一般为:/var/lib/docker/volumes/XXX/_data.
可以在创建 registry:2 的容器时, 通过 - v 参数, 修改这种对应关系:
docker run -d -p 5000:5000 --restart=always -v \ /opt/docker/registry/data:/var/lib/registry --name docker-registry registry:2
除了可以将数据保存在当前主机的文件系统上, registry 也支持其他基于云的存储系统, 比如 S3,Microsoft Azure, Ceph Rados, OpenStack Swift and Aliyun OSS 等. 可以在配置文件中进行配置: https://github.com/docker/distribution/blob/master/docs/configuration.md#storage
以上其实已经创建好了一个 docker 私有仓库, 但是这时候向其 push 或者 pull 时还是有问题的:
- [@hh_93_197 /]# docker tag hello-world 192.168.1.104:5000/hello-world
- [@hh_93_197 /]# docker push 192.168.1.104:5000/hello-world
- The push refers to a repository [192.168.1.104:5000/hello-world]
- unable to ping registry endpoint https://192.168.1.104:5000/v0/
- v2 ping attempt failed with error: Get https://192.168.1.104:5000/v2/: tls: oversized record received with length 20527
- v1 ping attempt failed with error: Get https://192.168.1.104:5000/v1/_ping: tls: oversized record received with length 20527
这是因为从 docker1.3.2 版本开始, 使用 registry 时, 必须使用 TLS 保证其安全.
最简单的解决办法是, 在需要连接该私有仓库的所有客户端 docker 宿主机上, 修改 dockerdaemon http://www.baidu.com/link?url=gScz1rMO4qA2ttFptWJ98MtBd-aKyijatbLKyY1QngF2Z_K22A-XdFLagohuekZnnv_4aA8xcOoCyL43bF5lQq 的配置文件, 增加 insecure-registry 参数.
比如, 对于 Redhat7 的宿主机来说, 新增文件 / etc/systemd/system/docker.service.d/docker.conf, 其内容配置如下:
- [Service]
- ExecStart=
- ExecStart=/usr/bin/docker daemon -H fd:// --insecure-registry=192.168.1.104:5000
然后, 重启 docker:
- [root@localhost /]# systemctl daemon-reload
- [root@localhost /]# service docker restart
此时就可以使用该私有仓库了.
但是, 上面这种配置方式既不安全(所有人都可以 push 或 pull), 也很不方便(使用该私有仓库的所有宿主机上都这样进行配置).
下面是带有认证的 registry 私仓构建过程:
二: 无代理, 有认证的 registry
使用 TLS 认证 registry 容器时, 必须有证书. 一般情况下, 是要去认证机构购买签名证书. 这里使用 openssl 生成自签名的证书.
1: 生成自签名证书
一般情况下, 证书只支持域名访问, 要使其支持 IP 地址访问, 需要修改配置文件 openssl.cnf.
在 Redhat7 系统中, 文件所在位置是 / etc/pki/tls/openssl.cnf. 在其中的 [ v3_ca] 部分, 添加 subjectAltName 选项:
- [ v3_ca ]
- subjectAltName = IP:192.168.1.104
接下来就是生成自签名的证书:
- 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) []:192.168.1.104:5000
- Email Address []:
这里的服务器域名写成 "192.168.1.104:5000", 后续就使用该地址访问私仓. 其余项直接回车即可.
2: 创建带有 TLS 认证的 registry 容器
docker run -d --name docker-registry-no-proxy --restart=always -v /opt/docker/registry/data:/var/lib/registry -u root -p 192.168.1.104: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
3: 配置客户端宿主机
目前, 已经搭建好了一个 registry 私有仓库了. 但是, 访问该私仓还是会报错:
- # docker pull 192.168.1.104:5000/redis
- Using default tag: latest
- Error response from daemon: unable to ping registry endpoint https://192.168.1.104:5000/v0/
- v2 ping attempt failed with error: Get https://192.168.1.104:5000/v2/: x509: certificate signed by unknown authority
- v1 ping attempt failed with error: Get https://192.168.1.104:5000/v1/_ping: x509: certificate signed by unknown authority
这是因为客户端宿主机上没有相应的证书. 需要把 registry 所在主机上, 刚生成的证书:
/opt/docker/registry/certs/domain.crt
复制到客户端宿主机上的:
/etc/docker/certs.d/192.168.1.104:5000/ca.crt
之后, 就可以使用该私仓了:
- # docker pull 192.168.1.104:5000/redis
- Using default tag: latest
- latest: Pulling from redis
- 80ab95908a2b: Pull complete
- a3ed95caeb02: Pull complete
- 47a0d79f89b9: Pull complete
- 7190081b1686: Pull complete
- fe09c22d81ac: Pull complete
- a5eae2bcc645: Pull complete
- 662723161f77: Pull complete
- b568670a8ccd: Pull complete
- a1a961e320bc: Pull complete
- Digest: sha256:769ac80a4711258ec4d6d325f3ad31fbce3bbfa006d5f8aae94c94917dfb0384
- Status: Downloaded newer image for 192.168.1.104:5000/redis:latest
更好的方式是使用 nginx 代理, 由 nginx 提供 https 的 ssl 的认证和 basicauthentication. 方法如下:
三: nginx 代理, 域名访问的 registry
1: 生成自签名证书:
- mkdir -p /opt/docker/registry/conf
- openssl req -x509 -days 3650 -nodes -newkey rsa:2048 -keyout /opt/docker/registry/conf/docker-registry.key -out /opt/docker/registry/conf/docker-registry.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) []:hh.registry.com
- Email Address []:
这里的服务器域名写成 "hh.registry.com", 其余项直接回车即可.
2: 创建能够访问仓库的用户名和密码
htpasswd -b -c -d /opt/docker/registry/conf/docker-registry.htpasswd admin admin
这里的用户名和密码都是 admin
3: 运行 nginx
这里使用容器 containersol/docker-registry-proxy 运行 nginx:
docker run -d -p 443:443 --name docker-registry-proxy -e REGISTRY_HOST="docker-registry" -e REGISTRY_PORT="5000" -e SERVER_NAME="hh.registry.com" --link docker-registry:docker-registry -v /opt/docker/registry/conf/docker-registry.htpasswd:/etc/nginx/.htpasswd:ro -v /opt/docker/registry/conf:/etc/nginx/ssl:ro containersol/docker-registry-proxy
注意, 这里的环境变量 SERVER_NAME 也要设置成 "hh.registry.com".
目前, 就已经搭建好了一个 registry 私有仓库了. 但是, 还需要在使用它的客户端宿主机执行以下的操作. 比如在私有仓库所在的主机上使用它, 也要执行以下步骤:
4: 修改 / etc/hosts 文件, 增加以下内容, 以使客户端宿主机可以解析域名 "hh.registry.com"
192.168.1.104 hh.registry.com
5: 复制证书
- mkdir -p /etc/docker/certs.d/hh.registry.com
- cp /opt/docker/registry/conf/docker-registry.crt /etc/docker/certs.d/hh.registry.com/ca.crt
这里是在 registry 所在主机上进行的操作. 如果是其他 docker 宿主机, 需要远程复制该 crt 文件.
客户端宿主机配置好以后, 通过下面的方式验证私有仓库的可用性:
6: 列出私有仓库上的所有镜像
- #curl -X GET https://admin:admin@hh.registry.com/v2/_catalog -k
- {"repositories":["hello-world","ubuntu"]}
7: 登陆
- #docker login -u admin -p admin hh.registry.com
- WARNING: login credentials saved in /root/.docker/config.json
- Login Succeeded
8:pull 镜像
- #docker pull hh.registry.com/ubuntu
- Using default tag: latest
- latest: Pulling from ubuntu
- 5a132a7e7af1: Pull complete
- fd2731e4c50c: Pull complete
- 28a2f68d1120: Pull complete
- a3ed95caeb02: Pull complete
- Digest: sha256:9409f5e54fdc68ef3f0aae3c5ffac22bfe2aabd0b363a4bdbe5292c93b75a661
- Status: Downloaded newer image for hh.registry.com/ubuntu:latest
9:push 镜像
- # docker tag registry.aliyuncs.com/ddbmh/redis hh.registry.com/redis
- # docker push hh.registry.com/redis
- The push refers to a repository [hh.registry.com/redis]
- 5f70bf18a086: Mounted from ubuntu
- 7986f971c50f: Pushed
- 590d3336f33c: Pushed
- 4458b6e6f424: Pushed
- 39d2b75cc73d: Pushed
- cbc6c973b349: Pushed
- d53a2702e023: Pushed
- 5bca8d976dd8: Pushed
- 603fd967d41c: Pushed
- latest: digest: sha256:769ac80a4711258ec4d6d325f3ad31fbce3bbfa006d5f8aae94c94917dfb0384 size: 3823
10: 再次列出私有仓库中的所有镜像
- # curl -X GET https://admin:admin@hh.registry.com/v2/_catalog -k
- {"repositories":["hello-world","redis","ubuntu"]}
四: nginx 代理, IP 访问的 registry
以上的步骤中, 访问私仓只能使用域名 "hh.registry.com", 如果使用 IP 访问, 则会报错:
- #docker login -u admin -p admin -e a 192.168.1.104
- Error response from daemon: invalid registry endpoint https://192.168.1.104/v0/: unable to ping registry endpoint https://192.168.1.104/v0/
- v2 ping attempt failed with error: Get https://192.168.1.104/v2/: x509: cannot validate certificate for 192.168.1.104 because it doesn't contain any IP SANs
- ...
如果想用 IP 地址访问, 则执行以下的步骤:
1: 在文件 / etc/pki/tls/openssl.cnf 的 [ v3_ca ] 部分, 添加 subjectAltName 选项
- [ v3_ca ]
- subjectAltName = IP:192.168.1.104
2: 重新生成证书
- openssl req -x509 -days 3650 -nodes -newkey rsa:2048 -keyout /opt/docker/registry/conf_ip/docker-registry.key -out /opt/docker/registry/conf_ip/docker-registry.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) []:hh.registry.com
- Email Address []:
这里的服务器域名还是写成 "hh.registry.com" 即可. 其余项直接回车即可.
3: 创建能够访问仓库的用户名和密码
htpasswd -b -c -d /opt/docker/registry/conf_ip/docker-registry.htpasswd admin admin
这里的用户名和密码都是 admin
4: 运行 nginx 容器
- # docker stop docker-registry-proxy
- docker-registry-proxy
- # docker run -d -p 443:443 --name docker-registry-proxy-ip -e REGISTRY_HOST="docker-registry" -e REGISTRY_PORT="5000" -e SERVER_NAME="hh.registry.com" --link docker-registry:docker-registry -v /opt/docker/registry/conf_ip/docker-registry.htpasswd:/etc/nginx/.htpasswd:ro -v /opt/docker/registry/conf_ip:/etc/nginx/ssl:ro containersol/docker-registry-proxy
搭建好 registry 私有仓库后, 在需要访问该私仓的客户端 docker 宿主机上, 无需修改 / etc/hosts 文件, 直接将 registry 主机上的证书, 复制成客户端 docker 宿主机上的 / etc/docker/certs.d/192.168.1.104/ca.crt 文件.
客户端 docker 宿主机配置好以后, 验证步骤如下:
- # curl -X GET https://admin:admin@192.168.1.104/v2/_catalog -k
- {"repositories":["hello-world","redis","ubuntu"]}
- # docker login -u admin -p admin -e a 192.168.1.104
- WARNING: login credentials saved in /root/.docker/config.json
- Login Succeeded
- # docker pull 192.168.1.104/redis
- Using default tag: latest
- latest: Pulling from redis
- 80ab95908a2b: Pull complete
- a3ed95caeb02: Pull complete
- 47a0d79f89b9: Pull complete
- 7190081b1686: Pull complete
- fe09c22d81ac: Pull complete
- a5eae2bcc645: Pull complete
- 662723161f77: Pull complete
- b568670a8ccd: Pull complete
- a1a961e320bc: Pull complete
- Digest: sha256:769ac80a4711258ec4d6d325f3ad31fbce3bbfa006d5f8aae94c94917dfb0384
- Status: Downloaded newer image for 192.168.1.104/redis:latest
参考:
- https://docs.docker.com/registry/
- https://hub.docker.com/r/chalimartines/cdh5-pseudo-distributed/
- http://www.pangxie.space/docker/353
- https://docs.docker.com/registry/insecure/
- http://www.tianmaying.com/tutorial/docker-registry
来源: http://www.bubuko.com/infodetail-2733408.html