Docker官方提供了用于搭建私有registry的镜像,并配有详细文档。
官方Registry镜像:https://hub.docker.com/_/registry
官方文档:https://docs.docker.com/registryhtml
根据文档快速搭建的私有registry,只支持http。可是目前docker客户端的pull、push等命令,默认使用https的方式和registry进行交互,这将致使咱们搭建的私有registry没法正常使用。前端
本文将从两个方面入手解决此问题:linux
固然,第二种方式是本文的重点。此外,本文还介绍了如何使用用户名密码的方式,验证客户端身份。nginx
这里假设咱们的服务端的ip为:192.168.0.1,没有专用域名。你们在配置时,内网ip外网ip都可。若是有专用域名,处理方式也相似,只是要在生成证书时,注意命令的配置。docker
这是经常使用的一种处理方式,优势是方便快捷,分分钟搞定。只要修改客户端docker守护进程的配置文件,将私有registry配置为一个不安全的registry便可 。此后,客户端都将使用http的方式和这个registry交互。主要步骤以下:apache
docker run -d -p 5000:5000 --name docker-registry registry:2
这个命令只是做为演示,真实环境下确定还会配置volume。json
客户端的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:bash
# 制做本身的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访问。
跟常见的https站点同样,咱们先要弄到一份证书,才能让咱们本身的registry支持https。证书都是由CA(数字证书管理机构)签发的,咱们能够向CA购买证书。根据CA的不一样,证书类型的不一样,证书的价格相差悬殊,你们能够本身网上搜搜看。若是有兴趣的话,你们还能够经过浏览器的调试工具,看看各大支持https网站的证书,分别是哪些CA签发的。
各个CA都有一份本身的证书(根证书),CA颁发给咱们的证书都是用这份根证书签发出来的,操做系统会内置部分CA的根证书(好比受信任的根证书颁发机构下的证书)。这些内置CA签发出来的证书都将会被操做系统认为是安全的。好比某个网站使用了这些CA颁发的证书,那么你在访问这个网站时,浏览器地址栏就会变成绿色,提示你网站是安全的,不然,浏览器会用明显的红色提醒你正在访问不安全的网站。
举个例子,12306的网站:https://kyfw.12306.cn/otn,你在访问时会提示不安全。经过浏览器调试工具查看其证书,发现是一个叫 SRCA
的CA颁发证书给它的。继续百度,得知 SRCA
的全称为:Sinorail Certification Authority(可翻译为中铁数字证书认证中心)。至关因而中铁本身做为CA,给本身旗下的一个网站签发了一份证书。SRCA
的CA资质是确定不会被国际承认的,道理你懂的,因此 SRCA
也不会被操做系统收录为受信任的CA。结果就是你在访问12306的网站时,浏览器会提示你正在访问不安全的网站。
这个问题的一种处理方式(也是12306网站目前在用的方式),就是把 SRCA
这个CA的根证书安装到系统中,操做系统就会认为由这个CA签发出的证书都是可信的,这样,访问12306的网站就不会再提示证书错误了。12306网站首页上有安装根证书的操做说明,你们能够自行查看。
向知名CA购买证书无疑是最好的选择,这里咱们处于学习和我的使用的目的,将采用相似12306的方式,本身做为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签发出来的证书是不安全的。
# 生成私钥文件 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请求会报错。命令以下:
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.
如下指令用于将证书安装至客户端:
# 备份 cp /etc/pki/tls/certs/ca-bundle.crt{,.backup} # 导入CA根证书 cat ca.crt >> /etc/pki/tls/certs/ca-bundle.crt
若是使用的是window系统,直接双击证书,导入至受信任的根证书颁发机构下的证书目录下便可。运行certmgr.msc命令可打开证书管理器,删除本证书。
注意,若是以前在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支持经过使用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前端架设nginx服务器。这种方式也是很值得推荐的,不少公共的registry提供商应该也是扩展这种方式提供服务。
这种方式的其优势有:
固然缺点也有: