3. Harbor 部署实战:Docker Compose 部署、Helm 部署、配置 HTTPS 与自签名证书

Harbor 的部署方式直接影响后续运维效率与安全合规性。本章聚焦三种主流部署路径:Docker Compose(适合 PoC 与中小规模)、Helm(适合 Kubernetes 原生环境)、以及HTTPS + 自签名证书(生产环境必备)。以下内容按“前置检查 → 部署步骤 → 证书配置 → 验证”的工程化顺序展开。

3.1 部署方式对比与选型建议

维度 Docker Compose Helm (Kubernetes)
适用场景 单机、测试、小团队(< 50 节点) K8s 集群、多租户、弹性扩缩
依赖组件 Docker Engine + docker-compose K8s 集群 + Helm 3 + StorageClass
升级复杂度 手动替换镜像、迁移数据目录 helm upgrade 滚动更新,回滚方便
高可用 需额外搭建主备或共享存储 原生多副本 + PV 多节点挂载
证书管理 挂载宿主机文件或 Docker secret K8s Secret + cert-manager 自动轮换
选型建议:若团队已运行 K8s 且希望利用原生调度与网络策略,优先选择 Helm 部署;若仅为内部开发或 CI 提供镜像存储,Docker Compose 可快速上线,后期再迁移至 K8s。

3.2 Docker Compose 部署 Harbor

3.2.1 环境准备

  • 操作系统:Ubuntu 22.04 / CentOS 7.9+
  • Docker Engine ≥ 20.10,docker-compose ≥ 2.20
  • 最低配置:4 vCPU、8 GB RAM、50 GB 可用磁盘

3.2.2 下载与配置

# 下载离线安装包(以 v2.10.0 为例)
wget https://github.com/goharbor/harbor/releases/download/v2.10.0/harbor-offline-installer-v2.10.0.tgz
tar -xzf harbor-offline-installer-v2.10.0.tgz
cd harbor

# 复制配置模板
cp harbor.yml.tmpl harbor.yml

# 编辑核心参数(以下为关键字段示例)
# hostname: registry.example.com
# http.port: 8080
# https.port: 443
# https.certificate: /data/cert/server.crt
# https.private_key: /data/cert/server.key
# harbor_admin_password: YourStrong!Passw0rd
# data_volume: /data/harbor

3.2.3 执行安装

# 运行安装脚本(自动拉取镜像并启动所有服务)
sudo ./install.sh

# 验证服务状态
docker-compose ps

# 输出示例(共 11 个服务)
# Name                  Command               State   Ports
# ------------------------------------------------------------
# harbor-core           /harbor/harbor_core   Up
# harbor-db             /docker-entrypoint …  Up      5432/tcp
# harbor-jobservice     /harbor/harbor_job…   Up
# harbor-log            /bin/sh -c …          Up      1514/tcp
# harbor-portal         nginx -g daemon off;  Up      8080/tcp
# nginx                 nginx -g daemon off;  Up      0.0.0.0:443->443/tcp
# redis                 redis-server …        Up      6379/tcp
# registry              /entrypoint.sh …      Up      5000/tcp
# registryctl           /harbor/start.sh …    Up
关键检查点:确保 harbor-core、nginx、registry 三个容器处于 Up 状态;若 harbor-core 反复重启,通常为数据库连接或证书路径错误。

3.3 Helm 部署 Harbor(Kubernetes 原生)

3.3.1 前置条件

  • K8s 集群 ≥ 1.24,已配置默认 StorageClass
  • Helm 3.8+ 已安装
  • Ingress Controller(如 nginx-ingress)已部署

3.3.2 添加 Helm 仓库与下载 Chart

helm repo add harbor https://helm.goharbor.io
helm repo update

# 拉取 Chart 到本地(便于定制 values)
helm pull harbor/harbor --version 1.14.0
tar -xzf harbor-1.14.0.tgz
cd harbor

3.3.3 核心 values.yaml 配置

# 以下为精简后的关键配置(完整文件约 400 行)
expose:
  type: ingress
  tls:
    enabled: true
    secretName: harbor-tls
  ingress:
    hosts:
      core: registry.example.com
    annotations:
      kubernetes.io/ingress.class: nginx

externalURL: https://registry.example.com

persistence:
  enabled: true
  persistentVolumeClaim:
    registry:
      size: 200Gi
    database:
      size: 20Gi
    jobservice:
      size: 10Gi

harborAdminPassword: "YourStrong!Passw0rd"

3.3.4 安装与验证

# 创建命名空间
kubectl create ns harbor

# 安装 Harbor
helm install harbor ./harbor \
  --namespace harbor \
  -f values.yaml

# 等待所有 Pod 就绪
kubectl wait --for=condition=Ready pods --all -n harbor --timeout=300s

# 查看暴露的 Ingress
kubectl get ingress -n harbor

# 输出示例
# NAME           HOSTS                  ADDRESS        PORTS     AGE
# harbor-ingress registry.example.com   192.168.1.100  80, 443   2m
注意:Helm 部署默认使用 postgresql-ha 子 Chart,会创建 3 个数据库副本。若资源有限,可在 values.yaml 中设置 database.type: internal 并调整副本数为 1。

3.4 配置 HTTPS 与自签名证书

生产环境必须启用 HTTPS。以下步骤适用于 Docker Compose 与 Helm 两种部署方式,证书生成部分通用。

3.4.1 生成自签名 CA 与服务器证书

# 1. 创建 CA 私钥
openssl genrsa -out ca.key 4096

# 2. 生成 CA 根证书(有效期 10 年)
openssl req -x509 -new -nodes -key ca.key \
  -sha256 -days 3650 \
  -subj "/CN=Harbor CA" \
  -out ca.crt

# 3. 创建服务器私钥
openssl genrsa -out server.key 2048

# 4. 生成证书签名请求(CSR)
openssl req -new -key server.key \
  -subj "/CN=registry.example.com" \
  -out server.csr

# 5. 创建扩展配置文件(含 SAN)
cat > server.ext << EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = registry.example.com
DNS.2 = harbor-core
IP.1 = 192.168.1.100
EOF

# 6. 使用 CA 签发服务器证书
openssl x509 -req -in server.csr \
  -CA ca.crt -CAkey ca.key -CAcreateserial \
  -out server.crt -days 365 \
  -sha256 -extfile server.ext

3.4.2 证书部署(Docker Compose)

# 将证书放入 Harbor 数据目录
mkdir -p /data/harbor/cert
cp server.crt server.key /data/harbor/cert/

# 修改 harbor.yml 中 https 段
# https:
#   port: 443
#   certificate: /data/harbor/cert/server.crt
#   private_key: /data/harbor/cert/server.key

# 重新生成配置并重启
sudo ./prepare
docker-compose down -v
docker-compose up -d

3.4.3 证书部署(Helm)

# 将证书创建为 K8s Secret
kubectl create secret tls harbor-tls \
  --cert=server.crt \
  --key=server.key \
  -n harbor

# 更新 values.yaml 中 tls 配置
# expose.tls.secretName: harbor-tls

# 升级 Helm Release
helm upgrade harbor ./harbor -n harbor -f values.yaml

3.4.4 客户端信任自签名 CA

所有需要推送/拉取镜像的节点,必须将 ca.crt 添加到 Docker 或 containerd 的信任列表:

# Docker 环境
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

# containerd 环境(K8s 节点)
sudo mkdir -p /etc/containerd/certs.d/registry.example.com
sudo cp ca.crt /etc/containerd/certs.d/registry.example.com/ca.crt
sudo systemctl restart containerd
验证 HTTPS:执行 curl -v https://registry.example.com/v2/ --cacert ca.crt,返回 200 且无证书错误即配置成功。

3.5 部署架构与证书流程总览

下图展示了 Docker Compose 与 Helm 两种部署模式下,HTTPS 证书的生成、分发与使用路径:

Harbor 部署架构与 HTTPS 证书流程 证书生成节点 openssl CA + 服务器证书 ca.crt / server.crt / server.key 有效期:CA 10年 / 服务端 1年 SAN:域名 + IP Docker Compose 部署 harbor.yml → ./prepare 证书挂载至 nginx 容器 docker-compose up -d 端口映射 443 → 容器 443 Helm 部署 (K8s) values.yaml → helm install 证书存为 K8s Secret Ingress 引用 Secret 自动负载均衡与滚动更新 客户端节点 Docker / containerd ca.crt 放入 certs.d docker login / pull / push curl --cacert 验证 TLS 双向验证 说明:证书生成后,Docker Compose 通过文件挂载注入 nginx;Helm 通过 K8s Secret 注入 Ingress。客户端均需信任同一 CA。

3.6 部署后快速验证清单

检查项 命令 / 方法 预期结果
Web UI 访问 浏览器打开 https://registry.example.com Harbor 登录页面,HTTPS 锁图标
Docker 登录 docker login registry.example.com Login Succeeded
镜像推送 docker push registry.example.com/library/nginx:latest 推送成功,无证书错误
API 健康检查 curl -k https://registry.example.com/api/v2.0/health 返回 {"status":"healthy"}
证书有效期 openssl x509 -in server.crt -text -noout | grep -A1 Validity Not Before / Not After 符合预期
常见故障:若 Docker 登录报 x509: certificate signed by unknown authority,说明客户端未正确放置 ca.crt;若报 tls: first record does not look like a TLS handshake,通常为 nginx 未正确加载证书或端口映射错误。

3.7 生产环境证书管理建议

  • 证书轮换:自签名证书有效期建议 ≤ 1 年,使用脚本或 cert-manager(K8s)自动续签。
  • 多域名支持:在 server.ext 的 [alt_names] 中添加多个 DNS 条目,避免为每个域名单独签发。
  • 备份策略:CA 私钥(ca.key)是信任根,必须离线加密备份;服务器私钥(server.key)建议使用 K8s External Secret 或 HashiCorp Vault 管理。
  • 监控告警:集成 Prometheus + Blackbox Exporter 对 Harbor 的 HTTPS 端点进行证书过期监控,提前 30 天告警。