docker官方提供了Registry镜像,可以用来搭建本地私有镜像仓库。本文示例私有镜像仓库的搭建,以及实现登录验证功能。
目录
一、启动 Docker Registry
docker run -d -p 5000:5000 --restart=always --name registry -v /mnt/registry:/var/lib/registry registry:2
指令参数说明:
-d:表示在后台运行该容器
-p 5000:5000:表示将私有镜像仓库容器内部默认暴露的5000端口,映射到宿主机的5000端口
--restart=always:表示docker启动后自动启动本地私有镜像仓库
--name registry:表示为生成的容器命名为registry
-v /mnt/registry:/var/lib/registry:将容器内私有镜像仓库默认存储位置/var/lib/registry中的数据挂载到宿主机的/mnt/registry目录下。这样的好处是,即使容器销毁了,宿主机的目录也还有备份数据。
Docker Registry目前有v1和v2两个版本,v2版本的本地镜像仓库容器中数据默认挂载点是/var/lib/registry目录
二、上传镜像到本地私有仓库
第一步:重命名镜像。镜像名格式为“仓库IP:端口号/repository名称”
docker tag hello-world:latest localhost:5000/jack-hello-world
第二步:推送镜像。
[root@localhost ~]# docker push localhost:5000/jack-hello-world
The push refers to repository [localhost:5000/jack-hello-world]
9c27e219663c: Pushed
latest: digest: sha256:90659bf80b44ce6be8234e6ff90a1ac34acbeb826903b02cfa0da11c82cbc042 size: 525
[root@localhost ~]#
第三步:查看本地仓库镜像,确认推送成功。
也可以查看宿主机的/mnt/registry目录进行确认,因为前面进行了目录挂载。
三、配置私有仓库认证
前面已经实现了将镜像推送到私有仓库,但有个问题,并不需要登录验证。这肯定是不安全的。接下来进行登录认证配置。
3.1 确定宿主机IP地址
查看Docker Registry私有仓库搭建所在的服务器地址,使用ifconfig命令查看。
例如:我的宿主机IP地址为192.168.42.169
3.2 生成自签名证书
在生成自签名证书之前,先配置openssl。对于Centos,编辑/etc/pki/tls/openssl.cnf文件。在[v3_ca]下面添加:subjectAltName = IP:域名|IP地址
[ v3_ca ] subjectAltName = IP:192.168.42.169
否则,后续docker 链接仓库时会报异常:
Get https://192.168.42.169:5000/v2/: x509: cannot validate certificate for 192.168.42.169 because it doesn't contain any IP SANs
要确保Docker Registry本地镜像仓库的安全性,还需要一个安全认证证书,来保证其他Docker机器不能随意访问该机器上的Docker Registry本地镜像仓库。所以搭建本地镜像仓库之前,需要先准备自签名证书(如果已购买就无需生成),指令如下:
[root@localhost ~]# mkdir -p /registry/certs && cd /registry/certs
[root@localhost certs]# openssl req -x509 -days 3650 -subj '/CN=192.168.42.169:5000/' -nodes -newkey rsa:2048 -keyout domain.key -out domain.crt
指令参数说明:
-x509:是一个自签发证书的格式
-days 3650:标识证书有效期
192.168.42.169:5000:标识具体部署Docker Registry本地镜像仓库的宿主机IP地址和端口号
rsa:2048:RSA私钥长度为2048bit
domain.key和domain.crt:就是生成的证书文件名
3.3 生成用户名和密码
有了证书,还需要生成链接本地镜像仓库认证用的用户名和密码。
[root@localhost certs]# cd /registry/ && mkdir auth
[root@localhost registry]# docker run --entrypoint htpasswd registry:2 -Bbn jack 123456 > /registry/auth/htpasswd
docker: Error response from daemon: OCI runtime create failed: container_linux.go:370: starting container process caused: exec: "htpasswd": executable file not found in $PATH: unknown.
报错了,该错误与Docker Registry版本有关,暂时不使用最新版,明确版本为2.7.0
[root@localhost registry]# docker run --entrypoint htpasswd registry:2.7.0 -Bbn jack 123456 > /registry/auth/htpasswd
3.4 启动Docker Registry本地镜像仓库服务
先将之前创建的registry容器删除,避免重名创建失败。
docker run -d -p 5000:5000 --restart=always --name registry -v /mnt/registry:/var/lib/registry -v /registry/auth:/auth -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd -v /registry/certs:/certs -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key registry:2.7.0
3.5 配置Docker Registry访问接口
Docker Registry本地镜像仓库服务启动后,还需要在搭建了Docker Registry本地镜像仓库所在的宿主机上配置供其他Docker机器访问的接口,指令如下:
[root@localhost auth]# mkdir -p /etc/docker/certs.d/192.168.42.169:5000
[root@localhost auth]# cp /registry/certs/domain.crt /etc/docker/certs.d/192.168.42.169\:5000/
3.6 通知docker使用私有仓库
编辑docker终端机器的/etc/docker/daemon.json文件,添加如下内容:
{
"registry-mirrors": ["https://na85zyh5.mirror.aliyuncs.com"] # aliyun镜像加速,不用可不配。注意去掉此注释
"insecure-registries": ["192.168.42.141:5000"]
}
配置完成后,重启docker服务并加载配置。
[root@localhost docker]# systemctl reload docker
[root@localhost docker]# systemctl restart docker
Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xe" for details.
此时,发现启动docker失败。daemon.json文件重命名为daemon.conf文件,重新启动即可。(网上的说法,可能是配置了阿里云镜像加速。但是之前是没问题的,加上insecure-registries就不行了。算是个小坑吧)
3.7 测试推送镜像
3.7.1 镜像打tag
docker tag hello-world:latest 192.168.42.169:5000/hello3
3.7.2 推送镜像
[root@localhost certs]# docker push 192.168.42.169:5000/hello2
The push refers to repository [192.168.42.169:5000/hello2]
9c27e219663c: Preparing
no basic auth credentials
推送出错,提示no basic auth credentials(没有基本的认证凭证),即要求登录验证。
3.7.3 登录私有仓库
[root@localhost certs]# docker login 192.168.42.169:5000
Username: jack
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
3.7.4 再次推送
[root@localhost certs]# docker push 192.168.42.169:5000/hello2
3.7.5 结果验证
之前做了目录挂载,可以直接查看宿主机的该目录: