当你的团队开始频繁构建和部署 Docker 镜像时,公共仓库(如 Docker Hub)的拉取速度、安全性和稳定性往往会成为瓶颈。私有仓库不仅让你完全掌控镜像的存储和分发,还能与 CI/CD 流程无缝集成。本文将从实际场景切入,带你一步步搭建一个可用的 Docker 私有仓库,并深入镜像管理的核心操作。
为什么需要私有仓库?
想象一下:你的开发环境无法访问外网,或者每次拉取镜像都要等上几分钟。更关键的是,你不想把内部代码或商业镜像暴露在公共仓库中。私有仓库可以解决这些问题,它提供本地化的镜像存储和访问控制,并且是 Kubernetes 等容器编排平台的基础组件之一。正如 Kubernetes 官方文档所指出的,容器化工作负载的管理需要一套可靠的分发机制,而私有仓库正是其中关键的一环。
搭建基础 Registry:从零开始
Docker 官方提供了 registry 镜像,可以快速启动一个最基本的私有仓库。执行以下命令:
docker run -d -p 5000:5000 --name registry registry:2
这样就在本机 5000 端口启动了一个 registry 容器。为了验证它是否工作,你可以先拉取一个镜像,然后打上私有仓库的标签并推送:
docker pull hello-world
docker tag hello-world localhost:5000/hello-world
docker push localhost:5000/hello-world
如果推送成功,说明基础仓库已经可用。但注意,这种默认配置没有认证和加密,只适合本地测试。如果要在网络环境使用,必须添加安全措施。
配置 TLS 与基本认证
在生产环境中,你需要为仓库配置 TLS 证书,否则 Docker 客户端会拒绝非 localhost 的推送。假设你已经有域名 registry.example.com 和证书文件,可以这样启动:
docker run -d -p 5000:5000 --name registry
-v /path/to/certs:/certs
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/server.crt
-e REGISTRY_HTTP_TLS_KEY=/certs/server.key
registry:2
同时,使用 htpasswd 创建认证文件,并挂载到容器中:
mkdir auth
htpasswd -Bc auth/htpasswd user1
启动时加入环境变量:
-e REGISTRY_AUTH=htpasswd
-e REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd
这样,客户端在推送或拉取时就需要登录:docker login registry.example.com。
镜像管理:推送、拉取、删除与清理
推送与拉取
推送镜像时,需要将镜像标签指向仓库地址。例如:
docker tag my-image:latest registry.example.com/my-image:latest
docker push registry.example.com/my-image:latest
拉取时直接使用仓库地址即可:
docker pull registry.example.com/my-image:latest
注意,镜像命名最好包含项目或团队前缀,例如 team-a/app,以便于管理。
删除镜像
默认的 registry 镜像不提供删除 API,但你可以通过 Docker Registry HTTP API 删除镜像的 manifest,然后运行垃圾回收:
curl -X DELETE https://registry.example.com/v2/my-image/manifests/<digest>
docker exec registry bin/registry garbage-collect /etc/docker/registry/config.yml
注意,删除操作需要谨慎,因为可能会影响正在运行的容器。建议在删除前确认镜像不再被使用。
清理与备份
随着时间推移,仓库会积累大量无用镜像。你可以定期执行垃圾回收,并备份仓库数据。最简单的方式是备份 registry 容器的数据卷,例如:
docker run --rm --volumes-from registry -v $(pwd):/backup ubuntu tar cvf /backup/registry-backup.tar /var/lib/registry
使用 Harbor 增强功能
如果你需要更完善的镜像管理功能,如镜像复制、漏洞扫描、RBAC 权限控制,推荐使用 Harbor。Harbor 是一个开源的企业级 registry 项目,它基于 Docker registry,并提供了 Web 界面和丰富的 API。你可以通过 Docker Compose 或 Helm 部署 Harbor,它支持多租户,并且与 Kubernetes 集成良好。
常见问题与排查
推送时出现“http: server gave HTTP response to HTTPS client”
这是因为 Docker 默认使用 HTTPS 连接。如果你在内网使用 HTTP,需要在 Docker 客户端配置中允许该地址:编辑 /etc/docker/daemon.json,添加:
{
"insecure-registries": ["registry.example.com"]
}
然后重启 Docker 服务。
认证失败
检查 htpasswd 文件是否生成正确,以及环境变量是否挂载。还可以尝试在客户端手动执行 docker login 来验证。
镜像存储占用过大
定期清理无用的镜像,并考虑使用镜像分层和压缩技术。也可以参考我们之前关于镜像构建优化的文章,从源头减小镜像体积。
总结与参考
搭建 Docker 私有仓库是容器化实践中的基础技能。本文从零开始介绍了 registry 的部署、TLS 和认证配置,以及镜像的推送、拉取、删除和备份。对于更复杂的需求,Harbor 提供了更全面的解决方案。在实际操作中,你还需要结合网络环境、存储规划和安全策略进行调整。
参考资料:
- Kubernetes Concepts 官方文档 – 了解容器编排与镜像分发的关系
- OpenTelemetry 官方文档 – 了解可观测性在容器环境中的应用
延伸阅读
