Docker镜像构建以后,如果想存起来或者分享,一般都存放到dockerhub,或者临时存放到ttl.sh。但dockerhub是有容量限制的,因而自己搭建docker registry也是个不错的选择,而且使用起来也很简单(这归功于docker简单的tag机制,在tag中包含registry前缀即可方便push到不同的地方)。
Docker官方提供了registry的镜像,部署起来比较方便–只有ssl证书方面比较麻烦。
为了部署私有registry,大致上有这么几个要点:
- 准备好ssl签名(自签名)。
- 在宿主机选好配置文件、registry存储目录。部署稳定的registry:2镜像。
- 在客户端信任ssl根证书。
准备自签名SSL证书
生成根证书
先产生私钥文件:
1 | mkdir root_ca |
还可以选更加简单的 prime256v1 加密算法替换 secp384r1。
创建CSR:
1 | openssl req -new -sha256 -key root_ca/ROOT_CA_PRIVATEKEY.key -out root_ca/ROOT_CA_CSR.csr -subj "/C=CN/ST=GD/L=GZ/OU=ALL/O=test/CN=test" |
其中信息缩写:
- CN - CommonName
- L - LocalityName
- ST - StateOrProvinceName
- O - OrganizationName
- OU - OrganizationalUnitName
- C - CountryName
创建配置文件ROOT_CA.cnf
1 | cat > root_ca/ROOT_CA.cnf |
创建根证书:
1 | openssl x509 -req -sha256 -days 36500 -extfile root_ca/ROOT_CA.cnf -in root_ca/ROOT_CA_CSR.csr -signkey root_ca/ROOT_CA_PRIVATEKEY.key -out root_ca/ROOT_CA_CERT.crt |
到此,所有文件为:
1 | % ls root_ca |
用根证书颁发域名证书(假设域名为mysvr)
创建key和CSR
1 | mkdir mysvr_certs |
创建ssl.cnf配置文件,用于颁发证书
1 | cat > mysvr_certs/ssl.cnf |
通过CA为mysvr的CSR颁发证书mysvr.crt。
首次生成crt:
1 | openssl x509 -req -CA root_ca/ROOT_CA_CERT.crt -CAkey root_ca/ROOT_CA_PRIVATEKEY.key -CAcreateserial -days 398 -sha256 -extfile mysvr_certs/ssl.cnf -in mysvr_certs/mysvr.csr -out mysvr_certs/mysvr.crt |
首次生成crt会通过-CAcreateserial参数产生srl文件在root_ca/ROOT_CA_CERT.srl,以后再度颁发证书则用首次的srl即可:
1 | cp root_ca/ROOT_CA_CERT.srl mysvr_certs/mysvr.srl |
验证证书是否可信:
1 | openssl verify -CAfile root_ca/ROOT_CA_CERT.crt mysvr_certs/mysvr.crt |
mysvr_certs/mysvr.crt: OK
如果以后要更新IP,则需要修改cnf,再重新颁发即可。
部署docker registry
我这里部署到群晖的nas上,其docker服务界面支持设置环境变量(命令行 -e)、端口(-p)、文件路径(-v),整体设置如下:
运行registry:2镜像,设置环境变量:
1 | REGISTRY_HTTP_TLS_CERTIFICATE=/certs/mysrv.crt |
上述路径为映射的路径。
设置路径映射:
1 | docker/docker-registry/registry:/var/lib/registry |
上传证书文件到宿主机的docker/mysrv/certs
目录下。
设置端口:
1 | 4000:4000 |
在客户端信任证书(安装根证书)
macos下让浏览器信任证书
安装根证书,双击,添加到login items,然后到Keychain Access里面找到test证书,确认信息,然后选择always trust。
此时浏览器已经能信任该证书。对于docker,只要重启engine即可。
Linux下让docker信任证书
本质上是复制根证书到docker客户端的registry配置目录内,然后重启即可。
docker registry证书在 /etc/docker/certs.d/${domain}:${port}/ca.crt 目录。例如我们这里为:
1 | cp root_ca/ROOT_CA_CERT.crt /etc/docker/certs.d/mysrv.local\:4000/ca.crt |
在群晖的docker服务中添加我们自己的docker registry
主要两步:
1. 添加根证书到群晖系统
群晖的 /etc/ssl/certs/ca-certificates.crt
文件内存放了所有证书,这个文件是由 /usr/syno/bin/update-ca-certificates.sh
脚本根据 /var/db/ca-certificates
目录来维护的。
因而,要添加证书,则可以这样做:
1 | sudo cp my_path_to_mysrv_root.crt /var/db/ca-certificates/mysrv_root.crt |
这个证书还会被自动链接到这个位置:
1 | $ ls -lh /etc/ssl/certs/`sudo openssl x509 -hash -noout -in /var/db/ca-certificates/mysrv_root.crt`* |
2. 添加根证书到群晖docker服务的配置目录
1 | sudo mkdir -p /var/packages/Docker/etc/certs.d/mysrv.local:4000/ |
然后重启docker服务:
1 | sudo systemctl restart pkgctl-Docker # 这个命令会比较久。 |
注意:使用.local域名的话,要注意主机上是否能解析(可以用ip)。
使用
支持,可以对镜像打tag并且push:
1 | docker tag my/image mysrv.local:4000/my/image |
可通过url查询镜像:
1 | https://mysrv.local:4000/v2/_catalog |