Harbor 私有镜像仓库搭建指南(企业级 Docker Registry + 镜像扫描)

在企业级容器化实践中,仅使用 Docker Hub 或公共镜像仓库往往无法满足安全审计、访问控制和合规要求。Harbor 是 CNCF 毕业的开源企业级镜像仓库项目,在原生 Docker Registry 基础上提供了基于角色的访问控制(RBAC)、镜像漏洞扫描(集成 Trivy)、镜像签名验证、仓库复制同步、Helm Chart 仓库,以及详细的操作审计日志,是搭建私有镜像仓库的首选方案。

本文将带你从零开始,使用 Docker Compose 在单台服务器上完整部署 Harbor,配置 HTTPS、镜像扫描策略,并演示如何将其接入 Kubernetes 集群拉取私有镜像。


环境要求

Harbor 组件较多(Portal、Core、JobService、Registry、Database、Redis、Trivy 等),生产环境推荐预留充足资源:

组件 最低配置 推荐配置
CPU 2 核 4 核
内存 4 GB 8 GB
系统盘 40 GB 60 GB SSD
镜像存储盘 100 GB+ 500 GB+(取决于镜像数量)
操作系统 Ubuntu 22.04 LTS Ubuntu 22.04 LTS
Docker 24.0+ 24.0+
Docker Compose v2.20+ v2.20+

Harbor 存储镜像需要大磁盘,推荐使用雨云服务器 rainyun-com的 4 核 8GB 机型并挂载额外数据盘。注册填优惠码 2026off 领 5 折优惠券,雨云支持灵活的磁盘扩容,可以根据镜像存储增长按需扩充,是搭建企业私有镜像仓库的经济实惠选择。

检查环境就绪:

docker version
# Client: Docker Engine - Community
#  Version: 26.1.0

docker compose version
# Docker Compose version v2.27.0

# 确认域名解析正常(Harbor 强烈建议使用域名+HTTPS)
ping registry.example.com

安装准备

准备 SSL 证书

Harbor 需要 HTTPS,有两种方式获取证书:

方式一:使用 Let’s Encrypt 免费证书(推荐,域名可公网解析时使用)

# 安装 certbot
apt-get install -y certbot

# 申请证书(需要域名指向本机 IP)
certbot certonly --standalone \
  -d registry.example.com \
  --email admin@example.com \
  --agree-tos --non-interactive

# 证书位置
# /etc/letsencrypt/live/registry.example.com/fullchain.pem
# /etc/letsencrypt/live/registry.example.com/privkey.pem

方式二:自签证书(内网或测试环境)

mkdir -p /data/harbor/certs && cd /data/harbor/certs

# 生成 CA 私钥和证书
openssl genrsa -out ca.key 4096
openssl req -x509 -new -nodes -sha512 -days 3650 \
  -subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/CN=registry.example.com" \
  -key ca.key \
  -out ca.crt

# 生成服务器私钥
openssl genrsa -out registry.example.com.key 4096

# 生成证书签名请求
openssl req -sha512 -new \
  -subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/CN=registry.example.com" \
  -key registry.example.com.key \
  -out registry.example.com.csr

# 生成 x509 v3 扩展文件
cat > v3.ext <<EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

[alt_names]
DNS.1=registry.example.com
DNS.2=localhost
IP.1=<your-server-ip>
EOF

# 用 CA 签发服务器证书
openssl x509 -req -sha512 -days 3650 \
  -extfile v3.ext \
  -CA ca.crt -CAkey ca.key -CAcreateserial \
  -in registry.example.com.csr \
  -out registry.example.com.crt

下载 Harbor 安装包

# 查看最新版本
HARBOR_VERSION="v2.11.0"

wget -q https://github.com/goharbor/harbor/releases/download/${HARBOR_VERSION}/harbor-online-installer-${HARBOR_VERSION}.tgz

tar xzvf harbor-online-installer-${HARBOR_VERSION}.tgz
cd harbor

部署步骤

第一步:配置 harbor.yml

cp harbor.yml.tmpl harbor.yml

编辑关键配置项:

# harbor.yml

# Harbor 访问地址
hostname: registry.example.com

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

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

# 数据库配置
database:
  password: root123
  max_idle_conns: 100
  max_open_conns: 900

# 数据存储路径(镜像存储在此目录,确保磁盘空间充足)
data_volume: /data/harbor/data

# Trivy 漏洞扫描配置
trivy:
  ignore_unfixed: false         # false: 报告所有漏洞
  skip_update: false            # 每次启动时更新漏洞数据库
  offline_scan: false
  security_check: vuln
  insecure: false

# 日志配置
log:
  level: info
  local:
    rotate_count: 50
    rotate_size: 200m
    location: /var/log/harbor

# 代理配置(如需通过代理拉取漏洞数据库)
# proxy:
#   http_proxy: http://proxy.example.com:8080
#   https_proxy: http://proxy.example.com:8080
#   no_proxy: 127.0.0.1,localhost,registry.example.com

第二步:执行安装脚本

# 安装并启用所有组件(包括 Trivy 漏洞扫描)
sudo ./install.sh --with-trivy

# 期望输出:
# ✔ ----Harbor has been installed and started successfully.----

第三步:验证服务状态

docker compose ps
# NAME                COMMAND                  SERVICE    STATUS         PORTS
# harbor-core         "/harbor/entrypoint.…"   core       Up (healthy)
# harbor-db           "/docker-entrypoint.…"   postgresql Up (healthy)
# harbor-jobservice   "/harbor/entrypoint.…"   jobservice Up (healthy)
# harbor-log          "/bin/sh -c /usr/loc…"   log        Up (healthy)
# harbor-portal       "nginx -g 'daemon of…"   portal     Up (healthy)
# harbor-redis        "redis-server /etc/r…"   redis      Up (healthy)
# harbor-registryctl  "/home/harbor/start.…"   registryctl Up (healthy)
# nginx               "nginx -g 'daemon of…"   proxy      Up (healthy)   0.0.0.0:443->8443/tcp
# registry            "/home/harbor/entryp…"   registry   Up (healthy)
# trivy-adapter       "/home/scanner/entryp…"  trivy      Up (healthy)

浏览器访问 https://registry.example.com,使用 admin / Harbor12345 登录。

第四步:创建项目和用户

通过 Web UI 或 Harbor API 创建:

# 使用 API 创建私有项目
curl -u "admin:Harbor12345" \
  -X POST "https://registry.example.com/api/v2.0/projects" \
  -H "Content-Type: application/json" \
  -d '{
    "project_name": "myapp",
    "public": false,
    "metadata": {
      "auto_scan": "true",
      "prevent_vul": "true",
      "severity": "high"
    }
  }'

# 创建机器人账号(供 CI/CD 使用)
curl -u "admin:Harbor12345" \
  -X POST "https://registry.example.com/api/v2.0/projects/myapp/robots" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "ci-bot",
    "description": "CI/CD Pipeline Robot",
    "duration": 365,
    "permissions": [
      {
        "kind": "project",
        "namespace": "myapp",
        "access": [
          {"resource": "repository", "action": "pull"},
          {"resource": "repository", "action": "push"},
          {"resource": "tag", "action": "delete"}
        ]
      }
    ]
  }'

第五步:推送镜像到 Harbor

# 客户端机器信任证书(自签证书场景)
sudo mkdir -p /etc/docker/certs.d/registry.example.com
sudo cp ca.crt /etc/docker/certs.d/registry.example.com/ca.crt
sudo systemctl restart docker

# 登录 Harbor
docker login registry.example.com -u admin -p Harbor12345

# 标记并推送镜像
docker pull nginx:1.25
docker tag nginx:1.25 registry.example.com/myapp/nginx:1.25
docker push registry.example.com/myapp/nginx:1.25

# Harbor 会自动触发 Trivy 扫描

第六步:接入 Kubernetes 集群

# 创建 imagePullSecret
kubectl create secret docker-registry harbor-secret \
  --docker-server=registry.example.com \
  --docker-username=robot\$ci-bot \
  --docker-password=<robot-token> \
  --namespace default

# 在 Deployment 中引用
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      imagePullSecrets:
        - name: harbor-secret   # 引用 Secret
      containers:
        - name: myapp
          image: registry.example.com/myapp/nginx:1.25
          ports:
            - containerPort: 80
EOF

配置说明

镜像扫描策略

在 Harbor Web UI 中配置自动扫描和阻断策略:

  1. 进入项目 → 配置管理 → 安全策略
  2. 开启"自动扫描镜像":推送后立即触发 Trivy 扫描
  3. 开启"阻止潜在漏洞镜像":选择阻断级别(Critical/High/Medium)
  4. 配置后,含有 High 以上漏洞的镜像将无法被拉取

仓库复制(镜像同步)

Harbor 支持将镜像同步到其他 Registry(包括另一个 Harbor、Docker Hub、GCR、ECR):

  1. 系统管理 → 仓库管理 → 新建目标
  2. 复制管理 → 新建规则
  3. 设置触发策略(手动/事件驱动/定时)

垃圾回收

定期清理未引用的 Blob,释放磁盘空间:

# 通过 API 触发 GC
curl -u "admin:Harbor12345" \
  -X POST "https://registry.example.com/api/v2.0/system/gc/schedule" \
  -H "Content-Type: application/json" \
  -d '{"schedule":{"type":"Manual"}}'

验证测试

验证 Trivy 扫描结果

# 查看镜像扫描报告(API)
curl -u "admin:Harbor12345" \
  "https://registry.example.com/api/v2.0/projects/myapp/repositories/nginx/artifacts/1.25/scan/report?mime_type=application/vnd.scanner.adapter.vuln.report.harbor%2Bjson%3Bversion%3D1.0" \
  | jq '.vulnerabilities | group_by(.severity) | map({severity: .[0].severity, count: length})'

验证访问控制

# 使用未授权账号尝试拉取私有镜像(应失败)
docker logout registry.example.com
docker pull registry.example.com/myapp/nginx:1.25
# Error response from daemon: pull access denied

# 使用机器人账号拉取(应成功)
docker login registry.example.com \
  -u "robot\$ci-bot" -p <robot-token>
docker pull registry.example.com/myapp/nginx:1.25

常见问题

Q:Harbor 启动后无法访问,502 Bad Gateway?

# 检查 nginx 代理容器日志
docker logs nginx

# 通常是证书路径配置错误,或证书文件权限不足
ls -la /data/harbor/certs/
chmod 644 /data/harbor/certs/*.crt
chmod 600 /data/harbor/certs/*.key

Q:Trivy 无法更新漏洞数据库(网络问题)?

# 在 harbor.yml 中配置代理
proxy:
  http_proxy: http://your-proxy:7890
  https_proxy: http://your-proxy:7890
  no_proxy: 127.0.0.1,localhost,registry.example.com

# 或开启离线扫描模式,手动导入漏洞数据库
trivy:
  offline_scan: true

Q:磁盘满了,如何快速清理?

# 先在 Web UI 中删除不需要的镜像标签
# 然后执行垃圾回收
docker compose exec core sh -c "curl -s http://localhost:8080/api/v2.0/system/gc/schedule \
  -X POST -u admin:Harbor12345 \
  -H 'Content-Type: application/json' \
  -d '{\"schedule\":{\"type\":\"Manual\"}}'"

# 监控 GC 进度
docker logs harbor-jobservice | grep -i gc

Q:Kubernetes 拉取镜像失败 ErrImagePull

# 检查 Secret 是否正确
kubectl get secret harbor-secret -o jsonpath='{.data.\.dockerconfigjson}' | base64 -d | jq

# 在节点上测试拉取
docker pull registry.example.com/myapp/nginx:1.25

# 确认节点信任了 Harbor 的证书
ls /etc/docker/certs.d/registry.example.com/

Harbor 作为 CNCF 毕业项目,已在金融、互联网等行业的大规模生产环境中得到充分验证,是企业私有镜像仓库的不二之选。由于 Harbor 包含多个组件且镜像存储需要大容量磁盘,推荐使用雨云服务器 rainyun-com的 4 核 8GB 机型,并根据镜像规模挂载额外数据盘,注册填写优惠码 2026off 即可领取 5 折优惠券,以实惠的价格获得稳定可靠的云服务器资源,构建企业级私有镜像管理基础设施。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐