大数跨境
0
0

k8s 使用helm部署企业级harbor

k8s 使用helm部署企业级harbor SRE云原生
2025-11-27
0


一、环境清单

1、集群基础信息

项目
配置值
集群架构
Kubernetes 单 Master+3Worker(1 主 3 从)+ 3 节点 Ceph 集群
K8s 版本
v1.23.0
容器运行时
Docker 26.1.4
网络插件
Calico v3.22
操作系统
CentOS 7.9(所有节点统一)
内核版本
3.10.0-1160.el7.x86_64
K8s 节点资源
4 核 CPU + 8G 内存
Ceph 节点资源
4 核 CPU + 8G 内存 + 单块 20GiB OSD 盘
Pod 网络段
10.244.0.0/16
Service 网络段
10.96.0.0/12
核心插件
Ingress-Nginx v1.5.1(集群入口网关)

2、节点信息总览

机器名称
机器 IP
角色
核心功能
k8s-master
10.132.47.60
K8s Master + NFS 服务器
集群控制面 + NFS 共享存储提供
k8s-node1
10.132.47.61
K8s Worker
NFS 客户端
k8s-node2
10.132.47.62
K8s Worker
NFS 客户端
k8s-node3
10.132.47.63
K8s Worker
运行 Ingress Controller Pod NFS 客户端
ceph-1
10.132.47.68
Ceph mon + mgr(备用)+ osd + rgw
Ceph 监控节点 + 备用管理节点 + 存储节点 + S3 网关
ceph-2
10.132.47.69
Ceph mon + mgr(备用)+ osd
Ceph 监控节点 + 备用管理节点 + 存储节点
ceph-3
10.132.47.70
Ceph mon + mgr(主节点)+ osd
Ceph 监控节点 + 主管理节点 + 存储节点

3、 Ceph 分布式存储(Harbor 镜像存储专用)

配置项
详情
集群版本
Ceph Nautilus(14.x)
部署架构
3 节点集群(mon 三副本 + osd 三副本 + mgr 主备冗余)
集群健康状态
HEALTH_WARN(非致命警告,不影响存储读写)
核心组件
mon(监控)、mgr(管理)、osd(存储)、rgw(S3 网关)
总存储容量
60 GiB(3 个 OSD 盘,单盘 20GiB)
可用容量
57 GiB(扣除系统元数据与 OSD 开销)
存储池配置
my-pool(Harbor 专用,64 PG/PGP,3 副本)
RGW 网关
部署于 ceph-1 节点,监听 7480 端口(S3 协议,无 SSL)
访问密钥
专用账号 harbor_rgw(用于 Harbor 对接)

4、业务资源

4.1 数据库机器基础信息表
机器名称
机器 IP
系统版本
硬件配置
部署数据库 / 服务
mysql_master
10.132.47.65
CentOS 7.9
4 核 8G
Redis、PostgreSQL 15

部署节点 IP
数据库类型
用户名
密码
权限范围
用途
10.132.47.65
Redis
-
Shyshy521521!
全量操作权限
Redis 访问认证
10.132.47.65
PostgreSQL 15
postgres
Shyshy521521!
超级管理员权限
数据库管理、Harbor 连接
4.2 数据库访问方式表
部署节点 IP
数据库类型
服务端口
监听地址
访问方式(本地 / 远程)
认证方式
10.132.47.65
Redis
6379
0.0.0.0
本地 + 远程
密码认证
10.132.47.65
PostgreSQL 15
5432
*(所有地址)
本地 + 远程
md5 密码认证
4.3 Ingress-Nginx 集群入口
4.3.1 基础配置
配置项
取值
命名空间
ingress-nginx
控制器版本
v1.5.1
镜像来源
阿里云镜像(registry.cn-hangzhou.aliyuncs.com)
准入控制
已关闭(简化部署)
4.3.2 服务与工作负载
资源类型
资源名称
类型
端口配置
副本数
节点分配
Service
nginx-ingress-ingress-nginx-controller
NodePort
集群内 80/443 / 外部 30080(HTTP)、30443(HTTPS)
-
-
Deployment
nginx-ingress-ingress-nginx-controller
-
-
1
k8s-node3
4.3.3 访问入口
访问协议
外部访问地址格式
用途
HTTP
任意 Worker 节点 IP:30080
集群 HTTP 流量统一入口
HTTPS
任意 Worker 节点 IP:30443
集群 HTTPS 流量统一入口

5、Ceph 集群详细配置

5.1 软件版本与安装
软件名称
版本号
安装方式
核心功能
Ceph
Nautilus(14.x)
ceph-deploy
分布式存储核心集群
ceph-deploy
2.0.1
pip 安装
Ceph 集群部署工具
ceph-radosgw
14.x(Nautilus)
YUM 安装
S3 兼容对象存储网关
ceph-common
14.x(Nautilus)
YUM 安装
Ceph 集群通用工具集
5.2 核心组件配置
组件
节点分布
状态
核心配置
mon
ceph-1、ceph-2、ceph-3
三副本 quorum 就绪
监听 6789 端口,负责集群元数据管理
mgr
主:ceph-3;备:ceph-1/2
主备冗余(active/standby)
监听 6800/6801 端口,提供集群管理功能
osd
每个节点 1 个(共 3 个)
全部 up + in
单盘 20GiB,3 副本存储策略
rgw
ceph-1
active (running)
监听 7480 端口,S3 协议,开机自启
5.3 存储池配置
存储池名称
PG/PGP 数量
副本数
应用类型
核心用途
my-pool
64/64
3
rgw
Harbor 镜像存储专用池(手动创建)
.rgw.root
8/8
3
rgw
RGW 根目录元数据存储(自动创建)
.rgw.control
8/8
3
rgw
RGW 控制通道(自动创建)
.rgw.gc
8/8
3
rgw
RGW 垃圾回收(自动创建)
.users.uid
64/64
3
rgw
RGW 用户 UID 映射(自动创建)

二、部署前准备工作

1. 环境依赖校验

# 1. 检查 K8s 集群状态(确保节点 Ready、核心组件正常)kubectl get nodeskubectl get pods -n kube-systemkubectl get pods -n ingress-nginx  # 确认 Ingress 控制器运行
############################################################################################################# 2. 检查 PostgreSQL 可用性以及数据库psql -h 10.132.47.65 -U postgres -d postgres# 执行后输入以下 SQL 验证,能返回结果则正常\l
exit
#示例[root@localhost ~]# psql -h 10.132.47.65 -U postgres -d postgres用户 postgres 的口令:psql (9.2.24, 服务器 15.14) 警告:psql 版本9.2, 服务器版本15.0.一些psql功能可能无法工作.输入 "help" 来获取帮助信息.
postgres=# \l                                           资料库列表         名称         |  拥有者  | 字元编码 |  校对规则   |    Ctype    |       存取权限        ----------------------+----------+----------+-------------+-------------+----------------------- harbor_core          | postgres | UTF8     | zh_CN.UTF-8 | zh_CN.UTF-8 |  harbor_notary_server | postgres | UTF8     | zh_CN.UTF-8 | zh_CN.UTF-8 |  harbor_notary_signer | postgres | UTF8     | zh_CN.UTF-8 | zh_CN.UTF-8 |  postgres             | postgres | UTF8     | zh_CN.UTF-8 | zh_CN.UTF-8 |  template0            | postgres | UTF8     | zh_CN.UTF-8 | zh_CN.UTF-8 | =c/postgres          +                      |          |          |             |             | postgres=CTc/postgres template1            | postgres | UTF8     | zh_CN.UTF-8 | zh_CN.UTF-8 | =c/postgres          +                      |          |          |             |             | postgres=CTc/postgres(6 行记录)############################################################################################################
# 3. 检查 Redis 集群可用性(测试连接)redis-cli -h 10.132.47.65 -p 6379 -a Shyshy521521! -c# 执行后输入以下命令,返回 PONG 则正常pingexit
#示例[root@localhost ~]# redis-cli -h 10.132.47.65 -p 6379 -a Shyshy521521! -c10.132.47.65:6379> pingPONG10.132.47.65:6379> exit#############################################################################################################检查[root@k8s-master harbor]# kubectl get nodesNAME         STATUS   ROLES                  AGE   VERSIONk8s-master   Ready    control-plane,master   10d   v1.23.0k8s-node1    Ready    <none>                 10d   v1.23.0k8s-node2    Ready    <none>                 10d   v1.23.0k8s-node3    Ready    <none>                 10d   v1.23.0[root@k8s-master harbor]# kubectl get pods -n kube-systemNAME                                       READY   STATUS    RESTARTS     AGEcalico-kube-controllers-5bb5d4f7f4-ldx68   1/1     Running   1 (9d ago)   10dcalico-node-4c4wz                          1/1     Running   1 (8d ago)   10dcalico-node-mc6xn                          1/1     Running   1 (8d ago)   10dcalico-node-mhck8                          1/1     Running   1 (9d ago)   10dcalico-node-nk77r                          1/1     Running   1 (8d ago)   10dcoredns-6d8c4cb4d-76fkb                    1/1     Running   1 (9d ago)   10dcoredns-6d8c4cb4d-b4wwq                    1/1     Running   1 (9d ago)   10detcd-k8s-master                            1/1     Running   1 (9d ago)   10dkube-apiserver-k8s-master                  1/1     Running   1 (9d ago)   10dkube-controller-manager-k8s-master         1/1     Running   1 (9d ago)   10dkube-proxy-474gq                           1/1     Running   1 (8d ago)   10dkube-proxy-g8sfp                           1/1     Running   1 (8d ago)   10dkube-proxy-rgrn7                           1/1     Running   1 (9d ago)   10dkube-proxy-tjmh5                           1/1     Running   1 (8d ago)   10dkube-scheduler-k8s-master                  1/1     Running   1 (9d ago)   10dmetrics-server-8f68868ff-nwjrx             1/1     Running   1 (8d ago)   10dnfs-client-provisioner-5bfb45b7b8-9gbbn    1/1     Running   0            3d[root@k8s-master harbor]# kubectl get pods -n ingress-nginxNAME                                                     READY   STATUS    RESTARTS   AGEnginx-ingress-ingress-nginx-controller-f5664cdf7-9tckg   1/1     Running   0          57m############################################################################################################

2. 检查 Ceph RGW 可用性(测试 S3 连接)

2.1 安装 awscli(用于测试 S3)
yum install -y awscli
2.2 查看 Ceph RGW 已创建的用户
#登录任意 Ceph 节点(如 ceph-1:10.132.47.68),执行以下命令列出所有 RGW 用户:
radosgw-admin user list#输出示例(包含你创建的 harbor-user 用户):["harbor-user"]
2.3. 如果没有:

创建 RGW 专用存储池与用户

# 用ceph-deploy部署RGW# 在部署节点执行ceph-deploy rgw create ceph-1 ceph-2 ceph-3

# 部署完成后,验证RGW服务# 查看RGW进程ssh ceph-1 "ps -ef | grep radosgw"# 查看RGW端口(默认7480)ssh ceph-1 "netstat -ntlp | grep 7480"

# 创建基础用户(仅包含uid、display-name、email)radosgw-admin user create \--uid=Harbor_rgw \--display-name="RGW Super Administrator" \--email=Harbor_rgw@example.com

# 1. 添加用户管理全权限(创建/删除其他用户)radosgw-admin caps add --uid=Harbor_rgw --caps="users=*"
# 2. 添加桶管理全权限(创建/删除/修改所有桶)radosgw-admin caps add --uid=Harbor_rgw --caps="buckets=*"
# 3. 添加对象操作全权限(读写/删除所有桶内对象)radosgw-admin caps add --uid=Harbor_rgw --caps="objects=*"
# 4. 添加元数据操作全权限(修改所有对象元数据)radosgw-admin caps add --uid=Harbor_rgw --caps="metadata=*"
# 5. (已添加,可选验证)确认usage权限radosgw-admin caps add --uid=Harbor_rgw --caps="usage=*"

# 查看用户信息(关键:获取Access Key和Secret Key,用于客户端连接)radosgw-admin user info --uid=Harbor_rgw

执行后会输出用户的access_keysecret_key务必保存好,后续配置 Harbor 会用到。

2.5 验证用户创建成功
# 再次列出 RGW 用户,确认 harbor-user 已存在radosgw-admin user list# 输出示例:["harbor-user"]
# 查看用户详细信息(若之前没记全密钥,可重新查询)radosgw-admin user info --uid=harbor-user
vim /etc/ceph/ceph.conf

[client.rgw.<你的rgw实例名>]段(如[client.rgw.ceph-1])添加以下配置:

  • 若不知道rgw实例名,可执行ceph -ssystemctl list-units | grep rgw查看(如ceph-radosgw@rgw.ceph-1.service中的ceph-1)。
[client.rgw.ceph-1]# 强制开启S3路径风格访问(关键,解决Registry的路径解析问题)rgw_s3_enable_path_style = true# 强制使用S3 V4签名(与Registry的signature_version: s3v4匹配)rgw_signature_version = s3v4# 关闭虚拟主机风格访问(避免冲突)rgw_dns_name = # 允许跨桶的路径访问rgw_allow_multiple_buckets_in_request = true

配置 S3 客户端

aws configure set aws_access_key_id 你的_harbor_rgw_access_keyaws configure set aws_secret_access_key 你的_harbor_rgw_secret_keyaws configure set default.s3.signature_version s3v4
# 配置 access_key(使用你的实际密钥)aws configure set aws_access_key_id HARBOR123456789# 配置 secret_key(使用你的实际密钥)aws configure set aws_secret_access_key HarborSecretKey123456789# 配置 S3 签名版本(Ceph RGW 需 v4 认证)aws configure set default.s3.signature_version s3v4

# 测试连接(使用正确的 IP)aws s3 ls --endpoint-url http://10.132.47.68:7480# 创建 Harbor 专用桶aws s3 mb s3://harbor-image-storage --endpoint-url http://10.132.47.68:7480# 验证桶创建成功aws s3 ls --endpoint-url http://10.132.47.68:7480
#示例[root@k8s-master harbor]# aws s3 ls --endpoint-url http://10.132.47.68:7480[root@k8s-master harbor]# aws s3 mb s3://harbor-image-storage --endpoint-url http://10.132.47.68:7480make_bucket: harbor-image-storage[root@k8s-master harbor]# aws s3 ls --endpoint-url http://10.132.47.68:74802025-11-14 11:13:22 harbor-image-storage
测试列出存储桶
aws s3 ls --endpoint-url http://10.132.47.68:7480

3. 创建 Harbor 专用命名空间

kubectl create namespace harbor# 验证命名空间创建成功kubectl get namespaces | grep harbor
#示例[root@k8s-master harbor-helm-1.8.3]# kubectl get namespaces | grep harborharbor                 Active   9s

4. 下载 Harbor Helm Chart 包

# 创建 Chart 存储目录mkdir -p /root/k8s-yaml/harbor && cd /root/k8s-yaml/harbor
# 添 Harbor 官方 Helm 仓库(若无法访问可替换为国内镜像)helm repo add harbor https://helm.goharbor.iohelm repo update
#若失败,直接下载wget --no-check-certificate https://ghproxy.com/https://github.com/goharbor/harbor-helm/releases/download/v1.7.0/harbor-1.7.0.tgz -O harbor-1.7.0.tgz#官网下载zip文件https://github.com/goharbor/harbor-helm/tree/v1.7.0# 解压 ZIP 包(需安装 unzip,若未安装先执行:yum install -y unzip)unzip harbor-helm-1.7.0.zip# 进入解压后的目录(目录名应为 harbor-helm-1.8.3)cd harbor-helm-1.7.0# 检查是否包含部署必需文件ls -l values.yaml Chart.yaml templates/# 预期输出:# -rw-r--r-- 1 root root xxxx  values.yaml    # 配置文件# -rw-r--r-- 1 root root xxxx  Chart.yaml     # Chart 元数据# drwxr-xr-x 2 root root xxxx  templates/     # 部署模板目录

# 下载指定版本的 Chart 包helm pull harbor/harbor --version 1.7.0 tar -zxvf harbor-1.7.0.tgz  # 解压 Chart 包cd harbor  # 进入 Chart 目录(后续修改 values.yaml 在此目录)

二、核心配置文件修改(values.yaml)

进入 Chart 解压后的 harbor 目录,编辑 values.yaml,按以下关键配置修改(其余默认,注释说明修改原因):

1. 全局基础配置

# 1. 管理员密码(自定义,建议复杂度高)harborAdminPassword: "Shyshy521521!"
# 2. 外部访问 URL(对应 /etc/hosts 配置的域名)externalURL: https://harbor.example.com
# 3. 镜像拉取策略(复用现有环境配置)imagePullPolicy: IfNotPresent

2. 关闭内部依赖,使用外部PostgreSQL

# 数据库配置:控制 Harbor 元数据存储的数据库来源(内部或外部)database:  # 数据库类型:  # - "internal":使用 Harbor 内置的 PostgreSQL 数据库(默认)  # - "external":使用外部数据库(此处配置为外部,需填写下方 external  section)  type: external
  # 内部数据库(PostgreSQL)配置(当 type=internal 时生效,当前禁用)  internal:    # 服务账户配置:指定运行数据库 Pod 的 ServiceAccount(留空则使用默认)    serviceAccountName: ""    # 是否自动挂载服务账户令牌(用于访问集群内其他资源,默认关闭)    automountServiceAccountToken: false    # 内部数据库镜像信息    image:      repository: goharbor/harbor-db  # 镜像仓库      tag: v2.4.3  # 镜像版本(需与 Harbor 版本兼容)    # 内部数据库初始超级用户密码(首次启动时生效,生产需修改)    password: "changeit"    # 共享内存大小限制:PostgreSQL 用于 shared_buffer(共享缓冲区)    # 详情参考:https://github.com/goharbor/harbor/issues/15034    shmSizeLimit: 512Mi    # 资源限制配置(默认未设置,生产建议根据需求添加)    # resources:    #  requests:    #    memory: 256Mi  # 最小内存请求    #    cpu: 100m     # 最小 CPU 请求    # 节点选择器:指定数据库 Pod 调度到哪些节点(默认无限制)    nodeSelector: {}    # 污点容忍:允许数据库 Pod 调度到带有指定污点的节点    tolerations: []    # 亲和性规则:控制 Pod 与节点/其他 Pod 的调度关系    affinity: {}    # 优先级类:指定 Pod 的调度优先级(默认不设置)    priorityClassName:    # 初始化容器配置(数据库初始化、权限设置等)    initContainer:      migrator: {}  # 数据库迁移容器(用于版本升级时的数据迁移)      # 迁移容器资源配置(默认未设置)      # resources:      #  requests:      #    memory: 128Mi      #    cpu: 100m      permissions: {}  # 权限设置容器(用于调整存储目录权限)      # 权限容器资源配置(默认未设置)      # resources:      #  requests:      #    memory: 128Mi      #    cpu: 100m
  # 外部数据库配置(当 type=external 时生效,当前启用)  external:    host: "10.132.47.65"  # 外部数据库地址    port: "5432"  # 数据库端口(PostgreSQL 默认 5432)    username: "postgres"  # 访问数据库的用户名(需具备创建数据库的权限)    password: "Shyshy521521!"  # 用户名对应的密码(生产环境建议使用 Secret 存储)    # Harbor 各组件使用的数据库名(需提前创建或确保用户有权限创建)    coreDatabase: "harbor_core"  # 核心服务(core)数据库    notaryServerDatabase: "harbor_notary_server"  # 镜像签名服务(notary-server)数据库    notarySignerDatabase: "harbor_notary_signer"  # 签名验证服务(notary-signer)数据库    # SSL 连接模式(控制数据库通信加密):    # - "disable":不使用 SSL(明文传输,适合集群内部信任网络)    # - "require":强制使用 SSL,但不验证证书有效性    # - "verify-ca":强制使用 SSL,且验证证书由可信 CA 签发    # - "verify-full":强制使用 SSL,验证 CA 且证书主机名匹配    sslmode: "disable"  # 当前禁用 SSL(根据实际安全需求调整)
  # 补充内部数据库开关(显式禁用内置数据库,与 type=external 配合)  internal:    enabled: false  # 禁用内置 PostgreSQL(必须设为 false,否则与外部数据库冲突)
  # 数据库连接池配置(控制每个 Pod 对数据库的连接数)  # 空闲连接池最大连接数(每个 Pod:core 服务 +  exporter 组件)  # 若 <=0,则不保留空闲连接  maxIdleConns: 100  # 最大打开连接数(每个 Pod:core 服务 + exporter 组件)  # 若 <=0,则无限制(注意:PostgreSQL 默认最大连接数为 1024,需合理分配)  maxOpenConns: 900
  # 数据库相关 Pod 的额外注解(可添加监控、日志等注解)  podAnnotations: {}

3. 关闭内部依赖,复用外部 Redis 集群

# Redis 配置:控制 Harbor 缓存及临时数据存储的 Redis 来源(内部或外部)redis:  # Redis 类型:  # - "internal":使用 Harbor 内置的 Redis(默认)  # - "external":使用外部 Redis(此处配置为外部,需填写下方 external 部分)  type: external
  # 内部 Redis 配置(当 type=internal 时生效,当前禁用)  internal:    # 服务账户配置:指定运行 Redis Pod 的 ServiceAccount(留空则使用默认)    serviceAccountName: ""    # 是否自动挂载服务账户令牌(用于访问集群内其他资源,默认关闭)    automountServiceAccountToken: false    # 内部 Redis 镜像信息    image:      repository: goharbor/redis-photon  # 镜像仓库      tag: v2.4.3  # 镜像版本(需与 Harbor 版本兼容)    # 资源限制配置(默认未设置,生产建议根据需求添加)    # resources:    #  requests:    #    memory: 256Mi  # 最小内存请求    #    cpu: 100m     # 最小 CPU 请求    # 节点选择器:指定 Redis Pod 调度到哪些节点(默认无限制)    nodeSelector: {}    # 污点容忍:允许 Redis Pod 调度到带有指定污点的节点    tolerations: []    # 亲和性规则:控制 Pod 与节点/其他 Pod 的调度关系    affinity: {}    # 优先级类:指定 Pod 的调度优先级(默认不设置)    priorityClassName:
  # 外部 Redis 配置(当 type=external 时生效,当前启用)  external:    # Redis 地址:    # - 单节点 Redis:格式为 <主机>:<端口>    # - Redis 集群(无哨兵):若需指定多个节点,用逗号分隔(如 "node1:6379,node2:6379")    # - Redis+哨兵模式:填写哨兵节点地址(如 "sentinel1:26379,sentinel2:26379")    # 此处为 K8s 内 Redis 集群的 Service 地址(格式:服务名.命名空间.svc.cluster.local:端口)    addr: "10.132.47.65:6379""
    # 哨兵主节点集名称:仅 Redis+哨兵模式需要填写(指定监控的主节点名称)    # 无哨兵模式下留空(当前为无哨兵集群,故不配置)    sentinelMasterSet: ""
    # 各组件使用的 Redis 数据库索引(Redis 支持多数据库,通过索引隔离数据)    coreDatabaseIndex: "0"           # 核心服务(core)使用的数据库索引(必须为 0,Harbor 库不支持自定义)    jobserviceDatabaseIndex: "1"     # 任务服务(jobservice)使用的数据库索引    registryDatabaseIndex: "2"       # 镜像仓库(registry)使用的数据库索引    chartmuseumDatabaseIndex: "3"    # 图表仓库(chartmuseum)使用的数据库索引    trivyAdapterIndex: "5"           # 漏洞扫描(trivy)适配器使用的数据库索引

  # Redis 相关 Pod 的额外注解(可添加监控、日志等注解)  podAnnotations: {}

4. 存储配置:使用 Ceph RGW

# 持久化存储配置:控制 Harbor 各组件的数据持久化方式persistence:  enabled: true  # 启用持久化存储(生产环境必须开启,否则数据会随 Pod 销毁丢失)
  # 资源保留策略:删除 Helm 释放时的 PVC 处理规则  # - 设为 "keep":保留 PVC,避免误删数据(推荐生产环境使用)  # - 留空:删除 Helm 图表后自动删除 PVC(不推荐)  # 注意:内置数据库(PostgreSQL)和 Redis 的 PVC 永远不会自动删除,此配置仅作用于其他组件  resourcePolicy: "keep"
  # 各组件的 PersistentVolumeClaim(PVC)配置:为每个核心组件单独分配存储  persistentVolumeClaim:    # 镜像仓库(registry)组件的 PVC 配置:存储上传的镜像数据    registry:      existingClaim: "nfs-storage"  # 使用已存在的 PVC(需手动提前创建,此处未使用)      storageClass: ""  # 存储类名称(使用 NFS 存储,需集群已创建该存储类)      subPath: ""  # PVC 子路径(若 PVC 被多组件共享时指定,此处单独使用留空)      accessMode: ReadWriteOnce  # 访问模式:单节点读写(NFS 支持该模式)      size: 50Gi  # 存储容量:根据实际镜像存储需求调整(生产建议至少 100Gi+)
    # 图表仓库(chartmuseum)组件的 PVC 配置:存储 Helm 图表数据    chartmuseum:      existingClaim: ""      storageClass: "nfs-storage"  # 同样使用 NFS 存储类      subPath: ""      accessMode: ReadWriteOnce      size: 5Gi  # 图表存储容量:根据 Helm 图表数量调整
    # 任务服务(jobservice)组件的 PVC 配置:存储任务日志、临时文件(如镜像扫描结果)    jobservice:      existingClaim: ""      storageClass: "nfs-storage"      subPath: ""      accessMode: ReadWriteOnce      size: 1Gi  # 任务日志容量:一般 1-5Gi 足够
    # 数据库(database)组件的 PVC 配置:存储 Harbor 元数据(如项目、用户、权限)    # 注意:若已配置外部数据库(如之前的外部 PostgreSQL),此配置会被忽略    database:      existingClaim: ""      storageClass: ""  # 数据库专用存储类(单独配置,优化性能)      subPath: ""      accessMode: ReadWriteMany  # 访问模式:多节点读写(适配数据库主从或集群场景)      size: 1Gi  # 数据库容量:根据元数据量调整(生产建议 10Gi+)
    # Redis 组件的 PVC 配置:存储 Redis 缓存数据    # 注意:若已配置外部 Redis 集群,此配置会被忽略    redis:      existingClaim: ""      storageClass: ""      subPath: ""      accessMode: ReadWriteOnce      size: 1Gi  # Redis 缓存容量:一般 1-5Gi 足够
    # 漏洞扫描(trivy)组件的 PVC 配置:存储漏洞数据库、扫描缓存    trivy:      existingClaim: ""      storageClass: "nfs-storage"      subPath: ""      accessMode: ReadWriteOnce      size: 5Gi  # Trivy 漏洞库容量:漏洞库较大,建议 5-20Gi
  # 镜像和图表的存储后端配置:指定 registry(镜像)和 chartmuseum(图表)的数据存储方式  # 参考文档:https://github.com/docker/distribution/blob/master/docs/configuration.md#storage  imageChartStorage:    # 禁用存储重定向:部分存储后端(如 MinIO S3)不支持重定向,需设为 true    # 启用重定向时,客户端直接与存储后端交互(提升传输效率),默认禁用(false)    disableredirect: true
    # CA 证书秘钥名称:若存储服务使用自签名证书,需指定包含 "ca.crt" 的 Secret 名称    # 用于注入到 registry 和 chartmuseum 容器的信任证书库    # caBundleSecretName: ""
    # 存储类型:支持 filesystem(文件系统)、azure、gcs、s3、swift、oss    # 注意:若使用 PVC 持久化(上面的 persistentVolumeClaim 配置),需设为 filesystem    # 此处配置为 s3,说明镜像/图表直接存储到 S3 兼容存储(而非 PVC)    type: s3
    # 文件系统存储配置(当 type=filesystem 时生效)    filesystem:      rootdirectory: /storage  # 存储根目录(与 PVC 挂载路径对应)      # maxthreads: 100  # 最大并发线程数(默认不限制)
    # Azure Blob 存储配置(当 type=azure 时生效,此处未使用)    azure:      accountname: accountname  # Azure 存储账户名      accountkey: base64encodedaccountkey  # Base64 编码的账户密钥      container: containername  # 存储容器名称      # realm: core.windows.net  # Azure 域名(默认无需修改)
    # Google Cloud Storage 配置(当 type=gcs 时生效,此处未使用)    gcs:      bucket: bucketname  # GCS 存储桶名称      encodedkey: base64-encoded-json-key-file  # Base64 编码的密钥文件内容      # rootdirectory: /gcs/object/name/prefix  # 存储前缀(用于隔离数据)      # chunksize: "5242880"  # 分片上传大小(默认 5MB)
    # S3 兼容存储配置(当 type=s3 时生效,此处使用 Ceph RGW 作为 S3 存储)    s3:      region: default  # 区域(Ceph RGW 默认为 default)      bucket: harbor-image-storage  # 自动创建的桶名称      accesskey: CM3YBZV8Y55A9QWHNC0E  # Ceph RGW 访问密钥(AK)      secretkey: cuDoZN1jumZaV0eoUPYSi31kk585IIXsgc5AfmBq  # Ceph RGW 密钥(SK)      regionendpoint: http://10.132.47.68:7480  # Ceph RGW 访问地址(节点 IP + 7480 端口)      secure: false  # 是否启用 SSL(Ceph RGW 未配置 HTTPS,设为 false)      v4auth: true  # 启用 S3 v4 认证(Ceph RGW 支持,必须开启)      rootdirectory: /harbor  # 存储桶内根目录(用于隔离 Harbor 数据)      forcepathstyle: true  # 绕开域名解析      signature_version: "s3v4"  # 明确V4签名      encrypt: false  # 测试环境禁用加密,生产可按需开启      pathstyle: true  # 必须为 true,兼容 RGW      # accesskey: awsaccesskey  # AWS S3 访问密钥(兼容 AWS 时使用)      # secretkey: awssecretkey  # AWS S3 密钥      # regionendpoint: http://myobjects.local  # AWS S3 终端地址      # encrypt: false  # 是否加密存储(默认不加密)      # keyid: mykeyid  # 加密密钥 ID(启用加密时填写)      # skipverify: false  # 是否跳过 SSL 证书验证(默认不跳过)      chunksize: "5242880"  # 分片上传大小(默认 5MB)      #storageclass: STANDARD  # S3 存储类别(默认标准存储)
    # Swift 存储配置(当 type=swift 时生效,此处未使用)    swift:      authurl: https://storage.myprovider.com/v3/auth  # Swift 认证地址      username: username  # 用户名      password: password  # 密码      container: containername  # 存储容器名称      # region: fr  # 区域(根据实际环境填写)      # tenant: tenantname  # 租户名称(OpenStack 环境需填写)
    # 阿里云 OSS 存储配置(当 type=oss 时生效,此处未使用)    oss:      accesskeyid: accesskeyid  # OSS 访问密钥 ID      accesskeysecret: accesskeysecret  # OSS 访问密钥 Secret      region: regionname  # OSS 区域(如 cn-hangzhou)      bucket: bucketname  # OSS 存储桶名称      # endpoint: endpoint  # 自定义 OSS 终端地址(默认无需修改)

5. 网络暴露配置:Ingress

查看集群中可用的 IngressClass

kubectl get ingressclasses
kubectl get svc -n ingress-nginx
kubectl get pod -n ingress-nginx
helm ls -n ingress-nginx
kubectl get ingressclasses 输出,集群中有效的 IngressClass 名称是 nginx(控制器为 k8s.io/ingress-nginx)
# 服务暴露配置:控制 Harbor 如何通过 Kubernetes 对外提供服务expose:  # 暴露类型:使用 Ingress(需提前部署 Ingress Controller,如 Nginx Ingress)  type: ingress
  # TLS 证书配置(用于 HTTPS 加密)  tls:    enabled: true  # 启用 HTTPS 加密(必须开启,否则 Harbor 核心功能可能受限)    certSource: auto  # 证书来源:自动生成(由 Ingress Controller 或 cert-manager 自动创建证书)    auto:      commonName: "harbor.example.com"  # 自动生成证书的主域名(需与实际访问域名一致)    secret:      secretName: ""  # 若 certSource 设为 "secret",需填写存储证书的 Secret 名称(此处未使用)      notarySecretName: ""  # Notary 服务(镜像签名验证)的证书 Secret 名称(此处未使用)
  # Ingress 具体配置(当 expose.type=ingress 时生效)  ingress:    hosts:      core: harbor.example.com  # Harbor 核心服务(UI、API 等)的访问域名      notary: notary.harbor.example.com  # Notary 服务的访问域名(用于镜像签名验证)    controller: nginx  # Ingress Controller )    kubeVersionOverride: ""  # 覆盖 Kubernetes 版本(一般留空,由 Helm 自动识别)    annotations:  # Ingress 注解(用于配置 Ingress Controller 行为)      ingress.kubernetes.io/ssl-redirect: "true"  # 强制 HTTP 重定向到 HTTPS(旧版注解)      ingress.kubernetes.io/proxy-body-size: "0"  # 允许上传任意大小的文件(0 表示不限制)      nginx.ingress.kubernetes.io/ssl-redirect: "true"  # 强制 HTTP 重定向到 HTTPS(Nginx 新版注解)      nginx.ingress.kubernetes.io/proxy-body-size: "0"  # 允许上传任意大小的文件(Nginx 新版注解)    notary:      annotations: {}  # Notary 服务的独立 Ingress 注解(此处未额外配置)    harbor:      annotations: {}  # Harbor 核心服务的独立 Ingress 注解(此处未额外配置)
  # ClusterIP 配置(当 expose.type=clusterIP 时生效,仅集群内部可访问)  clusterIP:    name: harbor  # ClusterIP Service 的名称    annotations: {}  # 给 ClusterIP Service 添加的注解    ports:      httpPort: 80  # HTTP 端口(内部访问用)      httpsPort: 443  # HTTPS 端口(内部访问用)      notaryPort: 4443  # Notary 服务端口(内部访问用)
  # NodePort 配置(当 expose.type=nodePort 时生效,通过节点 IP+端口访问)  nodePort:    name: harbor  # NodePort Service 的名称    ports:      http:        port: 80  # 服务内部 HTTP 端口        nodePort: 30002  # 节点暴露的 HTTP 端口(需在 30000-32767 范围内)      https:        port: 443  # 服务内部 HTTPS 端口        nodePort: 30003  # 节点暴露的 HTTPS 端口      notary:        port: 4443  # 服务内部 Notary 端口        nodePort: 30004  # 节点暴露的 Notary 端口
  # LoadBalancer 配置(当 expose.type=loadBalancer 时生效,适用于云厂商环境)  loadBalancer:    name: harbor  # LoadBalancer Service 的名称    IP: ""  # 固定负载均衡器 IP(云厂商支持时填写)    ports:      httpPort: 80  # 负载均衡器转发的 HTTP 端口      httpsPort: 443  # 负载均衡器转发的 HTTPS 端口      notaryPort: 4443  # 负载均衡器转发的 Notary 端口    annotations: {}  # 给 LoadBalancer Service 添加的注解(如云厂商特定配置)    sourceRanges: []  # 限制允许访问的 IP 段(如 ["192.168.0.0/16"])

# Harbor 外部访问 URL(必须与 Ingress 配置的域名一致,用户实际访问的地址)externalURL: https://harbor.example.com

# 内部组件间通信的 TLS 配置(Harbor 各组件之间的加密通信)internalTLS:  enabled: false  # 禁用内部 TLS 加密(生产环境建议开启,需配置证书)  certSource: "auto"  # 内部证书来源:自动生成(若 enabled=true 时生效)  trustCa: ""  # 信任的 CA 证书(若使用自定义 CA 需填写)  # 以下为各组件的证书配置(若 enabled=true 时需分别设置)  core:    secretName: ""  # 存储 core 组件证书的 Secret 名称    crt: ""  # 证书内容(直接填写时用,通常优先用 secretName)    key: ""  # 私钥内容  jobservice:    secretName: ""  # jobservice 组件证书的 Secret 名称    crt: ""    key: ""  registry:    secretName: ""  # 镜像仓库组件证书的 Secret 名称    crt: ""    key: ""  portal:    secretName: ""  # UI 门户组件证书的 Secret 名称    crt: ""    key: ""  chartmuseum:    secretName: ""  # Helm 图表仓库组件证书的 Secret 名称    crt: ""    key: ""  trivy:    secretName: ""  # 漏洞扫描组件证书的 Secret 名称    crt: ""    key: ""

# IP 协议族配置(控制 Harbor 服务使用 IPv4 还是 IPv6)ipFamily:  ipv6:    enabled: false  # 禁用 IPv6  ipv4:    enabled: true  # 启用 IPv4(默认使用 IPv4)

6. 组件高可用配置

# 核心组件副本数(参考架构为 3,按需调整,建议 ≥2 保证高可用)core:  replicas: 2portal:  replicas: 2nginx:  replicas: 2registry:  replicas: 2jobservice:  replicas: 2
# 非核心组件副本数notary:  enabled: true  # 启用镜像签名验证  server:    replicas: 1  signer:    replicas: 1trivy:  enabled: true  # 启用漏洞扫描  replicas: 1chartmuseum:  enabled: true  # 启用 Chart 仓库  replicas: 1

三、执行 Helm 部署

1. 部署前配置校验

# 执行配置校验(检查 values.yaml 语法是否正确)helm lint -f values.yaml .

2. 执行部署

# 部署 Harbor 到 harbor 命名空间helm install harbor . -n harbor -f values.yamlhelm install harbor . -f values.yaml --namespace harbor --create-namespace# 查看部署进度(等待所有 Pod 变为 Running 状态)kubectl get pods -n harbor -o wide -w# 若有 Pod 启动失败,查看日志排查:kubectl logs <pod名称> -n harbor
#执行 Helm 升级,应用配置变更helm upgrade harbor . -n harbor -f values.yaml

#等待完成[root@k8s-master harbor-helm-1.8.3]# kubectl get pod -n harbor NAME                                    READY   STATUS    RESTARTS      AGEharbor-chartmuseum-79df59d854-4k6pg     1/1     Running   0             5m57sharbor-core-bcbf795db-b97kc             1/1     Running   0             5m37sharbor-core-bcbf795db-c6w8k             1/1     Running   0             5m57sharbor-jobservice-6466d59f5c-8nvms      1/1     Running   0             5m7sharbor-jobservice-6466d59f5c-zw7cp      1/1     Running   0             5m57sharbor-notary-server-f69564c57-xgq9z    1/1     Running   1 (27s ago)   5m57sharbor-notary-signer-7bb86c8596-hxcrx   1/1     Running   0             5m57sharbor-portal-57cf48cfc8-6lmlc          1/1     Running   0             14mharbor-portal-57cf48cfc8-rjdkj          1/1     Running   0             14mharbor-registry-64fc45b845-x7d77        2/2     Running   0             5m57sharbor-registry-64fc45b845-zl7mr        2/2     Running   0             5m55sharbor-trivy-0                          1/1     Running   0             14m

3. 验证部署资源

# 查看 Harbor 相关 Servicekubectl get svc -n harbor
# 查看 Ingress 规则(确认域名与后端服务绑定)kubectl get ingress -n harbor
# 查看 PVC 绑定状态(确认 NFS 存储挂载成功)kubectl get pvc -n harbor

如果出现问题:通过外部域名或IP访问时出现404或连接超时错误

# 检查ingresskubectl -n harbor get ingress
NAME             CLASS   HOSTS                     ADDRESS   PORTS     AGEharbor-ingress   nginx   dockerhub.kubekey.local    ############################################################################################################# 检查ingressClasskubectl get ingressclasses.networking.k8s.io
NAME    CONTROLLER             PARAMETERS   AGEnginx   k8s.io/ingress-nginx   <none>       7h45m#############################################################################################################给 harbor 的ingress 配置 ingressClasskubectl -n harbor edit ingress harbor-ingress
spec:  ingressClassName: nginx  # <---- 修改为对应 ingressClassName############################################################################################################kubectl -n harbor edit ingress harbor-ingress-notary
spec:  ingressClassName: nginx  # <---- 修改为对应 ingressClassName

卸载流程

helm uninstall harbor -n harbor
kubectl delete pvc -n harbor --all
kubectl get all -n harbor
kubectl delete all --all -n harbor --force
kubectl delete namespace harbor

四、访问与功能验证

1. 本地访问测试(部署节点)

# 由于未配置 SSL,直接访问 HTTP 地址(Ingress 会重定向到 HTTPS,忽略证书警告)curl -k https://harbor.example.com# 返回 Harbor 登录页面 HTML 内容则正常

2. 浏览器访问验证

#从 Harbor 集群中导出证书(在 k8s 主节点执行):# 1. 查看 Harbor 自动生成的证书 Secret(命名空间为 harbor)kubectl get secrets -n harbor | grep tls# 输出通常是 harbor-tls(核心证书)和 notary-tls(可选)
# 2. 导出证书并保存到 Docker 信任目录mkdir -p /etc/docker/certs.d/harbor.example.com
# 导出证书到 Docker 信任目录kubectl get secret harbor-ingress -n harbor -o jsonpath='{.data.tls\.crt}' | base64 -d > /etc/docker/certs.d/harbor.example.com/ca.crt
# 查看证书文件内容(有内容则正常)cat /etc/docker/certs.d/harbor.example.com/ca.crt
  1. 打开本地浏览器,输入地址:https://harbor.example.com


  2. 忽略 SSL 证书警告(若未配置有效证书)

  3. 使用管理员账号登录:用户名 admin,密码 Shyshy521521!(配置文件中自定义的)

    证书下载

    Harobr主页->配置管理->系统配置->镜像库根证书

    然后进入服务器,在服务器上 /etc/docker 目录下创建 certs.d 文件夹,然后在 certs.d 文件夹下创建 Harobr 域名文件夹,可以输入下面命令创建对应文件夹:

    mkdir -p /etc/docker/certs.d/harbor.example.com

    在此目录放证书文件




  1. 登录后验证核心功能:

    • 创建项目(如 test-project

    • 本地 Docker 登录 Harbor(需配置 Docker 信任私有仓库)

      # Docker 配置信任 Harbor 域名(避免 https 报错)cat > /etc/docker/daemon.json << EOF{  "insecure-registries": ["https://harbor.example.com"],}EOFsystemctl restart docker
      # Docker 登录 Harborecho 'Shyshy521521!' | docker login harbor.example.com -u admin --password-stdindocker login -u admin -p Shyshy521521! harbor.example.com

      #示例[root@k8s-master harbor-helm-1.8.3]# echo 'Shyshy521521!' | docker login harbor.example.com -u admin --password-stdinWARNING! Your password will be stored unencrypted in /root/.docker/config.json.Configure a credential helper to remove this warning. Seehttps://docs.docker.com/engine/reference/commandline/login/#credentials-store
      Login Succeeded












    • 推送镜像到 Harbor(测试存储功能)

      # 拉取测试镜像并打标签docker pull nginx:latest# 示例:将 nginx:latest 推送到 Harbor 的 library 项目(默认项目)docker tag nginx:latest harbor.example.com/library/nginx:v1	
      # 推送镜像(验证 Ceph RGW 存储是否正常)docker push harbor.example.com/library/nginx:v1
















    • 拉取镜像(验证镜像可访问)

      docker rmi harbor.example.com/library/nginx:v1docker pull harbor.example.com/library/nginx:v1






创建 Harbor 镜像仓库的 Secret

创建在默认(default)命名空间

kubectl create secret docker-registry registry-auth \  --docker-username=admin \  --docker-password=shyshy521521 \  --docker-server=harbor.example.com

若你的业务 Pod 部署在特定命名空间,建议将 Secret 创建在同一命名空间(K8s 的 Secret 是命名空间级资源,跨命名空间无法直接引用),命令添加-n <命名空间>即可:

# 示例:创建在dev命名空间kubectl create secret docker-registry registry-auth \  --docker-username=admin \  --docker-password=shyshy521521 \  --docker-server=harbor.example.com \  -n dev

查看 Secret

# 默认命名空间kubectl get secrets# 指定命名空间(如dev)kubectl get secrets -n dev
查看 Secret 详细信息# 默认命名空间kubectl describe secret registry-auth# 指定命名空间kubectl describe secret registry-auth -n dev
在 Pod/Deployment 中引用该 Secret

创建 Secret 后,需在 Pod 或 Deployment 的配置中通过imagePullSecrets字段引用,K8s 才会在拉取 Harbor 私有镜像时自动使用该凭据认证。

Deployment 中引用(生产环境常用)

编写一个拉取 Harbor 私有镜像的 Deployment 配置文件(如harbor-nginx-deploy.yaml),注意替换镜像地址为你 Harbor 中的实际镜像:

apiVersion: apps/v1kind: Deploymentmetadata:  name: harbor-nginx-deploy  namespace: default # 需与Secret的命名空间一致spec:  replicas: 1  selector:    matchLabels:      app: harbor-nginx  template:    metadata:      labels:        app: harbor-nginx    spec:      containers:      - name: nginx        # 替换为你Harbor中的镜像地址,格式:harbor.example.com/项目名/镜像名:版本        image: harbor.example.com/library/nginx:v1        ports:        - containerPort: 80      # 引用创建的Secret      imagePullSecrets:      - name: registry-auth

【声明】内容源于网络
0
0
SRE云原生
专注于分享运维、Devops、网络安全以及SRE云原生相关知识,内容包括但不限于自动化运维、云架构、云监控、云安全、AI、AWS以及攻防渗透等。内容多以原创为主,旨在于编写高质量文章。
内容 35
粉丝 0
SRE云原生 专注于分享运维、Devops、网络安全以及SRE云原生相关知识,内容包括但不限于自动化运维、云架构、云监控、云安全、AI、AWS以及攻防渗透等。内容多以原创为主,旨在于编写高质量文章。
总阅读22
粉丝0
内容35