路线图

15-镜像仓库选型

星辉 2026-07-02 阅读 4 min 772 字 路线图
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腾讯 TCRDocker 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"}}'
done

Robot 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:v1

ACR 的优势#

  • 国内访问快:阿里云骨干网
  • 合规无忧:数据存储在国内
  • 与 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 保证可追溯。