15-镜像仓库选型
镜像仓库是容器化部署的"中枢"——CI 构建出的镜像推到仓库,K8s 集群从仓库拉镜像部署。本章对比主流镜像仓库方案,重点讲 Harbor(开源自建首选)的 CI/CD 集成。
主流方案对比#
| 方案 | 类型 | 部署方式 | 安全扫描 | 多租户 | 适用场景 |
|---|---|---|---|---|---|
| Harbor | 开源 | 自建 | 内置 Trivy | 项目级 RBAC | 开源自建首选 |
| 阿里云 ACR | 云服务 | SaaS | 内置 | 企业版支持 | 阿里云生态、国内合规 |
| 腾讯 TCR | 云服务 | SaaS | 内置 | 企业版支持 | 腾讯云生态 |
| 华为 SWR | 云服务 | SaaS | 内置 | 支持 | 华为云生态 |
| Docker Hub | 云服务 | SaaS | 付费 | 弱 | 开源项目、个人 |
| quay.io | 云服务 | SaaS | 内置 | 支持 | Red Hat 生态 |
| GitHub Container Registry | 云服务 | SaaS | 内置 | 与 GitHub 集成 | GitHub 生态 |
关键维度对比#
| 维度 | Harbor | 阿里云 ACR | 腾讯 TCR | Docker Hub |
|---|---|---|---|---|
| 私有化 | ✓(开源自建) | ✗ | ✗ | ✗ |
| 国内访问 | 取决于自建位置 | 快 | 快 | 慢(需加速) |
| 安全扫描 | 内置 Trivy | 内置 | 内置 | 付费 |
| RBAC | 项目级 | 企业版 | 企业版 | 弱 |
| 镜像复制 | 支持 | 支持 | 支持 | ✗ |
| 成本 | 自建机器+存储 | 按量 | 按量 | 免费/付费 |
| 合规 | 自主可控 | 国内合规 | 国内合规 | 数据出境 |
Harbor:开源自建首选#
Harbor 是 CNCF 毕业的企业级容器镜像仓库,在国内自建场景占绝对主流。它的优势:
- 完全开源:CNCF 毕业,社区活跃
- 项目级 RBAC:多团队隔离
- 内置 Trivy 扫描:push 即扫描
- 镜像复制:跨区域同步
- LDAP/OIDC 集成:企业 SSO
- Helm Chart 仓库:一站式制品管理
核心组件#
text
┌─────────────────────────────────────────────────────────────┐
│ Harbor 架构 │
├─────────────┬──────────────┬──────────────┬─────────────────┤
│ Portal │ Core │ Registry │ JobService │
│ (前端 UI) │ (业务逻辑) │ (镜像存储) │ (异步任务队列) │
├─────────────┴──────────────┴──────────────┴─────────────────┤
│ PostgreSQL Redis │
│ (元数据存储) (缓存/会话/队列) │
├─────────────────────────────────────────────────────────────┤
│ Trivy(可插拔扫描器) │
└─────────────────────────────────────────────────────────────┘- Core:业务逻辑(认证、元数据、Webhook)
- Registry:底层用 Docker Distribution,负责镜像层存储
- JobService:异步任务(扫描、复制、GC)
- PostgreSQL:所有元数据
- Redis:任务队列和缓存
Helm 部署到 K8s#
yaml
# values.yaml 关键配置
expose:
type: ingress
tls:
enabled: true
secretName: harbor-tls
ingress:
hosts:
core: harbor.example.com
className: nginx
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "0" # 关键!允许大镜像上传
nginx.ingress.kubernetes.io/proxy-read-timeout: "900"
# S3 存储后端(推荐)
persistence:
imageChartStorage:
type: s3
s3:
region: us-west-2
bucket: harbor-registry-prod
accesskey: ${AWS_ACCESS_KEY}
secretkey: ${AWS_SECRET_KEY}
encrypt: true
# 副本数(HA)
core:
replicas: 2
jobservice:
replicas: 2
registry:
replicas: 2镜像安全扫描#
Harbor 2.x 默认内置 Trivy(2.0 起取代 Clair 成为默认扫描器,Clair 自 2.2 起降级为可选外部扫描器)。开启 scan on push:
text
Harbor UI → 项目 → 配置 → 自动扫描 ✓
→ 阻止有漏洞的镜像运行:Critical / High通过 API 批量配置:
bash
# 为所有项目开启扫描+阻断
for project_id in $(curl -s -u admin:Harbor12345 \
"https://harbor.example.com/api/v2.0/projects?page_size=100" | jq '.[].project_id'); do
curl -u admin:Harbor12345 -X PUT \
-H "Content-Type: application/json" \
"https://harbor.example.com/api/v2.0/projects/${project_id}" \
-d '{"metadata": {"prevent_vul": "true", "severity": "high", "auto_scan": "true"}}'
doneRobot Account(CI/CD 专用)#
每个 CI/CD 流水线用独立 Robot Account,不共享管理员账号。这是安全合规的基本要求——出了问题能追溯到哪条流水线、哪个时间点、哪个 token 操作的。
Robot Account 的权限模型:
- 项目级 Robot Account:限定单个项目的 push/pull,适合单服务流水线
- 系统级 Robot Account:跨项目操作,适合全局复制任务
bash
# 创建项目级 Robot Account
curl -u admin:Harbor12345 -X POST \
-H "Content-Type: application/json" \
"https://harbor.example.com/api/v2.0/projects/myproject/robots" \
-d '{
"name": "ci-pipeline",
"duration": 365,
"access": [
{"resource": "/project/myproject/repository", "action": "push"},
{"resource": "/project/myproject/repository", "action": "pull"}
]
}'
# 返回 token,只显示一次,立即存到 CI 变量轮换策略:Robot Account 设有效期(如 365 天),到期前 30 天创建新 token、更新 CI 变量、删除旧 token。用 CronJob 定期扫描即将过期的 Robot Account 并告警。
跨区域复制#
主仓库 → 多区域分发:
json
{
"name": "us-to-cn-sync",
"src_registry": {"id": 1},
"dest_registry": {"id": 2},
"dest_namespace": "production",
"filters": [
{"type": "name", "value": "production/**"},
{"type": "tag", "value": "v*"}
],
"trigger": {
"type": "scheduled",
"trigger_settings": {"cron": "0 2 * * *"}
}
}阿里云 ACR#
国内云厂商方案,分个人版和企业版:
个人版#
- 免费、配额小
- 无 SLA、无企业特性
- 适合个人项目、测试
企业版#
- 实例级别隔离(独享)
- 内置安全扫描、镜像签名
- 跨区域同步
- 与 ACK、RAM 深度集成
- 按量计费
bash
# 登录 ACR
docker login --username=<阿里云账号> goalfyai-acr-registry.cn-beijing.cr.aliyuncs.com
# 推送
docker tag myapp:v1 goalfyai-acr-registry.cn-beijing.cr.aliyuncs.com/prod/myapp:v1
docker push goalfyai-acr-registry.cn-beijing.cr.aliyuncs.com/prod/myapp:v1ACR 的优势#
- 国内访问快:阿里云骨干网
- 合规无忧:数据存储在国内
- 与 ACK 集成:免密拉镜像(RAM Role)
- CN 跨境场景:海外 ECR + 国内 ACR 双推,详见 09 章
腾讯 TCR / 华为 SWR#
特点与 ACR 类似,主要看团队用的云生态:
- 腾讯 TCR:与 TKE、腾讯云 IAM 集成
- 华为 SWR:与 CCE、华为云 IAM 集成
选型时优先选自己云生态的方案——免密拉镜像、统一权限管理是实在的好处。
Docker Hub / quay.io#
- Docker Hub:开源项目首选,免费但有限制(匿名拉取限流)。生产用建议付费
- quay.io:Red Hat 生态,企业特性完整
- GitHub Container Registry(ghcr.io):与 GitHub 深度集成,GitHub Actions 推镜像最方便
Harbor 的 CI/CD 集成#
GitLab CI#
yaml
# .gitlab-ci.yml
variables:
HARBOR_URL: harbor.example.com
HARBOR_PROJECT: production
IMAGE_TAG: ${HARBOR_URL}/${HARBOR_PROJECT}/${CI_PROJECT_NAME}:${CI_COMMIT_SHORT_SHA}
push-to-harbor:
stage: push
image: docker:24
services:
- docker:24-dind
before_script:
- echo ${HARBOR_ROBOT_TOKEN} | docker login ${HARBOR_URL} \
-u ${HARBOR_ROBOT_USER} --password-stdin
script:
- docker build -t ${IMAGE_TAG} .
- docker push ${IMAGE_TAG}
after_script:
- docker logout ${HARBOR_URL}
# 扫描检查(push 后等待扫描完成)
harbor-scan-check:
stage: scan
script:
- ./scripts/wait-for-scan.sh ${IMAGE_TAG}
allow_failure: false # 高危漏洞阻塞部署K8s 集群拉取镜像#
bash
# 创建 imagePullSecret
kubectl create secret docker-registry harbor-pull-secret \
--docker-server=harbor.example.com \
--docker-username='robot$myproject+ci-pull' \
--docker-password=<robot_token> \
--namespace=production
# 配置 ServiceAccount 默认使用
kubectl patch serviceaccount default -n production \
-p '{"imagePullSecrets": [{"name": "harbor-pull-secret"}]}'镜像保留策略#
防止历史版本无限积累:
text
Harbor UI → 项目 → 配置 → 镜像保留规则
规则:保留最近 10 个 v* tag + 永久保留 latest
Cron: 每周一凌晨 4 点执行通过 API:
bash
curl -u admin:Harbor12345 -X POST \
"https://harbor.example.com/api/v2.0/retentions" \
-d '{
"algorithm": "or",
"rules": [
{
"action": "retain",
"template": "latestPushedK",
"params": {"latestK": 10},
"tag_selectors": [{"pattern": "v*"}]
}
]
}'选型维度#
1. 数据合规和位置#
- 国内合规:ACR、TCR、SWR 或自建 Harbor
- 海外业务:Docker Hub、quay.io、自建 Harbor
- 跨境业务:海外 ECR + 国内 ACR 双仓库,Harbor 复制同步
2. 私有化需求#
- 必须私有化:Harbor(开源自建)
- 可以 SaaS:云厂商方案或 Docker Hub
3. 云生态#
- 阿里云:ACR 与 ACK 集成
- 腾讯云:TCR 与 TKE 集成
- 华为云:SWR 与 CCE 集成
- 多云/自建 K8s:Harbor
4. 安全要求#
- 需要 push 即扫描:Harbor、ACR 企业版、TCR 企业版
- 需要镜像签名:Harbor + Notary/Cosign
- 需要 RBAC:Harbor、企业版云服务
5. 规模和成本#
- 小规模(< 10 服务):个人版 ACR 或免费 Docker Hub
- 中规模(10-100 服务):企业版云服务或自建 Harbor
- 大规模(100+ 服务、跨区域):自建 Harbor + 跨区域复制
实战要点#
- 开源自建首选 Harbor。CNCF 毕业、社区活跃、功能完整。
- 国内云场景用对应云厂商的镜像仓库。免密拉镜像、统一权限管理是实在的好处。
- Robot Account 一项目一个。不要全公司共享一个管理员账号——出了问题没法追溯。
- 开启 scan on push。push 后立即扫描,高危漏洞在部署前被拦。
- 配置镜像保留策略。保留最近 N 个版本 + 永久保留
latest/v*,防止存储无限增长。 - 跨区域用复制功能。Harbor replication、ACR 企业版同步,比 CI 双推更省带宽。
proxy-body-size: "0"是 Nginx 反代 Harbor 的必备配置。否则大镜像上传会 413 错误。
小结#
镜像仓库选型本质是回答四个问题:数据在哪、要不要私有化、绑哪个云生态、安全要求多高。Harbor 是开源自建的事实标准;云厂商方案在对应云生态内有集成优势。
下一章讲制品仓库(不只是镜像,还有 npm/PyPI/Maven 包)和供应链安全——把镜像、Helm Chart、二进制包统一管理,并用 SBOM/SLSA 保证可追溯。