Harbor 实例部署

本文档介绍 Harbor Operator 的订阅及基于 Harbor 实例部署的功能。

命名空间安全策略限制

由于以下原因,Harbor 不支持在 SPA(Security Policy Admission)策略设置为 Restricted 的命名空间中部署:

  1. Init 容器需要 root 权限:Harbor 使用 init 容器初始化 PVC 目录权限,需 root 权限,而 Restricted 策略不允许。

建议:为 Harbor 部署创建专用命名空间,且确保其安全策略设置为 Restricted。当使用 hostPath 存储部署 Harbor 时,命名空间安全策略必须配置为 Privileged

前置条件

  • 本文档适用于平台提供的 Harbor 2.14 及以上版本,基于 Operator 等技术与平台解耦。

  • 请确保目标集群已部署(订阅)Harbor Operator,即 Harbor Operator 已准备好创建实例。

部署规划

Harbor 支持多种资源配置以满足不同客户场景。不同场景下所需资源和配置差异较大,因此本节介绍部署 Harbor 实例前需要考虑的方面及决策点的影响,帮助用户基于此信息进行后续具体实例部署。

基础信息

  1. 平台提供的 Harbor Operator 基于社区官方 Harbor Operator,具备企业级能力增强,如 ARM 支持和安全漏洞修复。功能上与社区版完全兼容,体验上通过可选和可定制模板提升 Harbor 部署便利性。

  2. 一个 Harbor 实例包含多个组件,如负责管理镜像文件的 Registry 组件,提供应用元数据和用户信息存储的 PostgreSQL 组件,以及用于缓存的 Redis 组件等。平台提供专业的 PostgreSQL Operator 和 Redis Operator,部署 Harbor 实例时不再直接部署 Redis 和 PostgreSQL 资源,而是通过配置已有实例的访问凭证进行访问。

部署前资源规划

部署前资源规划指部署前需做出的决策,并在部署时生效。主要内容包括:

高可用

  • Harbor 支持高可用部署,主要影响和限制如下:

    • 各组件将使用多个副本

    • 网络访问不再支持 NodePort,需通过 Ingress 配置的域名访问

    • 存储方式不再支持 节点存储,需通过 StorageClassPVC 访问

资源

根据社区建议和实践,非高可用 Harbor 实例最低可用 2 核 4Gi 资源,高可用模式下稳定运行最低需 8 核 16Gi 资源。

存储

存储选择指南
组件支持的存储类型说明
Registry对象存储(如 MinIO)
文件存储(如 Ceph FS)
高并发拉取镜像场景建议使用对象存储并开启重定向功能。
存储磁盘的顺序读写吞吐量(1 MB 块大小)不应低于 100 MiB/s。
JobService文件存储(如 Ceph FS)任务日志也可存储在数据库,此时无需为任务服务配置存储。
Trivy文件存储(如 Ceph FS)存储漏洞数据库和缓存;持久化为可选。
不持久化时使用 emptyDir,重启时重新下载数据库,扫描暂时中断。
  • 平台提供的常用存储方式均可用于 Harbor,如存储类、持久卷声明、节点存储等。

  • 若有意跳过 Trivy 持久化,保持 spec.helmValues.persistence.persistentVolumeClaim.trivy.storageClass 不设置。漏洞数据库将存于 emptyDir 卷,Trivy Pod 每次重启都会重新下载数据库并阻塞漏洞扫描直至完成。

  • 节点存储不适用于 高可用 模式,因为其文件存储在宿主节点指定路径。

  • 此外,Harbor 支持对象存储,配置说明见使用对象存储作为 Registry 存储后端

不要使用 NFS 作为存储后端

不建议在 Harbor 生产环境高负载场景(如大规模镜像推拉或高并发镜像工作负载)中使用 NFS 作为存储后端。由于协议特性,NFS 无法完全满足 Harbor Registry 的元数据密集型操作需求,重负载下常导致制品上传失败,可能出现如下错误:

  • digest invalid: provided digest did not match uploaded content
  • blob upload unknown
  • blob upload invalid

若在测试环境仍想使用 NFS,建议在 NFS 服务器启用 syncno_wdelay(具体配置请咨询存储提供商),且将 Registry 组件副本数设置为 1,可缓解上述问题。

网络

  • 平台提供两种主流网络访问方式:NodePortIngress

    • NodePort 需指定 HTTP 和 SSH 端口,确保端口可用。NodePort 不适用于 高可用 模式。

    • Ingress 需指定域名,确保域名解析正常。

  • 平台支持 HTTPS 协议,需实例部署后配置,详情见配置 HTTPS

Redis

Redis 组件存储选择指南

建议使用块存储(如 TopoLVM)以获得更高 IOPS 和更低延迟。

PostgreSQL

PostgreSQL 组件存储选择指南

建议使用块存储(如 TopoLVM)以获得更高 IOPS 和更低延迟。

账号凭证

初始化 Harbor 实例时需配置管理员账号及密码,通过配置 secret 资源实现,详见配置 Redis、PostgreSQL 和账号访问凭证

部署后配置规划

部署后配置规划指无需部署前决策,可通过标准化操作按需变更的规划,主要包括单点登录(SSO)、HTTPS 配置、外部负载均衡配置等,详情见后续操作

实例部署

平台提供的 Harbor Operator 主要支持两种部署方式:模板部署和 YAML 部署。

平台内置两种模板供使用:Harbor 快速启动模板和Harbor 高可用模板,同时支持自定义模板以满足特定客户场景。

内置模板及 YAML 部署信息如下:

使用 Harbor 快速启动 模板部署

该模板用于快速创建适合开发测试场景的轻量级 Harbor 实例,不推荐用于生产环境。

  • 计算资源:CPU 2 核,内存 4Gi
  • 存储方式:使用本地节点存储,需配置存储节点 IP 和路径
  • 网络访问:使用 NodePort 方式,节点 IP 与存储共享,需指定端口
  • 依赖服务:需配置已有 Redis 和 PostgreSQL 访问凭证
  • 其他设置:需配置账号凭证,默认关闭 SSO 功能

根据模板提示填写相关信息完成部署。

使用 Harbor 高可用 模板部署

部署高可用 Harbor 实例需更高资源配置,提供更高可用标准。

  • 计算资源:CPU 16 核,内存 16 Gi
  • 存储方式:使用存储类资源存储镜像文件、后台任务日志和镜像扫描漏洞数据库
  • 网络访问:使用 Ingress 方式,需指定域名
  • 依赖服务:需配置已有 Redis 和 PostgreSQL 访问凭证
  • 其他设置:需配置账号凭证,默认关闭 SSO 功能

实现 Harbor 高可用,外部依赖需满足:

  1. RedisPostgreSQL 实例必须高可用
  2. 网络负载均衡器必须高可用;使用 ALB 时需配置 VIP
  3. 集群节点数需超过 2 个

根据模板提示填写相关信息完成部署。

使用 Harbor 对象存储 模板部署

基于对象存储部署 Harbor 实例。

  • 计算资源:8 CPU 核,16 Gi 内存
  • 存储:镜像文件使用对象存储,后台任务日志使用数据库存储
  • 网络访问:使用 Ingress 访问服务,指定域名
  • 依赖:配置已有 Redis 和 PostgreSQL 访问凭证,另需为 Gitaly 组件在 PG 实例中单独配置独立数据库访问凭证
  • 其他设置:配置账号凭证,默认关闭 SSO 功能

该模板中 Trivy 扫描器不持久化数据,挂载 emptyDir,每次 Pod 重启都会重新下载漏洞数据库,暂时阻塞新扫描直至同步完成。

请确保所提供的对象存储凭证具备所需的 S3 API 权限,详见对象存储凭证

根据模板提示填写相关信息完成部署。

使用 YAML 部署

YAML 部署是最基础且强大的部署能力。这里提供 部署规划 各维度对应的 YAML 片段,并提供两个完整场景的 YAML 示例,帮助用户理解 YAML 配置方式并按需修改配置。

高可用(YAML 片段)

高可用模式下,Harbor 组件副本数应至少为 2。YAML 配置片段如下:

spec:
  helmValues:
    core:
      replicas: 2
    portal:
      replicas: 2
    jobservice:
      replicas: 2
    registry:
      replicas: 2

存储(YAML 片段)

Harbor 数据存储主要包括三部分:

  • Registry:管理和存储容器镜像及制品,负责镜像上传、下载和存储操作。
  • Jobservice:执行后台任务,如镜像跨 Registry 复制、垃圾回收及其他定时或按需任务。
  • Trivy:对容器镜像进行漏洞扫描,识别安全问题,确保符合安全策略。

目前支持三种存储配置方式:存储类、PVC 和本地节点存储。使用存储类或 PVC 时,存储必须支持多节点读写(ReadWriteMany)。

Registry 还支持使用对象存储(S3)作为存储后端。

Jobservice 支持将任务日志存储在多个位置(文件、数据库、标准输出)。若未选择将任务日志输出到文件,则无需为 Jobservice 配置存储后端。详情见配置任务日志存储

存储类配置示例:

spec:
  helmValues:
    persistence:
      enabled: true
      persistentVolumeClaim:
        registry:
          storageClass: ceph
          accessMode: ReadWriteMany
          size: 10Gi
        jobservice:
          jobLog:
            storageClass: ceph
            accessMode: ReadWriteMany
            size: 1Gi
        trivy:
          storageClass: ceph
          accessMode: ReadWriteMany
          size: 5Gi

PVC 配置示例(PVC 需提前创建):

spec:
  helmValues:
    harbor:
      persistence:
        enabled: true
        persistentVolumeClaim:
          registry:
            existingClaim: <registry 组件 pvc>
          jobservice:
            jobLog:
              existingClaim: <jobservice 组件 pvc>
          trivy:
            existingClaim: <trivy 组件 pvc>

本地节点存储配置示例:

spec:
  helmValues:
    persistence:
      enabled: true
      hostPath:
        registry:
          path: <registry 组件节点存储路径>
        jobservice:
          path: <jobservice 组件节点存储路径>
        trivy:
          path: <trivy 组件节点存储路径>
    registry:
      nodeSelector:
        kubernetes.io/hostname: <节点名称>
    jobservice:
      nodeSelector:
        kubernetes.io/hostname: <节点名称>
    trivy:
      nodeSelector:
        kubernetes.io/hostname: <节点名称>

配置对象存储(S3)作为 Registry 存储后端:

  • 使用 Amazon S3 或兼容 S3 的对象存储服务,如 MinIO、Ceph。

  • 对象存储桶需提前创建。

  • <object-storage-secret> Secret 需提前创建。

    spec:
      helmValues:
        harbor:
          persistence:
            enabled: true
            imageChartStorage:
              disableredirect: true
              s3:
                existingSecret: <object-storage-secret>
                bucket: <bucket>
                region: <region>
                regionendpoint: <regionendpoint>
                v4auth: true
              type: s3
            persistentVolumeClaim:
              jobservice:
                jobLog:
                  existingClaim: <jobservice 组件 pvc>
              trivy:
                existingClaim: <trivy 组件 pvc>
字段说明示例值
object-storage-secret包含 S3 访问密钥和密钥的 Secret,详见对象存储凭证object-storage-secret
bucket对象存储桶名称,需提前创建harbor-registry
regionendpoint对象存储服务端点 URL(如需包含端口)http://192.168.133.37:32227
region对象存储区域(MinIO 通常为 us-east-1us-east-1
disableredirect设置为 false 启用重定向以提升拉取性能。Harbor 会返回临时 S3 URL 供层下载,客户端必须能访问 S3 端点,否则层下载失败。true

详情见 S3 存储驱动

若需在平台使用 Ceph,请参考 Ceph 分布式存储

INFO

Harbor 当前仅支持配置 Registry 组件使用 S3 存储,其他组件仍使用 PVC 或 StorageClass 进行持久化存储。

网络访问(YAML 片段)

网络访问主要包括两种方式:域名访问和 NodePort 访问。

域名访问配置示例:

spec:
  helmValues:
    expose:
      type: ingress
      tls:
        enabled: false
      ingress:
        hosts:
          core: <域名>

    externalURL: http://<域名>

NodePort 访问配置示例:

spec:
  helmValues:
    expose:
      type: nodePort
      nodePort:
        name: harbor
        ports:
          http:
            port: 80
            nodePort: <端口号>

    externalURL: http://<节点 IP>:<端口号>

Redis 访问凭证配置

指在配置 Redis 凭证 secret 资源后,在 Harbor 实例中配置这些凭证的 YAML 片段:

独立 Redis 示例:

spec:
  helmValues:
    database:
    redis:
      external:
        addr: "<redis 访问地址>:<redis 端口>"
        existingSecret: <存储 redis 密码的 secret>
        existingSecretKey: password
      type: external

Sentinel 示例:

spec:
  helmValues:
    database:
    redis:
      external:
        addr: "<sentinel1 访问地址>:<sentinel1 端口>,<sentinel2 访问地址>:<sentinel2 端口>,<sentinel3 访问地址>:<sentinel3 端口>"
        sentinelMasterSet: mymaster
        existingSecret: <存储 redis 密码的 secret>
        existingSecretKey: password
      type: external

PostgreSQL 访问凭证配置

指在配置 PostgreSQL 凭证 secret 资源后,在 Harbor 实例中配置这些凭证的 YAML 片段:

spec:
  helmValues:
    database:
      external:
        host: <postgresql 访问地址>
        port: <postgresql 端口>
        sslmode: <是否启用 ssl>
        username: <postgresql 用户名>
        coreDatabase: <数据库名>
        existingSecret: <存储 postgresql 密码的 secret>
      type: external

管理员账号配置

指在配置账号凭证 secret 资源后,在 Harbor 实例中配置这些凭证的 YAML 片段:

spec:
  helmValues:
    existingSecretAdminPassword: <存储 harbor 管理员密码的 secret>
    existingSecretAdminPasswordKey: password

完整 YAML 示例:单实例,节点存储,NodePort 网络访问


spec:
  helmValues:
    existingSecretAdminPassword: harbor-password # 存储 harbor 管理员账号密码的 Secret
    existingSecretAdminPasswordKey: password # 存储 harbor 管理员账号密码的 Secret key
    externalURL: http://192.168.142.11:32001 # Harbor 访问地址
    expose:
      nodePort:
        name: harbor
        ports:
          http:
            nodePort: 32001 # Harbor 节点端口号
            port: 80
      type: nodePort
    persistence:
      enabled: true
      hostPath:
        jobservice:
          path: /data/harbor/jobservice # Jobservice 组件节点存储路径
        registry:
          path: /data/harbor/registry # Registry 组件节点存储路径
        trivy:
          path: /data/harbor/trivy # Trivy 组件节点存储路径
    portal:
      resources:
        request:
          cpu: 100m
          memory: 128Mi
        limit:
          cpu: 200m
          memory: 256Mi
    nginx:
      resources:
        request:
          cpu: 100m
          memory: 128Mi
        limit:
          cpu: 200m
          memory: 256Mi
    core:
      resources:
        request:
          cpu: 200m
          memory: 256Mi
        limit:
          cpu: 400m
          memory: 512Mi
    registry:
      nodeSelector:
        kubernetes.io/hostname: 192.168.142.11 # Registry 组件节点选择器
      resources:
        request:
          cpu: 200m
          memory: 512Mi
        limit:
          cpu: 400m
          memory: 1Gi
    jobservice:
      nodeSelector:
        kubernetes.io/hostname: 192.168.142.11 # Jobservice 组件节点选择器
      resources:
        request:
          cpu: 200m
          memory: 256Mi
        limit:
          cpu: 400m
          memory: 512Mi
    trivy:
      skipUpdate: true
      offlineScan: true
      nodeSelector:
        kubernetes.io/hostname: 192.168.142.11 # Trivy 组件节点选择器
      resources:
        request:
          cpu: 200m
          memory: 512Mi
        limit:
          cpu: 400m
          memory: 1Gi
    database:
      external:
        host: harbor-database # 数据库访问地址
        port: 5432 # 数据库端口号
        sslmode: require # 是否启用 SSL
        username: harbor # 数据库用户名
        coreDatabase: registry # 数据库名
        existingSecret: harbor-database # 存储数据库密码的 Secret
        existingSecretKey: password # 存储数据库密码的 Secret key
      type: external
    redis:
      external:
        addr: harbor-redis:6379 # Redis 访问地址和端口号
        existingSecret: harbor-redis # 存储 Redis 密码的 Secret
        existingSecretKey: password # 存储 Redis 密码的 Secret key
      type: external

完整 YAML 示例:高可用,存储类,Ingress 网络访问

spec:
  helmValues:
    existingSecretAdminPassword: harbor-password # 存储 harbor 管理员账号密码的 Secret
    existingSecretAdminPasswordKey: password # 存储 harbor 管理员账号密码的 Secret key
    externalURL: http://harbor.example.com # Harbor 访问地址
    expose:
      type: ingress
      tls:
        enabled: false
      ingress:
        hosts:
          core: harbor.example.com # Harbor 域名
    persistence:
      enabled: true
      persistentVolumeClaim:
        registry:
          storageClass: ceph # Registry 组件存储类
          accessMode: ReadWriteMany
          size: 10Gi # Registry 组件存储大小
        jobservice:
          jobLog:
            storageClass: ceph # Jobservice 组件存储类
            accessMode: ReadWriteMany
            size: 1Gi # Jobservice 组件存储大小
        trivy:
          storageClass: ceph # Trivy 组件存储类
          accessMode: ReadWriteMany
          size: 5Gi # Trivy 组件存储大小
    portal:
      replicas: 2 # Portal 组件副本数
      resources:
        request:
          cpu: 200m
          memory: 256Mi
        limit:
          cpu: 400m
          memory: 512Mi
    core:
      replicas: 2 # Core 组件副本数
      resources:
        request:
          cpu: 200m
          memory: 256Mi
        limit:
          cpu: 400m
          memory: 512Mi
    registry:
      replicas: 2 # Registry 组件副本数
      resources:
        request:
          cpu: 400m
          memory: 1Gi
        limit:
          cpu: 800m
          memory: 2Gi
    jobservice:
      replicas: 2 # Jobservice 组件副本数
      resources:
        request:
          cpu: 200m
          memory: 256Mi
        limit:
          cpu: 400m
          memory: 512Mi
    trivy:
      skipUpdate: true
      offlineScan: true
      resources:
        request:
          cpu: 400m
          memory: 1Gi
        limit:
          cpu: 800m
          memory: 2Gi
    database:
      external:
        host: harbor-database # 数据库访问地址
        port: 5432 # 数据库端口号
        sslmode: require # 是否启用 SSL
        username: harbor # 数据库用户名
        coreDatabase: registry # 数据库名
        existingSecret: harbor-database # 存储数据库密码的 Secret
        existingSecretKey: password # 存储数据库密码的 Secret key
      type: external
    redis:
      external:
        addr: harbor-redis:6379 # Redis 访问地址和端口号
        existingSecret: harbor-redis # 存储 Redis 密码的 Secret
        existingSecretKey: password # 存储 Redis 密码的 Secret key
      type: external

后续操作

配置单点登录(SSO)

WARNING

仅当数据库中未添加任何本地用户时,才可将认证模式从数据库切换为 OIDC。如果 Harbor 数据库中存在除 admin 以外的用户,则无法更改认证模式。

详情参考:配置 OIDC 提供者认证

配置 SSO 包括以下步骤:

  1. 在 global 集群注册 SSO 认证客户端
  2. 准备 SSO 认证配置
  3. 配置 Harbor 实例使用 SSO 认证

在 global 集群创建以下 OAuth2Client 资源以注册 SSO 认证客户端:

apiVersion: dex.coreos.com/v1
kind: OAuth2Client
name: OIDC
metadata:
  name: nbqxeytpoiwwizlyzpzjzzeeeirsk # 此值基于 id 字段的哈希计算,在线计算器:https://go.dev/play/p/QsoqUohsKok
  namespace: cpaas-system
alignPasswordDB: true
id: harbor-dex # 客户端 id
public: false
redirectURIs:
  - <harbor 访问地址>/c/oidc/callback
secret: Z2l0bGFiLW9mZmljaWFsLTAK # 客户端密钥
spec: {}
字段说明示例
name资源显示名称OIDC
id用于 SSO 认证的客户端 ID,可设置任意值。
id 不能设置为 alauda-dex,该值为保留值,可能导致冲突。
harbor-dex
secret用于 SSO 认证的客户端密钥,可设置任意值。Z2l0bGFiLW9mZmljaWFsLTAK
metadata.name资源名称,必须基于 id 字段的哈希计算生成。可使用在线哈希计算器如 https://go.dev/play/p/QsoqUohsKok 生成。nbqxeytpoiwwizlyzpzjzzeeeirsk
redirectURIs第三方产品 URL。Harbor 要求格式为:<harbor 访问地址>/c/oidc/callbackhttps://harbor.com/c/oidc/callback
metadata.namespace平台系统命名空间,默认为 cpaas-systemcpaas-system

编辑 Harbor 实例,添加以下配置:

spec:
  helmValues:
    oidc:
      enable: true
      clientID: "harbor-dex"
      clientSecret: "Z2l0bGFiLW9mZmljaWFsLTAK"
      issuer: "<平台访问地址>/dex"

配置 HTTPS

部署 Harbor 实例后,可按需配置 HTTPS。

首先在实例所在命名空间创建 TLS 证书 Secret:

apiVersion: v1
kind: Secret
metadata:
  name: harbor-tls-cert
  namespace: harbor
type: kubernetes.io/tls
data:
  tls.crt: <base64 编码的证书>
  tls.key: <base64 编码的密钥>

然后编辑 Harbor 实例 YAML 配置,启用 HTTPS 访问:

expose:
  type: ingress
  tls:
    enabled: true
    certSource: secret
    secret:
      secretName: harbor-tls-cert
  ingress:
    hosts:
      core: <域名>

externalURL: https://<域名>

配置镜像扫描漏洞数据库策略

Harbor 的镜像扫描功能由 Trivy 组件实现。考虑用户网络环境,该组件默认使用内置离线漏洞数据库。由于数据库不更新,无法及时发现新漏洞。

若需保持漏洞数据库更新,可编辑 Harbor 实例 YAML 配置,启用在线更新策略(该策略需访问 GitHub):

trivy:
  skipUpdate: false
  offlineScan: false

启用在线更新策略后,Trivy 会根据上次更新时间决定扫描前是否更新漏洞数据库。因下载数据库耗时,若不需要 Java 漏洞扫描,也可编辑配置禁用 Java 漏洞数据库更新:

trivy:
  skipJavaDBUpdate: true

附加信息

在 IPv6 环境部署 Harbor

Harbor 支持在 IPv6 环境部署,但需确保客户端工具版本支持 IPv6。若遇到 invalid reference format 错误,请检查客户端工具版本是否支持 IPv6。

相关社区问题: