Harbor 纯 MetalLB 部署方案
一、前置条件(已满足)
- Kubernetes 集群(1.20+),已部署:
- MetalLB(地址池已配置,有可用固定 IP,如
10.2.10.101) - Helm 3.x
- 默认 StorageClass
- MetalLB(地址池已配置,有可用固定 IP,如
- MinIO 集群(可选,已创建
harbor-registry存储桶 + 访问账号)
二、完整部署步骤
步骤 1:创建 Harbor 命名空间
kubectl create namespace harbor
# 验证命名空间
kubectl get ns harbor
步骤 2:准备 Harbor 配置文件(harbor-value.yaml)
核心配置:直接通过 LoadBalancer 暴露 Harbor,指定 MetalLB 固定 IP,含 MinIO 存储(无需则删除 storageService 段):
sudo tee harbor-value.yaml << 'EOF'
# ===================== 核心暴露配置(MetalLB + LoadBalancer) =====================
expose:
# 暴露类型:LoadBalancer(MetalLB分配固定IP)
type: loadBalancer
loadBalancer:
IP: 10.2.10.101
ports:
http: 80
https: 443
# TLS配置(临时关闭,避免证书干扰启动,稳定后可开启)
tls:
enabled: false
auto:
commonName: "10.2.10.101"
# ===================== 外部访问配置(HTTP,避免HTTPS证书问题) =====================
externalURL: http://10.2.10.101
# ===================== 管理员账户 =====================
harborAdminPassword: "Harbor12345"
# ===================== 内嵌数据库配置(含权限修复) =====================
database:
type: internal
internal:
password: "Harbor12345"
# 核心:修复PostgreSQL数据目录权限
securityContext:
enabled: true
fsGroup: 999 # postgres用户GID
runAsUser: 999 # postgres用户UID
runAsGroup: 999 # postgres用户组
runAsNonRoot: true # 非root运行
# ===================== 内嵌Redis配置(含权限修复) =====================
redis:
type: internal
securityContext:
enabled: true
fsGroup: 1000 # redis用户GID
runAsUser: 1000 # redis用户UID
runAsGroup: 1000 # redis用户组
runAsNonRoot: true
# ===================== 持久化配置(NFS存储类) =====================
persistence:
enabled: true
resourcePolicy: "keep" # 卸载时保留PVC
persistentVolumeClaim:
chartmuseum: {size: 1Gi, accessMode: ReadWriteOnce, storageClass: nfs-client}
jobservice: {size: 1Gi, accessMode: ReadWriteOnce, storageClass: nfs-client}
database: {size: 1Gi, accessMode: ReadWriteOnce, storageClass: nfs-client}
redis: {size: 1Gi, accessMode: ReadWriteOnce, storageClass: nfs-client}
trivy: {size: 5Gi, accessMode: ReadWriteOnce, storageClass: nfs-client}
# ===================== Trivy配置(含权限修复) =====================
trivy:
securityContext:
enabled: true
fsGroup: 1000
runAsUser: 1000
runAsGroup: 1000
runAsNonRoot: true
# ===================== 镜像存储配置(MinIO/S3) =====================
registry:
storage:
s3:
region: us-east-1 # MinIO兼容的默认区域
bucket: harbor-registry # MinIO中已创建的桶名
accesskey: harbor-user # MinIO用户名
secretkey: Harbor@1cbn996 # MinIO密码
regionendpoint: http://192.168.192.115:9000 # MinIO实际地址
encrypt: false # 非加密传输
secure: false # HTTP访问(非HTTPS)
v4auth: true # 开启v4签名(MinIO必需)
pathstyle: true # 路径式访问(MinIO必需)
rootdirectory: / # 桶根目录
# ===================== 其他配置(简化部署) =====================
logLevel: info
notary: {enabled: false} # 禁用Notary(非核心)
chartmuseum: {enabled: false} # 禁用ChartMuseum(非核心)
EOF
步骤 3:添加 Harbor Helm 仓库(首次部署)
helm repo add harbor https://helm.goharbor.io
helm repo update
步骤 4:安装 Harbor
helm upgrade --install harbor harbor/harbor --namespace harbor --values harbor-value.yaml
步骤 5:验证 MetalLB 绑定与 Harbor 部署
5.1 检查 Service 状态(核心)
kubectl get svc -n harbor
预期输出(harbor Service 的 TYPE 为 LoadBalancer,EXTERNAL-IP 为指定的 10.2.10.101):
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
harbor LoadBalancer 10.96.100.10 10.2.10.101 80:30080/TCP,443:30443/TCP 5m
harbor-database ClusterIP 10.96.100.11 <none> 5432/TCP 5m
harbor-redis ClusterIP 10.96.100.12 <none> 6379/TCP 5m
harbor-core ClusterIP 10.96.100.13 <none> 80/TCP 5m
harbor-registry ClusterIP 10.96.100.14 <none> 5000/TCP 5m
5.2 检查 Pod 状态
kubectl get pods -n harbor -w
所有 Pod 状态变为 Running 即为部署完成(初始化约 2-5 分钟)。
步骤 6:访问与功能验证
6.1 访问 Harbor Web 界面
直接在浏览器访问 MetalLB 固定 IP:https://10.2.10.101,使用账号 admin/Harbor12345 登录(忽略自签名证书警告)。
6.2 镜像推送/拉取测试
# 1. 登录Harbor(忽略自签名证书)
docker login 10.2.10.101 --insecure-registry
# 2. 标记并推送镜像
docker tag nginx:latest 10.2.10.101/library/nginx:latest
docker push 10.2.10.101/library/nginx:latest
# 3. 拉取镜像验证
docker pull 10.2.10.101/library/nginx:latest
6.3 MinIO 存储验证(可选)
# 配置MinIO客户端
mc alias set minio http://minio.minio:9000 admin Kgb4zZT1cU
# 查看存储桶内镜像数据(推送后应有内容)
mc ls minio/harbor
三、核心说明
1. 关键配置注意事项
expose.loadBalancer.IP:必须是 MetalLB 地址池内的可用 IP,且未被其他 Service 占用;externalURL:必须与 MetalLB IP 一致(https://<MetalLB_IP>),否则镜像推送/拉取会报「重定向错误」;tls.commonName:建议与 MetalLB IP 一致,避免证书域名不匹配警告。
2. 存储配置说明
Harbor 组件需要持久化存储来保存数据,包括:
- chartmuseum:Helm Chart 存储
- jobservice:任务服务数据
- database:内部数据库数据
- redis:缓存数据
- trivy:漏洞扫描数据
在配置中指定了使用 nfs-client StorageClass,确保集群中已部署 NFS Provisioner 并创 建了相应的 StorageClass。
镜像存储配置使用 S3 协议连接到 MinIO:
- bucket: harbor(存储桶名称)
- accesskey: admin(访问密钥)
- secretkey: Kgb4zZT1cU(私密密钥)
- regionendpoint: http://minio.minio:9000 (MinIO服务地址)
3. 生产环境优化(可选)
3.1 替换自定义 TLS 证书
# 1. 创建证书Secret(证书CN需为MetalLB IP)
kubectl create secret tls harbor-tls-secret -n harbor \
--cert=./10.2.10.101.crt \
--key=./10.2.10.101.key
# 2. 修改配置文件(harbor-value.yaml)
expose:
tls:
enabled: true
secretName: harbor-tls-secret # 指定自定义证书Secret
3.2 资源限制配置(避免资源抢占)
在配置文件中添加组件资源限制:
resources:
core:
requests: {cpu: 200m, memory: 512Mi}
limits: {cpu: 1000m, memory: 1Gi}
registry:
requests: {cpu: 200m, memory: 512Mi}
limits: {cpu: 1000m, memory: 1Gi}
jobservice:
requests: {cpu: 200m, memory: 512Mi}
limits: {cpu: 1000m, memory: 1Gi}
4. 故障排查
| 故障现象 | 排查方向 |
|---|---|
| Service EXTERNAL-IP 为 | 1. 检查MetalLB地址池是否包含指定IP;2. 检查MetalLB Pod是否正常运行;3. 检查IP是否被占用 |
| 访问 IP 超时 | 1. 检查Harbor Pod是否全部Running;2. 检查节点防火墙是否放行80/443端口;3. 检查MetalLB L2广告是否正常 |
| 镜像推送失败 | 1. 检查externalURL是否与IP一致;2. 检查docker login是否成功;3. 查看harbor-core日志 |
| PVC 状态为 Pending | 1. 检查StorageClass是否存在;2. 检查NFS Provisioner是否正常运行;3. 检查NFS服务器是否可访问 |
| MinIO连接失败 | 1. 检查MinIO服务是否正常运行;2. 检查accesskey/secretkey是否正确;3. 检查网络连通性 |
四、常用运维命令
# 1. 查看Harbor核心日志
kubectl logs -n harbor deploy/harbor-core -f
kubectl logs -n harbor deploy/harbor-registry -f
# 2. 升级Harbor(修改配置后)
helm upgrade harbor harbor/harbor -n harbor --values harbor-value.yaml
# 3. 卸载Harbor(保留PVC)
helm uninstall harbor -n harbor
# 4. 查看MetalLB绑定详情
kubectl describe svc harbor -n harbor