引言:当Docker Hub不再是“免费午餐”
想象一下这个场景:你熬了几个通宵,终于打包好了一个完美无瑕的Docker镜像,它就像你精心雕琢的艺术品。你兴冲冲地想要部署到生产服务器上,结果发现:docker pull 的速度慢如蜗牛(网络跨国长途),或者更糟,触发了Docker Hub的拉取频率限制,部署脚本直接卡死!
这还不是最可怕的。如果你的镜像里不小心包含了敏感的数据库连接信息、API密钥,那么把它放在公共仓库无异于“裸奔”。再者,对于企业而言,核心业务应用的镜像就是最高商业机密,岂能放在别人的服务器上?
于是,我们迫切需要一個私有的、安全的、高速的、内网的镜像托管中心。而Docker官方开源的 Docker Registry,就是为你打造这个专属“藏宝库”的神兵利器。
第一章:Registry是何方神圣?它不是Docker Hub!
首先,我们必须澄清一个常见的误解:Docker Registry是一个软件,而Docker Hub是一个服务。
- Docker Hub:可以理解为镜像托管的“GitHub”。它是一个由Docker公司运营的公共在线服务,我们平时常用的
docker pull ubuntu就是从这里的公共库拉取的。 - Docker Registry:是一个开源的应用程序,它实现了Docker Registry API,负责存储和分发Docker镜像。你可以把它安装在你自己的服务器上,从而创建一个完全受你控制的私有镜像仓库。
简单来说,Docker Hub是“公共云盘”,而Docker Registry是让你搭建“私有NAS”的工具包。它的核心优势在于:
- 隐私与安全:镜像只在内部网络流转,彻底杜绝外部泄露风险。
- 性能与速度:内网传输,带宽跑满,部署效率飙升。
- 成本控制:自建仓库,无需担心公有服务的流量和存储费用。
- 合规性:对于有严格数据监管要求的行业(如金融、政务),私有化部署是必选项。
第二章:庖丁解牛:Registry的核心概念与工作流
要玩转Registry,得先了解它的几个关键“器官”。
- 仓库(Repository):这不是指整个Registry服务,而是指某个镜像的集合。比如,你有一个Web应用镜像,其版本包括v1.0, v1.1, v2.0,那么所有这些版本的镜像都存放在同一个名为
my-web-app的仓库里。拉取时用myregistry.com/my-web-app:tag。 - 清单(Manifest):这是一个描述镜像的JSON文件。它包含了镜像的配置信息、各层的摘要(Digest)以及镜像的标签(Tag)。当你给镜像打上新标签时,本质上只是创建了一个指向相同层的新清单,非常高效。
- 层(Layer):Docker镜像由一系列只读层叠加而成。每一层代表Dockerfile中的一条指令。Registry会单独存储这些层。不同镜像共享的相同层只会存储一份,这极大地节省了存储空间。
- 标签(Tag):通常用于标识镜像的不同版本,比如
:latest,:v1.0。它是指向某个特定清单的指针,非常灵活。
工作流简述:
当你执行 docker push myregistry.com/myapp:latest 时:
- Docker客户端会与Registry服务通信,告知要推送的镜像。
- Registry检查镜像的各个层,如果它发现自己已经存在某些层(通过内容的哈希值判断),就会告诉客户端“这些层我有了,不用传了”。
- 客户端只上传Registry缺失的层。
- 所有层上传完毕后,客户端将镜像的清单(Manifest)推送给Registry。
- Registry存储清单,并将其与仓库名
myapp和标签latest关联起来。
拉取过程则正好相反,同样利用了层的复用机制来提升效率。
第三章:手把手实战:从零搭建一个安全的私有Registry
光说不练假把式。现在,我们就在一台Linux服务器上,搭建一个带基本身份认证的私有Registry。
环境准备:一台安装了Docker和Docker Compose的服务器(IP假设为 192.168.1.100)。
目标:搭建一个需要用户名密码才能访问的Registry,并通过HTTPS(自签名证书)提供服务。
步骤一:创建证书和认证文件
由于是内部使用,我们采用自签名证书。首先创建一个目录来存放所有配置。
mkdir ~/docker-registry && cd ~/docker-registry
- 生成自签名证书:
openssl req -newkey rsa:4096 -nodes -sha256 -keyout domain.key -x509 -days 365 -out domain.crt
-
- 在提示输入
Common Name时,必须输入你服务器的域名或IP,例如192.168.1.100。这是关键一步!
- 在提示输入
- 创建认证密码文件:
我们需要htpasswd工具,它通常来自apache2-utils包。
# Ubuntu/Debian
sudo apt-get install apache2-utils
# CentOS/RHEL
sudo yum install httpd-tools
# 创建密码文件,用户名为 myuser
htpasswd -Bc registry.password myuser
按提示输入密码。-B 表示使用bcrypt加密(推荐),-c 是创建新文件。
步骤二:编写Docker Compose文件
使用Docker Compose能方便地管理服务。创建 docker-compose.yml 文件:
version: '3'
services:
registry:
image: registry:2
container_name: my-private-registry
ports:
- "5000:5000"
environment:
# 设置Registry的URL
REGISTRY_HTTP_ADDR: 0.0.0.0:5000
# 启用身份认证
REGISTRY_AUTH: htpasswd
REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm
REGISTRY_AUTH_HTPASSWD_PATH: /auth/registry.password
# 指定TLS证书和密钥
REGISTRY_HTTP_TLS_CERTIFICATE: /certs/domain.crt
REGISTRY_HTTP_TLS_KEY: /certs/domain.key
volumes:
# 挂载数据卷,持久化存储镜像数据
- ./registry-data:/var/lib/registry
# 挂载证书和密码文件
- ./domain.crt:/certs/domain.crt
- ./domain.key:/certs/domain.key
- ./registry.password:/auth/registry.password
networks:
- registry-net
networks:
registry-net:
步骤三:启动Registry服务
在 ~/docker-registry 目录下,执行:
docker-compose up -d
使用 docker logs my-private-registry 查看日志,确认没有错误。
步骤四:配置Docker客户端信任自签名证书
Docker默认要求使用HTTPS且证书必须受信任。我们需要让客户端信任我们刚创建的证书。
- 在服务器本身(因为客户端和Registry在同一台机器),拷贝证书到Docker的证书目录:
sudo mkdir -p /etc/docker/certs.d/192.168.1.100:5000
sudo cp domain.crt /etc/docker/certs.d/192.168.1.100:5000/ca.crt
-
- 目录名必须是
/etc/docker/certs.d/你的Registry域名或IP:端口/。
- 目录名必须是
- 对于其他需要访问此私有仓库的机器(比如你的本地电脑),也需要将
domain.crt文件拷贝到相应目录。或者更简单的方法(仅用于测试):在Docker守护进程的配置中(/etc/docker/daemon.json)添加insecure-registries选项(不推荐用于生产环境)。
{
"insecure-registries": ["192.168.1.100:5000"]
}
然后重启Docker服务:sudo systemctl restart docker。
步骤五:完整示例:登录、推送、拉取
现在,我们来体验完整的流程。
- 登录到私有仓库:
docker login 192.168.1.100:5000
输入之前设置的用户名(myuser)和密码。
- 标记一个本地镜像,准备推送:
假设我们有一个本地镜像nginx:latest。
docker tag nginx:latest 192.168.1.100:5000/my-nginx:v1
○ 格式为:私有仓库地址/仓库名:标签。
- 推送到私有仓库:
docker push 192.168.1.100:5000/my-nginx:v1
如果一切正常,你会看到层被逐个上传。
- 从私有仓库拉取镜像:
为了测试,先删除本地刚标记的镜像。
docker rmi 192.168.1.100:5000/my-nginx:v1
docker rmi nginx:latest # 如果愿意,也可以删除原镜像
然后拉取:
docker pull 192.168.1.100:5000/my-nginx:v1
成功拉取!你的私有仓库完美工作了。
- 查看仓库中的镜像:
Registry API本身不提供漂亮的Web界面(但有很多第三方UI,如portus,docker-registry-ui),但我们可以通过API直接查询。
# 列出 my-nginx 仓库的所有标签
curl -u myuser:password https://192.168.1.100:5000/v2/my-nginx/tags/list
你会收到一个JSON响应,其中包含 ["v1"]。
第四章:进阶与展望
基础的Registry已经能满足很多需求,但在企业级场景下,我们还可以考虑:
- 使用反向代理(Nginx):将Registry放在Nginx后面,可以更方便地管理SSL终止、负载均衡和更复杂的认证方式。
- 集成对象存储:默认Registry将数据存储在本地文件系统。通过配置,可以将其后端改为AWS S3、Google Cloud Storage、阿里云OSS等,获得更好的可靠性和扩展性。
- 部署UI管理界面:为Registry加一个“脸面”,方便非命令行用户查看和管理镜像。
- 与CI/CD流水线集成:在Jenkins、GitLab CI等工具中,自动将构建成功的镜像推送到你的私有Registry,实现完全的自动化部署。
结语
Docker Registry看似简单,却是构建现代化、云原生应用交付体系中不可或缺的一环。它就像那个藏在公司机房深处的“宝藏库”,虽然低调,却守护着整个业务系统的核心资产。通过本文的介绍和实战,希望你已经掌握了这把钥匙,能够 confidently 搭建和管理属于自己的高效、安全的Docker镜像帝国。现在,就快去给你的镜像宝贝们安个家吧!
Docker私有仓库搭建指南

被折叠的 条评论
为什么被折叠?



