冷蟊初退 孤灯野澜 志起鸡鸣 墓不悲秋 技术交流 软件开发 商业合作 加Q:411239339

Day 23 如何搭建私有镜像仓库

浏览:10次阅读
没有评论

共计 767 个字符,预计需要花费 2 分钟才能阅读完成。

你有没有遇到过这样的场景:公司开发了一套内部系统,打好了 Docker 镜像,然后问题来了——这镜像往哪放?推到 Docker Hub?老板第一个不答应,公司代码怎么能放公网。放本地?那隔壁工位的同事怎么拉取?更别说生产环境部署了,总不能每次都用 U 盘拷吧。

这就是私有镜像仓库要解决的问题。它就像公司内部的 " 快递驿站 ",所有镜像统一存放、统一管理,谁要用谁来取,安全又高效。

本文你将学到

  • Docker Registry 的工作原理和架构
  • 5 分钟搭建一个私有镜像仓库
  • 为 Registry 配置 HTTPS 和访问认证
  • Harbor 企业级镜像仓库的部署和使用
  • 镜像推送、拉取、删除的完整操作流程
  • 生产环境的安全加固方案

阅读时间:10 分钟 | 实操时间:30 分钟 | 难度等级:中级


为什么需要私有镜像仓库

在聊怎么搭建之前,先说说为什么要搞这个东西。

用生活中的例子来类比:Docker Hub 就像淘宝,什么都有,但你不可能把公司的机密产品挂上去卖。私有镜像仓库就是公司的内部仓库,东西只在内部流通。

具体来说,私有仓库解决了这几个痛点:

安全性 :代码和配置不出内网,满足合规要求。金融、医疗、政府行业,这是硬性要求。

速度 :从内网拉镜像,速度比从公网快几十倍。特别是那些动辄几个 G 的镜像,内网几秒搞定,公网可能要等半天。

可控性 :谁能推、谁能拉、哪些镜像允许上生产,全都你说了算。

稳定性 :不依赖外网,Docker Hub 挂了也不影响你部署。

整体架构

先看看私有镜像仓库在整个开发流程中的位置:

 开发者本机                    私有仓库                     生产服务器
+-----------+    docker push   +-----------+   docker pull  +-----------+
|           | ---------------> |           | -------------> |           |
|  Build    |                  |  Registry |                |  Deploy   |
|  镜像     |                  |  存储镜像  |                |  运行容器  |
|           | <--------------- |           | <------------- |           |
+-----------+    docker pull   +-----------+   docker push  +-----------+
                                    |
                                    | Web UI (Harbor)
                                    v
                              +-----------+
                              |  管理员    |
                              |  审核 / 管理  |
                              +-----------+

方案一:Docker Registry(轻量级)

Docker 官方提供了一个开源的镜像仓库实现,叫 Docker Registry。它就像一个 " 毛坯房 "——功能够用,但比较朴素,适合小团队或测试环境。

快速启动

一条命令就能跑起来:

docker run -d \
  --name registry \
  --restart always \
  -p 5000:5000 \
  -v /data/registry:/var/lib/registry \
  registry:2

就这么简单,你已经有了一个私有镜像仓库。我们来验证一下:

curl http://localhost:5000/v2/_catalog

预期输出:

{"repositories":[]}

空的,因为还没推过镜像。接下来试试推一个。

推送镜像到私有仓库

假设你本地有一个 nginx 镜像,要推到私有仓库,需要先给它打个标签:

# 先拉一个测试镜像
docker pull nginx:alpine

# 打标签,格式:仓库地址 / 镜像名: 标签
docker tag nginx:alpine localhost:5000/my-nginx:v1

# 推送
docker push localhost:5000/my-nginx:v1

预期输出:

The push refers to repository [localhost:5000/my-nginx]
v1: digest: sha256:a1b2c3d4... size: 1568

再查一下仓库里有什么:

curl http://localhost:5000/v2/_catalog

预期输出:

{"repositories":["my-nginx"]}

镜像已经躺在私有仓库里了。

从私有仓库拉取镜像

在其他机器上(或者先删掉本地的),就可以从私有仓库拉取了:

# 先删掉本地的
docker rmi localhost:5000/my-nginx:v1

# 从私有仓库拉取
docker pull localhost:5000/my-nginx:v1

查看镜像标签列表

curl http://localhost:5000/v2/my-nginx/tags/list

预期输出:

{"name":"my-nginx","tags":["v1"]}

配置 HTTPS(生产环境必须)

刚才用的是 HTTP,在生产环境中这是不可接受的。就好比你把仓库大门敞开,谁都能进来搬东西。我们需要给它上把锁——HTTPS。

生成自签名证书

如果你有正式的 SSL 证书当然更好,这里先用自签名证书演示:

# 创建证书目录
mkdir -p /data/registry/certs

# 生成自签名证书(把 registry.example.com 换成你的域名或 IP)openssl req -newkey rsa:4096 -nodes -sha256 \
  -keyout /data/registry/certs/domain.key \
  -x509 -days 365 \
  -out /data/registry/certs/domain.crt \
  -subj "/CN=registry.example.com" \
  -addext "subjectAltName=DNS:registry.example.com"

启动带 HTTPS 的 Registry

先停掉之前的容器,再用新配置启动:

docker rm -f registry

docker run -d \
  --name registry \
  --restart always \
  -p 5000:5000 \
  -v /data/registry/data:/var/lib/registry \
  -v /data/registry/certs:/certs \
  -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
  -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
  registry:2

客户端信任证书

使用自签名证书时,Docker 客户端默认不信任,需要手动添加:

# 在每台需要访问仓库的机器上执行
mkdir -p /etc/docker/certs.d/registry.example.com:5000
cp /data/registry/certs/domain.crt \
  /etc/docker/certs.d/registry.example.com:5000/ca.crt

# 重启 Docker
systemctl restart docker

配置访问认证

光有 HTTPS 还不够,还要控制谁能访问。我们用 HTTP Basic Auth 来实现。

创建密码文件

mkdir -p /data/registry/auth

# 创建用户(用户名: admin,会提示输入密码)docker run --rm --entrypoint htpasswd \
  httpd:2 -Bbn admin yourpassword > /data/registry/auth/htpasswd

启动带认证的 Registry

docker rm -f registry

docker run -d \
  --name registry \
  --restart always \
  -p 5000:5000 \
  -v /data/registry/data:/var/lib/registry \
  -v /data/registry/certs:/certs \
  -v /data/registry/auth:/auth \
  -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
  -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
  -e REGISTRY_AUTH=htpasswd \
  -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
  -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
  registry:2

登录和使用

# 登录
docker login registry.example.com:5000

# 输入用户名和密码后,就可以正常推拉镜像了
docker push registry.example.com:5000/my-nginx:v1

方案二:Harbor(企业级)

Docker Registry 虽然能用,但它就像一个命令行工具——没有图形界面、没有权限管理、没有镜像扫描。如果你们公司有几十号开发人员,光靠 Registry 管理镜像,运维同学怕是要疯。

Harbor 就是来解决这个问题的。它是 VMware 开源的企业级镜像仓库,你可以把它理解为 " 精装修 " 的 Registry,自带 Web 管理界面、细粒度权限控制、镜像漏洞扫描、镜像签名等功能。

Harbor 的核心特性

Harbor 功能全景
+--------------------------------------------------+
|  Web 管理界面    |  基于角色的访问控制 (RBAC)         |
|  项目管理        |  管理员 / 开发者 / 访客 三种角色        |
+--------------------------------------------------+
|  镜像漏洞扫描    |  镜像复制(多仓库同步)|
|  自动扫描新镜像  |  支持主从 / 双主复制策略              |
+--------------------------------------------------+
|  Webhook 通知   |  审计日志                          |
|  CI/CD 集成     |  记录所有操作,满足合规要求          |
+--------------------------------------------------+
|  Helm Chart 仓库 |  垃圾回收                         |
|  统一管理容器和 Chart|  自动清理无引用的镜像层           |
+--------------------------------------------------+

安装 Harbor

Harbor 依赖 Docker Compose,确保你的机器上已经安装了。

# 下载 Harbor 离线安装包(以 v2.11 为例)wget https://github.com/goharbor/harbor/releases/download/v2.11.0/harbor-offline-installer-v2.11.0.tgz

# 解压
tar xzvf harbor-offline-installer-v2.11.0.tgz
cd harbor

# 复制配置模板
cp harbor.yml.tmpl harbor.yml

修改配置文件

编辑 harbor.yml,主要改这几个地方:

# 访问地址
hostname: harbor.example.com

# HTTPS 配置
https:
  port: 443
  certificate: /data/harbor/certs/domain.crt
  private_key: /data/harbor/certs/domain.key

# 管理员密码(首次登录后请立即修改)harbor_admin_password: Harbor12345

# 数据存储路径
data_volume: /data/harbor/data

执行安装

# 带镜像扫描组件一起安装
./install.sh --with-trivy

预期输出(最后几行):

✔ ----Harbor has been installed and started successfully.----

安装完成后,打开浏览器访问 https://harbor.example.com,用 admin 账号登录。

Harbor 日常操作

创建项目

在 Web 界面点击 " 新建项目 ",填写项目名称,比如 backend。可以设置为公开或私有。

推送镜像到 Harbor

# 登录 Harbor
docker login harbor.example.com

# 打标签,格式:Harbor 地址 / 项目名 / 镜像名: 标签
docker tag my-app:latest harbor.example.com/backend/my-app:v1.0

# 推送
docker push harbor.example.com/backend/my-app:v1.0

权限管理

在项目设置中可以添加成员,并分配角色:

角色 权限
项目管理员 完全控制,包括成员管理
开发者 推送和拉取镜像
访客 只能拉取镜像

Harbor vs Docker Registry 对比

特性 Docker Registry Harbor
安装复杂度 一条命令 需要 Docker Compose
Web 界面 有,功能丰富
权限管理 仅 Basic Auth RBAC,细粒度控制
镜像扫描 内置 Trivy
镜像复制 支持多种策略
审计日志 完整审计
适用场景 个人 / 小团队 中大型企业

常见问题 Q&A

Q1:推送镜像时报 "http: server gave HTTP response to HTTPS client" 怎么办?

这是因为 Docker 默认要求使用 HTTPS,但你的 Registry 用的是 HTTP。有两种解决办法:

方法一(推荐):给 Registry 配上 HTTPS,参考上文的证书配置。

方法二(仅限测试环境):在 Docker 客户端配置中添加不安全仓库:

# 编辑 /etc/docker/daemon.json
{"insecure-registries": ["your-registry:5000"]
}

# 重启 Docker
systemctl restart docker

Q2:镜像越来越多,磁盘快满了怎么办?

Docker Registry 删除镜像后并不会立即释放磁盘空间,需要执行垃圾回收:

# 进入 Registry 容器执行垃圾回收
docker exec registry bin/registry garbage-collect \
  /etc/docker/registry/config.yml

Harbor 的话,可以在 Web 界面的 " 系统管理 - 垃圾回收 " 中配置定时清理任务,省心很多。

Q3:如何实现多机房镜像同步?

如果你有多个数据中心,可以用 Harbor 的镜像复制功能。在源 Harbor 中创建 " 复制规则 ",指定目标 Harbor 地址和触发条件(推送时自动同步 / 定时同步),Harbor 会自动处理增量同步,不用你写脚本。


小结

今天我们学习了两种私有镜像仓库方案:

Docker Registry 适合个人开发者和小团队,一条命令就能搞定。但它功能比较基础,就像一个 " 毛坯房 ",能住但不太舒服。

Harbor 是企业级方案,功能全面——Web 界面、权限管理、镜像扫描、审计日志一应俱全。如果你们公司有正式的 DevOps 需求,强烈推荐 Harbor。

无论选哪个方案,生产环境必须做到两点:一是 HTTPS 加密传输,二是访问认证。裸奔的仓库就像没上锁的保险柜,迟早出事。

明天是 Day 24 容器资源限制 ,我们会聊聊怎么给容器戴上 " 紧箍咒 "——限制 CPU、内存、磁盘 IO,防止某个容器吃光所有资源把整台机器搞崩。这在生产环境中非常重要,不容错过。

正文完
创作不易,扫码加点动力
post-qrcode
 0
果较瘦
版权声明:本站原创文章,由 果较瘦 于2026-03-29发表,共计767字。
转载说明:除特殊说明外本站文章皆由果较瘦原创发布,转载请注明出处。