1 简介
Container Registry(容器注册表 / 镜像仓库) :专门用来存储、分发 Docker 镜像的服务,开源、无状态、可扩展
实际选型
- 公有托管仓库(Docker Hub、GitHub Container Registry)
不用自己搭建服务器,开箱即用,公有云托管。 - 开源自建增强私有仓库(Harbor)
基于原生 registry 二次开发,开源免费,自己部署,增加 RBAC、LDAP、漏洞扫描、镜像复制。 - 商业企业级仓库(Docker Trusted Registry、Quay Enterprise)
商业闭源 / 付费产品,全套企业镜像管理能力。
2 registry 私有仓库
2.1 搭建私有仓库
配置镜像加速器
bash
[root@docker1 ~]# cd /etc/docker/
[root@docker1 docker]# vim daemon.json

bash
[root@docker1 docker]# systemctl restart docker
[root@docker1 docker]# docker info

配置完成,当执行docker pull时,docker 优先走这个代理去拉取 Docker Hub 镜像,解决国内访问 Docker Hub 超时问题
registry 是 Docker 官方原生镜像仓库(docker‑distribution)的镜像,从 Docker Hub 拉取,把它 run 起来,就是一个私有仓库服务
bash
[root@docker1 docker]# docker pull registry

启动私有镜像仓库
bash
[root@docker1 ~]# docker run -d --name registry -p 5000:5000 -v /registry:/var/lib/registry registry
-d:--detach,后台守护进程运行容器--name registry:给容器命名为registry-p 5000:5000:端口映射- 宿主机端口
5000: 容器内部端口5000 - registry 服务默认监听容器内 5000 端口,HTTP 裸服务,无网页
- 宿主机端口
-v /registry:/var/lib/registry数据卷挂载(重点)- 宿主机目录:
/registry - 容器内部镜像存储路径:
/var/lib/registry
- 宿主机目录:
容器内部
/var/lib/registry是 registry 存放所有镜像数据的目录。做挂载:删除 registry 容器,镜像文件还保留在宿主机/registry目录,不会丢失,实现持久化 。如果宿主机/registry不存在,docker 会自动创建这个宿主机目录
- 末尾的
registry:使用的镜像名称,就是之前docker pull registry拉取的官方原生仓库镜像。
查看容器运行状态

上传本地镜像到仓库
docker push语法强制要求:镜像名称必须带上「仓库地址:端口」前缀,Docker 靠这个前缀识别要推送到哪一个仓库,故在上传前必须打标签,不打标签无法直接 push 到私有仓库
bash
[root@docker1 ~]# docker tag webserver:v4 localhost:5000/webserver:v4
[root@docker1 ~]# docker push localhost:5000/webserver:v4

从仓库里拉取
bash
[root@docker1 ~]# docker pull localhost:5000/webserver:v4

因为本地已经存在一模一样的镜像,故不会有真正拉取的动作,上传也一样
2.2 配置仓库自启动
bash
[root@docker1 ~]# vim /etc/systemd/system/registry.service

刷新配置,停止容器
bash
[root@docker1 ~]# systemctl daemon-reload
[root@docker1 ~]# docker stop registry
设置开机自启并立即启动
bash
[root@docker1 ~]# systemctl enable --now registry

2.3 仓库加密
insecure‑registries 和仓库加密二者互斥,不会同时生效
Docker 默认要求镜像仓库必须使用HTTPS 加密通信 。
我们用registry容器搭建的私有仓库默认跑在HTTP ,没有证书,传输为明文。
当使用 IP 访问仓库时,docker 会报错:
http: server gave HTTP response to HTTPS client
insecure‑registries告诉 docker:这个仓库允许使用 HTTP 明文访问,跳过 HTTPS 校验
Docker 私有仓库开启加密通信需要配置TLS 证书实现 HTTPS。
当配置 TLS 证书之后,仓库升级为 HTTPS 加密访问:
通信过程:客户端 ↔ registry 之间镜像数据全部加密传输
配置 TLS 证书告诉 docker:该仓库使用 HTTPS 加密通信,执行正常证书校验,不再使用 HTTP 明文。
⚠️此时客户端不能再配置 insecure‑registries ,否则客户端会用 HTTP 协议去连接 HTTPS 服务,报错:
http: server gave HTTPS response to HTTP client
删除正在运行的容器 registry
bash
[root@docker1 ~]# docker rm -f registry
下载 epel 源,升级软件包
openssl req 用来生成证书请求 CSR、自签名证书,做 registry 私有仓库 TLS 证书就用这个命令
bash
[root@docker1 ~]# wget -O /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo
[root@docker1 ~]# yum install -y openssl11
‑addext:给证书增加扩展项,可以多次使用
若有这个参数,可以不升级

添加域名解析
bash
[root@docker1 ~]# vim /etc/hosts

创建 certs 目录,专门用于存放证书;生成一份自签名 TLS 证书,用于 registry 私有仓库 HTTPS,域名reg.westos.org
bash
[root@docker1 ~]# mkdir certs
[root@docker1 ~]# openssl11 req -newkey rsa:4096 -nodes -sha256 -keyout certs/westos.org.key -addext "subjectAltName = DNS:reg.westos.org" -x509 -days 365 -out certs/westos.org.crt
| 参数 | 解释 |
|---|---|
| openssl11 req | 使用 openssl11 工具,req 子命令,处理证书 / 证书请求 |
| -newkey rsa:4096 | 新建密钥,RSA 算法,密钥长度 4096 位 |
| -nodes | No DES,私钥不加密,不设置密码;registry 容器必备,否则启动要输密码 |
| -sha256 | 证书签名哈希算法使用 SHA256 |
| -keyout certs/westos.org.key | 输出私钥文件,输出到 certs 目录 |
| -addext "subjectAltName = DNS:reg.westos.org" | 添加 SAN 扩展,主题备用名称,域名reg.westos.org;docker 校验 HTTPS 证书必须要有 SAN,只写 CN 会校验失败 |
| -x509 | 直接生成自签名证书,不是生成 CSR 证书申请文件 |
| -days 365 | 证书有效期 365 天 |
| -out certs/westos.org.crt | 输出公钥证书 crt 文件 |
域名必须保持一致

启动 TLS 加密 registry
bash
[root@docker1 ~]# docker run -d -p 443:443 --restart=always --name registry -v /registry:/var/lib/registry -v /root/certs:/certs -e REGISTRY_HTTP_ADDR=0.0.0.0:443 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/westos.org.crt -e REGISTRY_HTTP_TLS_KEY=/certs/westos.org.key registry
| 参数 | 说明 |
|---|---|
| ‑d | 后台守护进程运行容器 |
| ‑p 443:443 | 端口映射,宿主机 443 映射容器 443,HTTPS 默认端口 443 |
| - -restart=always | 容器开机自启、意外退出自动重启 |
| - -name registry | 容器名字叫 registry |
| ‑v /registry:/var/lib/registry | 持久化镜像数据。宿主机/registry存放镜像,映射容器镜像存储目录 |
| ‑v /root/certs:/certs | 证书目录挂载,宿主机/root/certs(存放 crt、key)挂载到容器内/certs |
| ‑e REGISTRY_HTTP_ADDR=0.0.0.0:443 | 环境变量,registry 监听容器内全部网卡的 443 端口 |
| ‑e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/shturl.cc/.crt | 指定容器内证书公钥路径 |
| ‑e REGISTRY_HTTP_TLS_KEY=/certs/shturl.cc/.key | 指定容器内私钥路径 |
| registry | 使用官方 registry 镜像 |

部署客户端证书
Docker 访问 HTTPS 私有仓库时,默认会向系统 CA 根证书库校验仓库的 TLS 证书。
我们用openssl生成的是自签名证书 ,不是正规 CA 颁发的,系统默认不信任,docker 会报错证书校验失败,拒绝 push/pull。
Docker 启动的时候,会自动扫描 /etc/docker/certs.d/ 下面的子目录,把服务端的公钥证书westos.org.crt复制过来,改名为ca.crt放到这个目录,告诉 Docker:这个特定私有仓库reg.westos.org的自签名证书是可信的,可以正常做 HTTPS 加密通信。
bash
[root@docker1 ~]# mkdir -p /etc/docker/certs.d/reg.westos.org/
[root@docker1 ~]# cp /root/certs/westos.org.crt /etc/docker/certs.d/reg.westos.org/ca.crt
给镜像打标签并上传到私有仓库
bash
[root@docker1 ~]# docker tag nginx:latest reg.westos.org/nginx:latest
[root@docker1 ~]# docker push reg.westos.org/nginx:latest

测试
-k:跳过本地证书校验 。即使是自签名证书,curl 也允许连接
