
前面围绕这个项目:
text
https://github.com/Rodert/DockerHub
我们已经聊过很多 Docker 镜像相关问题:
text
Docker Hub 国内访问
registry-mirrors
Manifest
Layer
Digest
公共镜像代理
镜像可用性检测
供应链安全
但只要真正长期使用公共 Docker Mirror,你迟早会遇到一个问题:
今天能用的镜像地址,明天可能就失效了。
比如你在服务器上配置:
json
{
"registry-mirrors": [
"https://mirror-a.example.com",
"https://mirror-b.example.com"
]
}
今天:
bash
docker pull nginx
很快。
过一段时间:
text
timeout
connection reset
429
manifest unknown
服务关闭
又得重新找。
于是就进入一个更工程化的问题:
与其每天到处找公共镜像源,能不能自己搭一个 Docker Hub 缓存?
答案是:
可以。
而且已经有很成熟的方案:
Harbor Proxy Cache。
Harbor 不只是一个:
text
"公司内部存 Docker 镜像的仓库"
它还可以作为上游 Registry 的:
Pull-through Proxy Cache。
也就是说:
text
Docker Hub
↓
Harbor
↓
公司服务器 / 开发机 / K8s
第一次拉取:
text
Harbor 没有
↓
去 Docker Hub 拉
↓
返回给客户端
↓
同时缓存
第二次:
text
Harbor 已经有
↓
直接走本地缓存
Harbor 官方当前文档明确支持将 Harbor 配置为目标 Registry 的 Proxy Cache,并支持 Docker Hub 等多种 Registry;如果本地没有对应镜像,Harbor 会从上游获取并缓存,后续请求可以复用缓存。
今天就把这套架构讲透。
一、先理解公共 Mirror 的问题
我们现在常见的使用方式:
text
你的服务器
↓
公共 Docker Mirror
↓
Docker Hub
最大的优势:
简单。
例如:
bash
docker pull \
docker.1ms.run/library/nginx:latest
或者:
json
{
"registry-mirrors": [
"https://docker.1ms.run"
]
}
几分钟就能配置。
但问题是:
这个节点不是你控制的。
它什么时候:
text
限速
关闭
改策略
限制流量
增加登录
失效
你都控制不了。
二、个人开发当然没问题
如果只是:
text
个人电脑
测试服务器
临时 Docker 环境
公共 Mirror 非常方便。
比如:
text
MacBook
↓
Public Mirror
↓
Docker Hub
没必要为了:
text
偶尔拉几个镜像
自己搭 Harbor。
三、服务器越来越多以后就不一样了
假设公司:
text
100 台服务器
全部运行:
text
nginx
redis
mysql
node
golang
openjdk
如果每台服务器:
text
各自访问公网
就会出现:
text
重复下载
公网带宽浪费
Docker Hub 限流
网络不稳定
部署时间不可控
比如:
text
golang 镜像 800MB
100 台机器:
text
理论上可能重复传输几十 GB。
显然不合理。
四、更加合理的架构
增加一层:
text
Docker Hub
│
│ 第一次获取
↓
Harbor
Proxy Cache
/ | \
/ | \
↓ ↓ ↓
Server1 Server2 Server3
第一次:
text
Server1
↓
Harbor
↓
Docker Hub
Harbor 下载:
text
Manifest
Layers
Config
并缓存。
第二台:
text
Server2
↓
Harbor
如果对应内容已经存在:
text
直接从 Harbor 获取。
这就从:
公网重复下载
变成:
内网 Layer 复用。
五、这和 CDN 思路非常像
比如视频网站:
text
Origin Server
↓
CDN Edge
↓
User
Docker:
text
Docker Hub
↓
Harbor
↓
Docker Host
本质都是:
把热门内容缓存到离用户更近的位置。
只不过 Docker 缓存的是:
text
Manifest
Config
Layer Blob
六、为什么 Docker 特别适合缓存?
因为前面讲过:
text
Layer
通过:
text
Digest
进行内容寻址。
例如:
text
sha256:abc123
代表一份确定的内容。
只要 Digest 一样:
text
内容就是同一个 Blob。
这非常适合缓存。
七、Harbor Proxy Cache 怎么工作?
用户请求:
text
harbor.example.com/dockerhub/library/nginx:latest
Harbor 首先检查:
text
本地有没有这个 Artifact。
没有:
text
Harbor
↓
Docker Hub
↓
获取镜像
然后:
text
返回给用户
+
缓存到 Harbor。
官方文档当前描述的行为是:请求进入 Proxy Cache Project 后,如果镜像尚未缓存,Harbor 会向目标 Registry 拉取并返回,同时保存为缓存;后续请求则会根据上游 Manifest 状态决定使用缓存还是更新。
八、第二次再拉
用户:
bash
docker pull \
harbor.example.com/dockerhub/library/nginx:latest
Harbor:
text
已有缓存
就不需要:
text
重新下载所有 Layer。
Harbor 会检查上游镜像是否发生变化;如果未更新,就使用缓存,如果上游已有新内容则重新获取并更新缓存。
九、一个更有意思的情况:Docker Hub 暂时访问不了
假设:
text
Harbor → Docker Hub
突然网络中断。
但是:
text
nginx
redis
mysql
之前已经被缓存。
这时候客户端请求这些已缓存镜像,Harbor 的 Proxy Cache 设计可以在上游不可达时继续提供已有缓存内容。
这件事情非常重要。
因为它意味着:
Harbor 不只是加速。
还可以提高:
镜像供应可用性。
十、比如半夜部署
凌晨:
text
Docker Hub 网络异常。
Kubernetes 节点扩容:
text
新增 20 台机器。
需要:
text
redis:7
nginx:latest
公司基础镜像
如果这些镜像:
text
都已经存在 Harbor Cache。
你的内部部署:
text
仍然可以继续。
这就是:
缓存的真正价值。
十一、先看完整架构
我比较推荐:
text
Internet
│
↓
Docker Hub
│
↓
┌───────────────┐
│ Harbor │
│ Proxy Cache │
└───────────────┘
│
┌──────┼──────┐
↓ ↓ ↓
Docker CI Kubernetes
Server Runner Nodes
公司内部:
text
只需要允许 Harbor
访问外网。
其他服务器:
text
只访问 Harbor。
网络模型会简单很多。
十二、第一步:先有 Harbor
这篇重点放:
text
Proxy Cache
所以 Harbor 安装本身不展开太多。
最基本你需要:
text
Harbor Server
例如:
text
harbor.example.com
以及:
text
HTTPS
持久化存储
足够磁盘空间
如果只是内网实验:
text
一台 Linux
+
Docker Compose
就可以跑起来。
十三、正式环境为什么最好用 HTTPS?
因为客户端:
text
Docker Daemon
和:
text
Harbor Registry
之间需要传输:
text
镜像
认证信息
Token
正式环境应该:
text
HTTPS
而不是:
text
HTTP Registry。
否则又要在所有 Docker 主机里配置:
text
insecure-registries。
维护麻烦。
十四、第二步:添加 Registry Endpoint
Harbor 管理后台:
text
Administration
↓
Registries
添加:
text
Docker Hub
Endpoint。
概念:
text
Name:
dockerhub
Provider:
Docker Hub
如果使用 Docker Hub Account:
text
Access ID
Secret
也可以在 Endpoint 中配置。
Harbor 当前官方文档要求在创建 Proxy Cache Project 之前先配置对应 Registry Endpoint,并可以为 Endpoint 配置访问凭据以及证书验证。
十五、为什么推荐配置 Docker Hub 账号?
匿名访问:
text
可能受到更严格的 Rate Limit。
如果有:
text
Docker Hub Account
可以考虑:
text
给 Harbor 配一个只用于拉取的账号。
但原则:
最小权限。
不要:
text
为了拉公共镜像
给一个超级管理员账号。
Harbor 文档也明确提醒,用于 Proxy Cache 的 Endpoint 凭据决定 Harbor 能够访问哪些上游镜像,因此应该使用可信上游,并配置最小权限账号。
十六、第三步:创建 Proxy Cache Project
Harbor:
text
Projects
↓
New Project
例如:
text
Project Name:
dockerhub
然后打开:
text
Proxy Cache
选择刚才:
text
Docker Hub Endpoint。
这样:
text
dockerhub
这个 Project:
不再是普通 Harbor Project。
而是:
Proxy Cache Project。
Harbor 官方说明 Proxy Cache Project 与普通 Project 类似,但用途是代理目标 Registry,而且不能像普通项目那样向这个 Proxy Cache Project 推送镜像。
十七、于是地址就变成了
原来:
bash
docker pull nginx:latest
通过 Harbor:
bash
docker pull \
harbor.example.com/dockerhub/library/nginx:latest
结构:
text
harbor.example.com
↓
dockerhub
↓
library/nginx
↓
latest
十八、为什么这里仍然有 library?
因为:
text
nginx
是 Docker Hub Official Image。
它的完整 Repository:
text
library/nginx
所以:
text
Harbor Server
+
Proxy Project
+
Docker Hub Repository
组合成:
text
harbor.example.com/dockerhub/library/nginx
Harbor 官方当前的 Proxy Cache 使用方式也是给原始镜像名前面加上:
text
<harbor_server>/<proxy_project>/
前缀。
十九、比如 Redis
原始:
bash
docker pull redis:7
Harbor:
bash
docker pull \
harbor.example.com/dockerhub/library/redis:7
二十、比如个人 Docker Hub 镜像
原始:
bash
docker pull \
username/myapp:v1
Harbor:
bash
docker pull \
harbor.example.com/dockerhub/username/myapp:v1
注意:
text
不是 library/myapp。
因为它原来的 Namespace:
text
username
必须保留。
二十一、第一次 Pull 会发生什么?
执行:
bash
docker pull \
harbor.example.com/dockerhub/library/nginx:latest
流程:
text
Docker Client
↓
Harbor
↓
发现 Cache Miss
↓
Docker Hub
↓
Manifest
↓
Layers
↓
Harbor Storage
↓
Docker Client
这里:
text
Cache Miss
意思:
Harbor 里还没有。
二十二、第二次是什么?
另一个服务器:
bash
docker pull \
harbor.example.com/dockerhub/library/nginx:latest
流程:
text
Docker Client
↓
Harbor
↓
Cache Hit
↓
直接返回 Layer
客户端:
text
不需要自己跨公网访问 Docker Hub。
这就叫:
Cache Hit。
二十三、为什么第二次速度差距可能非常大?
假设:
text
Harbor 和服务器
都在:
text
1Gbps 内网。
Docker Hub 公网:
text
5MB/s
一个:
text
500MB
镜像。
公网:
text
约 100 秒。
内网:
理论上:
text
可以快得多。
尤其:
text
几十台机器并发拉取
的时候差距会非常明显。
二十四、CI/CD 也特别适合
例如 GitLab Runner / Jenkins:
text
每次 Build
都需要:
Dockerfile
FROM golang:1.25
如果每个 Runner:
text
都自己访问 Docker Hub
很浪费。
可以改:
Dockerfile
FROM harbor.example.com/dockerhub/library/golang:1.25
第一次:
text
Harbor 缓存。
后面的 CI:
text
直接内网拿。
二十五、Kubernetes 更适合
例如 Deployment:
yaml
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: nginx
image:
harbor.example.com/dockerhub/library/nginx:latest
以后所有 Node:
text
只访问 Harbor。
而不是:
text
每台 Node
↓
直接访问 Docker Hub。
二十六、这对 Kubernetes 扩容特别重要
比如:
text
晚上流量上涨。
HPA / Cluster Autoscaler:
text
突然增加 30 个 Pod。
甚至:
text
新增 Node。
如果每台机器:
text
都要跨公网拉 500MB Image。
扩容速度会被:
text
网络
严重拖慢。
有 Harbor Cache:
text
内网 Pull。
容器启动时间:
text
更稳定。
二十七、那么为什么不直接把所有镜像提前 push 到 Harbor?
当然可以。
这是另外一种方式:
text
docker pull nginx
↓
docker tag
↓
docker push harbor
例如:
bash
docker pull nginx:latest
然后:
bash
docker tag \
nginx:latest \
harbor.example.com/base/nginx:latest
再:
bash
docker push \
harbor.example.com/base/nginx:latest
二十八、这种方式叫什么?
可以理解成:
Explicit Mirroring。
或者:
手工 / 自动同步。
和 Proxy Cache 最大区别:
text
Mirror:
提前同步
Proxy Cache:
第一次有人用时再拉
也就是:
Eager vs Lazy。
二十九、Proxy Cache 最大优势:按需缓存
Docker Hub:
text
几百万镜像。
你公司真正使用:
text
可能只有 50 个。
完全没必要:
text
提前同步海量镜像。
Proxy Cache:
text
有人请求
↓
才缓存。
非常节省:
text
磁盘
流量
维护成本。
三十、什么时候应该提前同步?
例如公司关键基础镜像:
text
ubuntu
alpine
nginx
redis
mysql
openjdk
golang
node
你希望:
text
即使 Docker Hub 长时间不可用
这些镜像仍然:
text
100% 在内部 Registry。
那可以:
text
主动同步。
三十一、所以实际可以混合
例如:
text
关键镜像
↓
主动 Mirror
其他偶尔使用镜像:
text
↓
Proxy Cache
形成:
text
Harbor
├── base-images
│
│ 主动维护
│
└── dockerhub-cache
│
按需缓存
我认为这是非常合理的企业设计。
三十二、那么 registry-mirrors 和 Harbor Proxy Cache 有什么区别?
这是特别容易混淆的问题。
Docker Daemon:
json
{
"registry-mirrors": [
"https://mirror.example.com"
]
}
这里:
text
用户仍然:
docker pull nginx
Docker Daemon:
text
自动尝试 Mirror。
属于:
Docker Daemon 层透明代理。
Harbor Proxy Cache:
bash
docker pull \
harbor.example.com/dockerhub/library/nginx
镜像名:
text
发生了变化。
属于:
显式 Registry Namespace。
三十三、两者最大的区别
registry-mirrors:
text
使用方便
对业务透明
客户端配置依赖较强
Harbor:
text
地址明确
可控制
可做权限
可做审计
可做内部治理
企业环境下:
Harbor 的控制能力明显更强。
三十四、例如你能知道谁拉了什么镜像
公共 Mirror:
text
你基本控制不了。
Harbor:
text
User
Project
Repository
Artifact
都是你的基础设施。
可以:
text
统一认证
统一权限
统一审计
这就从:
text
"下载加速"
升级成:
Registry Governance。
三十五、为什么 Harbor 不只是一个缓存工具?
因为 Harbor 本身还有:
text
Project
RBAC
Robot Account
Replication
Retention
Artifact Management
等能力。
所以企业引入 Harbor 以后:
text
Public Image
和:
text
Company Image
可以放在同一套:
Container Registry Platform。
三十六、比如公司自己的镜像
text
harbor.example.com/company/api:v1
正常 Project。
Docker Hub 缓存:
text
harbor.example.com/dockerhub/library/nginx:latest
Proxy Cache Project。
结构非常清晰:
text
Harbor
│
├── company
│ ├── api
│ ├── web
│ └── worker
│
└── dockerhub
├── library/nginx
├── library/redis
└── library/golang
三十七、再结合前面讲的 Digest
Harbor 缓存:
text
Manifest
+
Layer
都基于:
text
Digest
组织。
如果:
text
nginx
和另外一个镜像:
text
共享相同 Layer
Registry 底层就天然适合:
text
内容去重与复用。
这也是为什么 Harbor Cache:
不等于复制大量重复 tar 包。
三十八、缓存最重要的问题:磁盘
现在假设:
text
Harbor
运行半年。
大家不停拉:
text
nginx
redis
node
python
golang
各种版本
缓存:
text
越来越大。
很可能:
text
几十 GB
↓
几百 GB
↓
几 TB。
所以一定要:
管理缓存生命周期。
三十九、Harbor Proxy Cache Project 有 Retention 概念
官方文档当前说明,新建 Proxy Cache Project 默认会创建一个 7 天的 Retention Policy,你也可以结合自己的使用需求调整保留策略。
这就非常重要。
例如:
text
过去 30 天
没有使用过的镜像
可以考虑:
text
清理。
四十、但 Retention 和 Garbage Collection 不完全一样
这个概念要分清。
Retention:
text
决定哪些 Artifact 应该保留。
Garbage Collection:
text
清理已经没有引用的 Blob。
类似:
text
删除数据库记录
不一定立即:
text
释放所有底层文件。
Registry 也有:
text
引用关系。
所以正式运维:
text
Retention
+
GC
通常都要考虑。
四十一、监控哪些指标?
如果让我运维 Harbor Proxy Cache,我至少关注:
text
磁盘使用率
Pull 请求量
Cache Hit
Cache Miss
上游请求失败
Harbor 可用性
Registry 延迟
尤其:
text
Disk Usage。
磁盘一旦:
text
100%
整个 Registry:
text
都会出问题。
四十二、Harbor 自己也可以启用内部 Cache Layer
这里要注意:
text
Harbor Proxy Cache
和:
text
Harbor Cache Layer
不是一回事。
Proxy Cache:
text
缓存外部 Registry 镜像。
Harbor Cache Layer:
text
缓存 Harbor 内部的一些资源和元数据,
减少重复请求处理。
官方当前配置说明中也单独提供了 Cache Layer 配置,高并发 Pull 场景下可以用于降低重复资源请求开销。
不要把两个"Cache"混了。
四十三、Harbor 本身最好也不要单点
如果公司所有 Kubernetes:
text
都依赖 Harbor。
但是 Harbor:
text
只有一台服务器。
这就变成:
Single Point of Failure。
Docker Hub 挂了:
text
你不怕。
Harbor 挂了:
text
所有 Node 都拉不到。
反而更麻烦。
四十四、正式环境至少考虑
text
Harbor 高可用
外部数据库
Redis
共享对象存储
Load Balancer
或者至少:
text
备份
+
快速恢复。
小团队不一定要:
text
一开始就 Kubernetes HA。
但一定要知道:
Harbor 已经成为核心基础设施。
四十五、另一个很重要的问题:Harbor 能不能走 HTTP 代理访问 Docker Hub?
可以从 Harbor 自身网络层配置:
text
http_proxy
https_proxy
no_proxy
官方 harbor.yml 当前提供对应配置项。
这意味着一个很现实的架构:
text
Internal Servers
↓
Harbor
↓
Outbound Proxy
↓
Docker Hub
这样:
text
只有 Harbor
需要处理复杂外网访问。
内部所有服务器:
text
完全不需要外网。
这个设计非常适合:
受控网络环境。
四十六、再进一步:服务器完全禁止访问 Docker Hub
防火墙:
text
Docker Nodes
❌ Internet
只允许:
text
Docker Nodes
↓
Harbor
然后:
text
Harbor
↓
Controlled Egress
↓
Docker Hub
这样网络安全策略非常清晰。
四十七、为什么这对企业安全也有帮助?
如果所有机器:
text
都能 docker pull 任意公网镜像
意味着开发者可能:
bash
docker pull randomuser/randomimage
生产服务器就运行了。
风险很高。
通过 Harbor:
text
统一入口
以后可以逐步建立:
text
镜像白名单
签名验证
漏洞扫描
权限
审计
这和我们上一篇:
text
Docker Supply Chain
正好接起来。
四十八、最终完整架构可以变成
text
Docker Hub
│
↓
Harbor Proxy Cache
│
┌──────────┼──────────┐
│ │ │
↓ ↓ ↓
CI Runner K8s Node Dev Server
Harbor 内部:
text
Proxy Cache
+
Private Registry
+
RBAC
+
Retention
+
Security Scan
形成:
统一镜像入口。
四十九、DockerHub 项目可以怎么和 Harbor 结合?
这就很有意思了。
你的:
text
Rodert/DockerHub
现在维护:
text
公共 Mirror 列表。
未来可以增加:
自建 Mirror 指南。
比如分三个层次:
text
方案 1
公共 Mirror
适合:
text
个人。
text
方案 2
Harbor Proxy Cache
适合:
text
团队 / 公司。
text
方案 3
Harbor + Mirror + Internal Registry
适合:
text
企业生产。
用户根据规模:
text
直接选方案。
五十、甚至可以做一个 Docker 镜像方案决策树
text
你有几台机器?
│
├── 1~3 台
│
│ ↓
│ Public Mirror
│
├── 5~50 台
│
│ ↓
│ Harbor Proxy Cache
│
└── 大规模生产
↓
Harbor HA
+
Proxy Cache
+
Internal Registry
+
Security Policy
这比:
text
只告诉大家 6 个 Mirror 地址
价值高很多。
五十一、自己测试 Harbor Cache 是否生效
第一台机器:
bash
time docker pull \
harbor.example.com/dockerhub/library/nginx:latest
记录:
text
第一次耗时。
然后删除本机:
bash
docker rmi \
harbor.example.com/dockerhub/library/nginx:latest
注意:
text
只是删除客户端本地镜像。
Harbor Cache:
text
仍然存在。
五十二、第二次重新拉
bash
time docker pull \
harbor.example.com/dockerhub/library/nginx:latest
如果:
text
第一次:
20 秒
第二次:
2 秒
说明:
text
Harbor 内网缓存
发挥作用。
当然具体时间:
text
取决于镜像大小和网络。
五十三、最好使用两台客户端验证
更真实:
text
Client A
↓
第一次拉
让 Harbor 缓存。
然后:
text
Client B
本地从来没有这个镜像。
执行:
bash
docker pull \
harbor.example.com/dockerhub/library/nginx
如果:
text
速度仍然很快。
就能确认:
快的不是 Client A 本地 Layer Cache。
而是:
Harbor Cache。
五十四、这个区别一定要注意
Docker 有:
text
客户端本地 Layer Cache。
Harbor 又有:
text
服务器端 Registry Cache。
两个完全不同。
结构:
text
Docker Host
├── Local Layers
│
└── Harbor
├── Registry Cache
│
└── Docker Hub
排查速度问题时:
text
一定要分清到底命中了哪层缓存。
五十五、CI 里最容易体现价值
每次 CI Runner:
text
可能都是新机器。
本地:
text
完全没有 Layer Cache。
但是 Harbor:
text
一直存在。
所以新 Runner:
text
也能享受 Registry Cache。
这就是:
Server-side Cache
比:
text
Local Docker Cache
覆盖范围更大的地方。
五十六、Harbor Proxy Cache 能不能 Push?
Proxy Cache Project 的定位是:
text
从上游 Registry 代理和缓存。
Harbor 官方当前说明中,Proxy Cache Project 不能像普通 Project 那样用于 Push。
所以:
text
公司自己构建的镜像
应该放:
text
普通 Project。
例如:
text
harbor.example.com/company/myapp:v1
而不是:
text
harbor.example.com/dockerhub/myapp:v1
五十七、项目命名最好一开始就分清
比如:
text
dockerhub
Proxy Cache。
text
ghcr
GitHub Container Registry Cache。
text
company
公司内部镜像。
text
base
公司基础镜像。
最终:
text
harbor.example.com/dockerhub/...
harbor.example.com/ghcr/...
harbor.example.com/company/...
harbor.example.com/base/...
一眼就知道:
镜像来自哪里。
五十八、Harbor Proxy Cache 不只支持 Docker Hub
当前 Harbor 官方文档列出的 Proxy Cache 上游包括 Docker Hub、Harbor、普通 Docker Registry,以及包括 AWS ECR、Azure Container Registry、Google Registry、GitHub Container Registry、JFrog Artifactory 等在内的多个 Registry 类型。
所以架构可以继续扩:
text
Docker Hub ──┐
GHCR ──┤
ECR ──┼→ Harbor
Quay ──┘
↓
Internal Clients
这就真正形成:
Registry Gateway。
五十九、以后 Agent / DevOps 平台也可以只认识 Harbor
比如 AI Agent 要部署项目:
text
需要 Redis
不要:
text
自己决定访问哪个公共 Mirror。
统一:
text
harbor.example.com/dockerhub/library/redis:7
这样:
text
Agent
CI
Kubernetes
Docker Host
全部:
使用同一个镜像入口。
这对未来自动化特别重要。
六十、这里还有一个非常实用的优化:预热
虽然 Proxy Cache:
text
按需缓存。
但是你知道:
text
今晚 8 点要部署 100 台机器。
用到:
text
node:22
nginx
redis
可以提前:
bash
docker pull \
harbor.example.com/dockerhub/library/node:22
bash
docker pull \
harbor.example.com/dockerhub/library/nginx:latest
bash
docker pull \
harbor.example.com/dockerhub/library/redis:7
先让 Harbor:
Cache Warm-up。
到了正式部署:
text
全部走内网。
六十一、这个思路甚至可以自动化
比如 GitOps:
text
扫描 Kubernetes YAML
↓
提取所有 image
↓
检查 Harbor Cache
↓
部署前预热
↓
开始 Rollout
例如 YAML:
yaml
image:
nginx:latest
系统自动:
text
nginx:latest
↓
Harbor
↓
提前 pull。
这叫:
Registry Prewarming。
对于大规模发布:
text
非常有价值。
六十二、甚至可以结合你的 DockerHub 项目做一个"镜像预热生成器"
用户输入:
text
nginx:latest
redis:7
mysql:8.4
golang:1.25
页面生成:
bash
docker pull \
harbor.example.com/dockerhub/library/nginx:latest
docker pull \
harbor.example.com/dockerhub/library/redis:7
docker pull \
harbor.example.com/dockerhub/library/mysql:8.4
docker pull \
harbor.example.com/dockerhub/library/golang:1.25
这样团队可以:
text
一键预热。
六十三、生产环境再加镜像固定
不要:
text
所有东西都 latest。
而是:
text
Harbor Proxy Cache
+
固定版本
+
Digest
例如:
text
redis:7.4.x
甚至:
text
redis@sha256:...
这样:
text
缓存
+
版本确定
同时具备。
六十四、再配合内部镜像策略
比如规定:
text
Production
禁止直接使用 docker.io
只允许:
text
harbor.example.com/*
这样:
text
所有生产镜像
都经过:
企业 Registry Gateway。
以后你想:
text
审计
限制
扫描
签名验证
都非常容易。
六十五、这就是为什么 Harbor 的价值远不只是"私有 Docker Hub"
很多教程把 Harbor 介绍成:
Docker 私有仓库。
没错。
但它真正更有意思的是:
text
内部 Registry
+
外部 Registry Gateway
+
Proxy Cache
+
Replication
+
RBAC
+
Artifact Governance
所以它其实更像:
企业容器镜像基础设施。
六十六、最后再对比三种方案
公共 Mirror
架构:
text
Docker
↓
Public Mirror
↓
Docker Hub
优点:
text
简单
免费
快速配置
缺点:
text
稳定性不可控
安全策略不可控
无法统一治理
适合:
text
个人开发。
Harbor Proxy Cache
text
Docker
↓
Your Harbor
↓
Docker Hub
优点:
text
缓存
稳定
统一入口
权限可控
内网加速
缺点:
text
需要服务器
需要磁盘
需要运维
适合:
text
团队。
Harbor + 企业供应链治理
text
Internet Registry
↓
Harbor
↓
Scan
↓
Signature / Policy
↓
Internal Registry
↓
Production
优点:
text
完整治理
缺点:
text
复杂度更高。
适合:
text
企业生产。
总结
很多人解决 Docker Hub 访问问题时,一直停留在:
text
找一个能用的镜像源。
今天:
text
Mirror A。
明天:
text
Mirror B。
后天:
text
Mirror C。
对于个人开发:
text
完全没问题。
但一旦:
text
服务器越来越多
CI/CD 越来越多
Kubernetes Node 越来越多
Docker Image 越来越多
这套方案就会越来越难维护。
更加工程化的路径应该是:
text
Docker Hub
↓
Harbor Proxy Cache
↓
内网统一 Registry
↓
Docker / CI / Kubernetes
第一次:
text
访问公网。
以后:
text
尽可能命中 Harbor Cache。
于是:
text
Docker Hub 网络问题
从:
每一台机器的问题
变成:
Harbor 这一台基础设施的问题。
这就是架构设计最重要的变化:
把分散的不稳定性,集中到一个你可以控制、监控和治理的节点。
对于你的:
text
https://github.com/Rodert/DockerHub
这个项目来说,我觉得整个内容路线现在已经非常清晰:
text
第一层
找公共镜像
↓
第二层
检测公共镜像
↓
第三层
理解 Manifest / Layer / Digest
↓
第四层
验证镜像可信性
↓
第五层
自建 Harbor Proxy Cache
↓
第六层
企业镜像供应链治理
这样这个项目就不只是:
Docker 镜像地址大全
而可以逐步变成:
一套从"小白解决 docker pull 失败"到"企业搭建镜像基础设施"的完整 Docker Registry 知识库。
项目地址:
text
https://github.com/Rodert/DockerHub
如果只记住一句话: