共计 6634 个字符,预计需要花费 17 分钟才能阅读完成。
Docker 官方提供了用于搭建私有 registry 的镜像,并配有详细文档。
官方 Registry 镜像:https://hub.docker.com/_/registry
官方文档:https://docs.docker.com/registry
根据文档快速搭建的私有 registry,只支持 http。但是目前 docker 客户端的 pull、push 等命令,默认使用 https 的方式和 registry 进行交互,这将导致我们搭建的私有 registry 无法正常使用。
本文将从两个方面入手解决此问题:
- 让客户端以 http 方式和私有 registry 交互。
- 让私有 registry 支持 https。
当然,第二种方式是本文的重点。此外,本文还介绍了使用用户名密码的方式,验证客户端身份。
这里假设我们的服务端的 ip 为:192.168.0.1,没有专用域名。大家在配置时,内网 ip 外网 ip 均可。如果有专用域名,处理方式也类似,只是要在生成证书时,注意命令的配置。
客户端使用 Http 的方式和私有 Registry 进行交互
这是常用的一种处理方式,优点是方便快捷,分分钟搞定。只要修改客户端 docker 守护进程的配置文件,将私有 registry 配置为一个 不安全的 registry即可。此后,客户端都将使用 http 的方式和这个 registry 交互。主要步骤如下:
在服务端启动私有 registry:
docker run -d -p 5000:5000 --name docker-registry registry:2
这个命令只是作为演示,真实环境下肯定还会配置 volume。
配置客户端,和私有 registry 交互:
客户端的 daemon.json 配置内容如下:
{"insecure-registries": ["192.168.0.1:5000"]
}
daemon.json 的一般路径为:/etc/docker/daemon.json
配置参考官方文档:https://docs.docker.com/engine/reference/commandline/dockerd
启动(或重启)客户端 docker,使用以下命令制作一个自己的 busybox 镜像,并推送至私有 registry:
# 制作自己的 busybox 镜像
docker tag busybox 192.168.0.1:5000/busybox
# 将镜像推送至私有 registry
docker push 192.168.0.1:5000/busybox
docker 会使用 http 的方式和 registry 进行交互,将镜像推送至私有 registry。
配置私有 Registry,支持 Https
下面介绍下如何配置私有 Registry,使其支持 https 访问。
准备证书
跟常见的 https 站点一样,我们先要弄到一份证书,才能让我们自己的 registry 支持 https。证书都是由 CA(数字证书管理机构)签发的,我们可以向 CA 购买证书。根据 CA 的不同,证书类型的不同,证书的价格相差悬殊,大家可以自己网上搜搜看。如果有兴趣的话,大家还可以通过浏览器的调试工具,看看各大支持 https 网站的证书,分别是哪些 CA 签发的。
各个 CA 都有一份自己的证书(根证书),CA 颁发给我们的证书都是用这份根证书签发出来的,操作系统会内置部分 CA 的根证书(比如受信任的根证书颁发机构下的证书)。这些内置 CA 签发出来的证书都将会被操作系统认为是安全的。比如某个网站使用了这些 CA 颁发的证书,那么你在访问这个网站时,浏览器地址栏就会变成绿色,提示你网站是安全的,否则,浏览器会用明显的红色提醒你正在访问不安全的网站。
举个例子,12306 的网站:https://kyfw.12306.cn/otn/regist/init,你在访问时会提示不安全。通过浏览器调试工具查看其证书,发现是一个叫 SRCA
的 CA 颁发证书给它的。继续百度,得知 SRCA
的全称为:Sinorail Certification Authority(可翻译为中铁数字证书认证中心)。相当于是中铁自己作为 CA,给自己旗下的一个网站签发了一份证书。SRCA
的 CA 资质是肯定不会被国际认可的,道理这里就不多讲了,所以 SRCA
也不会被操作系统收录为受信任的 CA。结果就是你在访问 12306 的网站时,浏览器会提示你正在访问不安全的网站。
这个问题的一种处理方式(也是 12306 网站目前在用的方式),就是把 SRCA
这个 CA 的根证书安装到系统中,操作系统就会认为由这个 CA 签发出的证书都是可信的,这样,访问 12306 的网站就不会再提示证书错误了。12306 网站首页上有安装根证书的操作说明,大家可以自行查看。
向知名 CA 购买证书无疑是最好的选择,这里我们处于学习和个人使用的目的,将采用类似 12306 的方式,自己作为 CA,为自己签发一份证书。
首先,我们自己把自己视为 CA,生成一份根证书
# 生成 CA 私钥
openssl genrsa -out ca.key 2048
# 生成 CA 证书
openssl req -new -x509 -days 365 -key ca.key -out ca.crt -subj "/C=CN/CN=name"
参数说明:
CN=name
指证书的颁发者和使用者均为 name(自己给自己签发根证书,颁发者和使用者当然都是自己,没毛病)。建议更改为你的姓名或公司名称。尝试了下中文,出现了乱码,所以建议使用英文。
第二个命令生成的证书(ca.crt 文件),就是所谓的 CA 根证书,到时候要交给客户端安装,否则客户端默认会认为,由这个 CA 签发出来的证书是不安全的。
再用这份根证书,为我们的 registry 生成一份证书
# 生成私钥文件
openssl genrsa -out server.key 2048
# 生成证书签名请求文件
openssl req -new -key server.key -out server.csr -subj "/C=CN/CN=192.168.0.1"
# 生成证书
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -extfile <(printf "subjectAltName=IP:192.168.0.1") -out server.crt
参数说明:
CN=192.168.0.1
指证书的使用者为 192.168.0.1,可更改为任意字符串。在私有 registry 没有域名的情况下,建议更改为私有 registry 的 ip;有域名的情况下,建议更改为域名。此配置不影响证书的正常使用。subjectAltName=IP:192.168.0.1
指明证书使用者的 ip 必须为 192.168.0.1。如果证书颁发给的是域名而非 ip,则使用subjectAltName=DNS: 你的域名
作为配置。当然也可以两者使用,比如subjectAltName=IP:192.168.0.1,DNS: 你的域名
,这种配置应该是同时限制使用者的 ip 和域名的作用,没有深究。注意,此配置是 X509 Version 3 的新特性,配置后一份证书可供一个或多个 ip(或域名)使用。此配置是必须有,并且是配置正确的,否则 https 请求会报错。
启动私有 registry
命令如下:
docker run -d -p 5000:5000 --name docker-registry \
-v /home/docker-registry:/home/docker-registry \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/home/docker-registry/server.crt \
-e REGISTRY_HTTP_TLS_KEY=/home/docker-registry/server.key \
registry:2
参数说明如下:
REGISTRY_HTTP_TLS_CERTIFICATE
证书文件路径REGISTRY_HTTP_TLS_KEY
私钥路径
参考官方文档中的 http 章节:https://docs.docker.com/registry/configuration/#http
注意,文档中有说明,如果一个配置 A 是可选的,但它又存在必选的子配置 B 和 C,你可以整个 A 及其子配置 B、C 都不配置,否则 B 和 C 都必须配置。原文如下:
In some instances a configuration option is optional but it contains child options marked as required. In these cases, you can omit the parent with all its children. However, if the parent is included, you must also include all the children marked required.
配置客户端,安装 CA 根证书
以下指令用于将证书安装至客户端:
# 备份
cp /etc/pki/tls/certs/ca-bundle.crt{,.backup}
# 导入 CA 根证书
cat ca.crt >> /etc/pki/tls/certs/ca-bundle.crt
如果使用的是 window 系统,直接双击证书,导入至 受信任的根证书颁发机构下的证书 目录下即可。运行 certmgr.msc 命令可打开证书管理器,删除本证书。
客户端和私有 Registry 交互
注意,如果之前在 daemon.json 文件中配置过 insecure-registries,则必须去掉此配置并重启 docker,否则客户端会使用 http 方式和 registry 交互,导致交互失败。
推送镜像至私有 registry:
# 制作自己的 busybox 镜像
docker tag busybox 192.168.0.1:5000/busybox
# 将镜像推送至私有 registry
docker push 192.168.0.1:5000/busybox
docker 会使用 https 的方式和 registry 进行交互,将镜像推送至私有 registry。
配置 Registry,使用用户名密码的方式,验证客户端身份
私有 registry 支持通过使用 htpasswd 工具生成的用户名密码配置文件,来验证客户端身份。
不同 linux 发行版的中的 htpasswd 工具安装方式可能存在不同,这里以 CentOS 为例:
yum install -y httpd-tools
生成用户名密码配置文件
# 创建用户名密码配置文件.passwd,并新增用户 user1,密码手工输入
htpasswd -cB .passwd user1
htpasswd 工具的参考文档:https://httpd.apache.org/docs/2.4/programs/htpasswd.html
注意命令中的 - B 参数,配置后,htpasswd 将以 bcrypt 加密方式加密密码,安全性更高。bcrypt 也是 docker 指定的唯一一种加密方式,其他加密方式均不被支持,详见官方文档中的 htpasswd 章节:https://docs.docker.com/registry/configuration/#htpasswd。
这里再列几个命令用于维护用户:
# 新增用户 user2:
htpasswd -B .passwd user2
# 删除用户 user2:
htpasswd -D .passwd user2
注意:htpasswd 工具并未提供修改密码功能,如需修改密码,可以先删除用户,再新增用户实现。
启动私有 registry:
docker run -d -p 5000:5000 --name docker-registry \
-v /home/docker-registry:/home/docker-registry \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/home/docker-registry/server.crt \
-e REGISTRY_HTTP_TLS_KEY=/home/docker-registry/server.key \
-e REGISTRY_AUTH=htpasswd \
-e REGISTRY_AUTH_HTPASSWD_REALM=basic-realm \
-e REGISTRY_AUTH_HTPASSWD_PATH=/home/docker-registry/.passwd \
registry:2
文档中没有对 REGISTRY_AUTH_HTPASSWD_REALM 这个必选配置有比较详细的说明,自己百度了些资料,大概是用于和 silly、token 这两种身份验证方式配合使用,没做深究。因为我们这里只用到了 htpasswd 这种身份验证方式,所以就用文档里的默认配置了。哪位如果比较了解这部分内容,希望不吝赐教。
此后,我们就可以使用用户名密码登录私有 registry 了,没有登录的客户端将被拒绝访问:
# 登录私有 registry
docker login 192.168.0.1:5000 -u user1 -p 你的密码
# 将镜像推送至私有 registry
docker push 192.168.0.1:5000/busybox
注意:用户名密码的验证方式只建议在 https 的方式下使用,因为用户名密码是通过 http 请求头发送的,如果使用 http 的方式非常不安全,原文如下:
Only use the htpasswd authentication scheme with TLS configured, since basic authentication sends passwords as part of the HTTP header.
户名密码的验证方式还有个缺点,私有 registry 只在启动的时候读取 htpasswd 生成的用户名密码配置文件,所以任何对该配置文件的修改,必须重启 registry 才能生效,原文如下:
The htpasswd file is loaded once, at startup.
其他私有 Registry 搭建方式
网上也有很多资料介绍其他私有 registry 搭建方式,其中一种是在 registry 前端配置 nginx 服务器。这种方式也是很值得推荐的,很多公共的 registry 提供商应该也是扩展这种方式提供服务。
这种方式的其优点有:
- nginx 会处理 https 相关内容。
- 可以使用 nginx 配置负载均衡,搭建 registry 集群,提高 registry 服务的可靠性。
当然缺点也有:
- 配置较繁琐,需要对 nginx 和 registry 有比较深入的了解,特别是在涉及到负载均衡和集群时。
- 如果涉及到负载均衡和集群,registry 的运维工作量也不可小觑。
更多 Docker 相关教程见以下内容:
Docker 安装应用(CentOS 6.5_x64) http://www.linuxidc.com/Linux/2014-07/104595.htm
Ubuntu 16.04 服务器上配置使用 Docker http://www.linuxidc.com/Linux/2017-06/145176.htm
Ubuntu 15.04 下安装 Docker http://www.linuxidc.com/Linux/2015-07/120444.htm
Docker 安装实例 http://www.linuxidc.com/Linux/2017-04/142666.htm
Docker 创建基础镜像 http://www.linuxidc.com/Linux/2017-05/144112.htm
在 Ubuntu 15.04 上如何安装 Docker 及基本用法 http://www.linuxidc.com/Linux/2015-09/122885.htm
Ubuntu 16.04 上 Docker 使用手记 http://www.linuxidc.com/Linux/2016-12/138490.htm
使用 Docker 分分钟启动常用应用 http://www.linuxidc.com/Linux/2017-04/142649.htm
Ubuntu 16.04 下 Docker 修改配置文件不生效解决办法 http://www.linuxidc.com/Linux/2017-05/143862.htm
Docker 的详细介绍:请点这里
Docker 的下载地址:请点这里
本文永久更新链接地址:http://www.linuxidc.com/Linux/2017-07/145907.htm