#作者:西门吹雪
文章目录
摘要
- 通过在内网部署 Docker Distribution Registry 的"代理缓存"(pull‑through cache),可将外部镜像内容缓存到本地,显著提升后续拉取速度与稳定性。
- 为 Docker 客户端配置
registry-mirrors后,开发者仍使用原有镜像名与工作流,无需更改命令,实现"无感化"加速。 - 本文聚焦于对
docker.io(Docker Hub)上游的缓存与加速,包含原理、部署、客户端配置、验证与排错;最后附上对"多上游仓库"的建议。
架构与原理
+------------------+ +-------------------------+ +-------------------------+
| Docker 客户端 | 拉取 | 本地 Registry (缓存) | 未命中 | Docker Hub (docker.io)|
| docker pull X +---------> http://<cache>:5000 +----------> registry-1.docker.io |
| | | /var/lib/registry | | |
| 第二次 pull | 命中 | 命中本地缓存直接返回 | | |
+------------------+ +-------------------------+ +-------------------------+
- 模式:注册表以"代理缓存"模式运行,向上游仓库拉取并将
manifests与blobs持久化到本地。 - 存储:默认路径在容器内为
/var/lib/registry/docker/registry/v2/,包括:blobs/sha256/...(内容寻址存储)repositories/<namespace>/<name>/_manifests/...(清单、标签索引)
- 第二次拉取命中本地缓存,性能与稳定性显著提升,减少外网带宽与限流影响。
准备与配置
Registry 配置文件(示例)
文件:/Users/user/docker/config.yml(参考:/Users/userhome/docker/config.yml:10-11)
yaml
version: 0.1
log:
level: info
storage:
filesystem:
rootdirectory: /var/lib/registry
http:
addr: :5000
proxy:
remoteurl: https://registry-1.docker.io
proxy.remoteurl指向 Docker Hub 上游。storage.filesystem.rootdirectory为缓存落盘目录。
Docker Compose 部署(推荐)
示例文件(稳定版镜像):
yaml
services:
registry:
image: registry:2
container_name: registry-proxy
ports:
- "5000:5000"
volumes:
- /Users/userhome/docker/config.yml:/etc/docker/registry/config.yml
- /Volumes/DockerSystem/registry:/var/lib/registry
environment:
HTTP_PROXY: "http://<proxy_host>:<proxy_port>"
HTTPS_PROXY: "http://<proxy_host>:<proxy_port>"
NO_PROXY: "localhost,127.0.0.1,registry-proxy,192.168.3.0/24,192.168.123.0/24,172.16.0.0/12,192.168.0.0/16"
restart: unless-stopped
HTTP_PROXY/HTTPS_PROXY/NO_PROXY:让容器能通过公司代理访问上游;必要时注入公司 CA 并信任。- 使用
registry:2。不使用registry:3 - 仓库运行主机IP为
192.168.3.7,下面会引用,确保客户端能访问该IP。
启动与日志:
bash
docker compose up -d
docker compose logs -f
客户端无感化配置
Docker 引擎配置(registry‑mirrors)
- 目标:客户端继续使用原始镜像名(如
grafana/grafana:12.0.0),由引擎透明转发到你的缓存注册表。 - Linux(
/etc/docker/daemon.json):
json
{
"registry-mirrors": ["http://192.168.3.7:5000"],
"insecure-registries": ["192.168.3.7:5000", "localhost:5000"]
}
重启引擎:
bash
sudo systemctl restart docker
- macOS/Windows(Docker Desktop → Settings → Docker Engine):
json
{
"registry-mirrors": ["http://192.168.3.7:5000"],
"insecure-registries": ["192.168.3.7:5000", "localhost:5000"]
}
点击 Apply & Restart。
无感化行为说明
- 当客户端执行
docker pull grafana/grafana:12.0.0时,引擎将对docker.io的请求透明转发到你的缓存注册表。 - CI/CD、
docker build、Dockerfile中的FROM alpine:latest等场景全部保持原样;对开发者"无感"。
使用与验证
健康检查
bash
curl http://localhost:5000/v2/
# 应返回 200 OK
拉取镜像
- 命名空间镜像(不加
library/前缀):
bash
docker pull grafana/grafana:12.0.0 # 无感模式(通过 registry-mirrors)
# 或显式前缀(直接走你的缓存注册表)
docker pull localhost:5000/grafana/grafana:12.0.0
- 官方无命名空间镜像(使用
library/前缀):
bash
docker pull alpine:latest # 无感模式
docker pull localhost:5000/library/alpine:latest
查看已缓存内容
- 列出缓存仓库:
bash
curl -s http://localhost:5000/v2/_catalog
- 查看标签:
bash
curl -s http://localhost:5000/v2/grafana/grafana/tags/list
curl -s http://localhost:5000/v2/library/alpine/tags/list
-
宿主机缓存目录:
/Volumes/DockerSystem/registry/docker/registry/v2/
├── blobs/sha256/...
└── repositories/grafana/grafana/_manifests/tags/12.0.0/... -
整体迁移特性:
这个目录整体拷贝到新的环境,运行registry服务,这里缓存的镜像将在新环境可用。
性能与运营建议
- 持久化与硬件:将
/var/lib/registry映射到宿主机 SSD 目录,避免容器重建导致缓存丢失。 - NO_PROXY 合理配置:对本地与内网地址设置,避免经企业代理绕路。
- 上游限流:在容器中设置
REGISTRY_PROXY_USERNAME/REGISTRY_PROXY_PASSWORD使用有额度账号。 - 版本选择:生产使用
registry:2优先。registry:3使用中遇到问题。
安全与合规
- HTTPS 与信任:为缓存注册表配置 TLS,或在客户端配置
insecure-registries时做好边界控制。
建议(多上游仓库)
- 单实例 Registry 的
proxy.remoteurl仅能指向一个上游。 - 若要支持
ghcr.io、quay.io等:- 为每个上游部署一个独立实例(不同端口/主机名),并设置对应凭据;客户端通过显式前缀拉取。
- 或在容器运行时(如 containerd/Kubernetes)配置 per‑registry mirrors,实现对多个主机名的"无感化"支持。
- 不建议使用 HTTPS 透明代理加缓存(安全与复杂度较高),除非团队具备相关运维与合规能力。
附录:关键命令速查
bash
# 启动与日志
docker compose up -d
docker compose logs -f
# 健康检查
curl http://localhost:5000/v2/
# 拉取(无感模式)
docker pull grafana/grafana:12.0.0
# 拉取(显式前缀)
docker pull localhost:5000/grafana/grafana:12.0.0
docker pull localhost:5000/library/alpine:latest
# 查看标签
curl -s http://localhost:5000/v2/grafana/grafana/tags/list
curl -s http://localhost:5000/v2/library/alpine/tags/list