公共 Docker 镜像源总失效?用 Harbor Proxy Cache 自建 Docker Hub 镜像缓存

前面围绕这个项目:

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

如果只记住一句话:

公共 Mirror 解决的是"今天怎么拉下来",Harbor Proxy Cache 解决的是"以后所有机器怎么稳定地拉下来"。

相关推荐
智鸟科技GemeOpen开发者智能设备1 小时前
平安校园 AI 智能实时告警系统 智鸟科技·GemeOpen + 谷华科技·融合创新方案白皮书
java·开发语言·python·物联网·智能家居
自强的小白2 小时前
nacos配置中心面试题(导入配置的优先级),注意是如果后导入相同配置是以 后导入优先。外部入优先和nacos的数据隔离。
java·微服务
Wang's Blog2 小时前
Java框架 SpringCloud 快速入门: Feign 的自定义配置与日志级别
java·开发语言·spring cloud
成旭先生2 小时前
企业全景信息查询 API:工商照面 33 项、股东出资、变更与社保一次查全
java·开发语言·api接口·企业信息查询·工商数据·风控尽调·供应商准入
她的男孩2 小时前
分片上传的大文件人人可下载:文件模块 isPrivate 在合并时被抹成 false,另有 4 个静默坑
java·后端·架构
SWAGGY..2 小时前
【C++进阶】:(7)红黑树的原理与 C++ 实现:结构设计、插入调整及性质验证
android·java·开发语言·c++·算法
Wang's Blog3 小时前
Java框架 SpringCloud 快速入门: Eureka 服务发现与服务名调用改造
java·spring cloud·eureka
夕除3 小时前
redis--OpenResty
java·redis
YZ1225523 小时前
【Docker专题】使用Docker部署Vue-Flask项目前后端分离版【前端Docker部署】
前端·vue.js·docker