关于Harbor的配置
Harbor主要是用于管理私有镜像库的,这里我记录下配置Harbor过程中遇到的一些问题以及解决措施。
1. 基础准备
我这里服务器采用的是rke2发行的k8s,已经预装了helm,因为校园服务器连不上外网,所以需要自己提前下载Harbor的镜像然后再上传到服务器上离线下载,因此这里说的也是对对应于这种方式。
这里我下载的是harbor-offline-installer-v2.14.1.tgz,下载好后上传到服务器,然后解压
tar -zxvf harbor-offline-installer-v2.14.1.tgz
cd harbor
里面会看到有名为harbor.v2.14.1.tar.gz,这就是我们要用的镜像,如果不确定,就检查一下tar -tf harbor.v2.14.1.tar.gz | head,看一下是不是有相应的json, VERSION, layer.tar文件,是否符合镜像包结构。
这里我们采用ctr来将其导入到rke2使用的containerd中(注意这里的ctr要选用rke2的,namespace要指定为k8s.io):
sudo /var/lib/rancher/rke2/data/<your rke2 version>/bin/ctr -n k8s.io --address /run/k3s/containerd/conta inerd.sock images import --all-platforms harbor.v2.14.1.tar.gz
导入成功时应该会看到显示各个镜像都已经saved了,如果不放心可以检查一下:
sudo /var/lib/rancher/rke2/data/<your rke2 version>/bin/ctr \
-n k8s.io \
--address /run/k3s/containerd/containerd.sock \
images ls | grep goharbor
2. 开始部署
先创建Harbor的namespace
kubectl create namespace harbor
为了防止可能残留的数据(retained policy留下来的pvc绑定),处理一下PV的claimRef
kubectl patch pv pv-harbor-database -p '{"spec":{"claimRef": null}}'
kubectl patch pv pv-harbor-redis -p '{"spec":{"claimRef": null}}'
kubectl patch pv pv-harbor-registry -p '{"spec":{"claimRef": null}}'
kubectl patch pv pv-harbor-jobservice -p '{"spec":{"claimRef": null}}'
kubectl patch pv pv-harbor-trivy -p '{"spec":{"claimRef": null}}'
然后检查一下是不是上述Harbor所有的pv都已经变为available
kubectl get pv -n harbor
接下来在宿主机上检查是否已经创建了相应的存储目录,以及存储目录的权限设置问题。存储的目录可以先检查一下是不是已经存在,如果没有的话就要重新创建。
# 创建存储目录(如果尚未创建)
sudo mkdir -p /mnt/data/harbor/{database,redis,registry,jobservice,trivy}
然后查看一下redis和postgre用户的uid(这里新版的redis和postgre的uid都是999),然后为相应的文件夹设定权限:
sudo chown 999:999 /mnt/data/harbor/database
sudo chown 999:999 /mnt/data/harbor/redis
sudo chmod 755 /mnt/data/harbor/database
sudo chmod 755 /mnt/data/harbor/redis
其他几个组件可以看情况给设定权限。
接下来开始绑定pv和pvc,确保配置正确:
# 应用pv和pvc的绑定配置
kubectl apply -f harbor-pv.yaml
kubectl apply -f harbor-pvc.yaml
# 检查pvc绑定关系
kubectl get pvc -n harbor
如果看到对应输出的对应关系和状态没问题就可以用helm来安装了。
# 1. 添加 Harbor Helm 仓库(如果尚未添加)
helm repo add harbor https://helm.goharbor.io
helm repo update
# 2. 安装 Harbor
helm install harbor harbor/harbor -n harbor -f harbor-values.yaml
# 3. 等待安装完成,观察 Pod 状态
watch kubectl get pods -n harbor
如果说有问题,可以查看对应组件的日志
kubectl logs harbor-database-0 -n harbor
kubectl logs harbor-redis-0 -n harbor
安装完成后,就可以访问对应ip的30002端口(默认)来通过面板管理Harbor了。
Appendix
这是几个会用到的配置文件。
harbor-pv.yaml
# harbor-pv.yaml
# 快速配置PV:kubectl apply -f harbor-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-harbor-database
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /mnt/data/harbor/database
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-harbor-redis
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /mnt/data/harbor/redis
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-harbor-registry
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /mnt/data/harbor/registry
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-harbor-trivy
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /mnt/data/harbor/trivy
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-harbor-jobservice
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /mnt/data/harbor/jobservice
harbor-pvc.yaml
---
# 1. 数据库 PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: database-data-harbor-database-0
namespace: harbor
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
volumeName: pv-harbor-database # 绑定到正确的 PV
---
# 2. Redis PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data-harbor-redis-0
namespace: harbor
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
volumeName: pv-harbor-redis # 绑定到正确的 PV
---
# 3. Registry PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: harbor-registry-pvc
namespace: harbor
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
volumeName: pv-harbor-registry # 绑定到正确的 PV
---
# 4. JobService PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: harbor-jobservice-pvc
namespace: harbor
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
volumeName: pv-harbor-jobservice # 绑定到正确的 PV
---
# 5. Trivy PVC(如果启用)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: harbor-trivy-pvc
namespace: harbor
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
volumeName: pv-harbor-trivy # 绑定到正确的 PV
harbor-values.yaml
# harbor-values.yaml
# -----------------------
# 基本配置
# -----------------------
externalURL: "http://1.1.1.1" # your ip
harborAdminPassword: "Harbor12345"
expose:
type: nodePort
tls:
enabled: false
imagePullPolicy: IfNotPresent
# -----------------------
# 持久化存储配置
# -----------------------
# 1. 数据库持久化配置
database:
internal:
image:
repository: docker.io/goharbor/harbor-db
tag: v2.14.1
persistence:
enabled: true
existingClaim: "database-data-harbor-database-0" # 使用已有的PVC
# 注意:当指定 existingClaim 时,size 和 storageClass 会被忽略
# 2. Redis持久化配置
redis:
internal:
image:
repository: docker.io/goharbor/redis-photon
tag: v2.14.1
persistence:
enabled: true
existingClaim: "data-harbor-redis-0" # 使用已有的PVC
# 3. Registry持久化配置
registry:
registry:
image:
repository: docker.io/goharbor/registry-photon
tag: v2.14.1
controller:
image:
repository: docker.io/goharbor/harbor-registryctl
tag: v2.14.1
persistence:
enabled: true
existingClaim: "harbor-registry-pvc" # 需要创建这个PVC
# 4. JobService持久化配置
jobservice:
image:
repository: docker.io/goharbor/harbor-jobservice
tag: v2.14.1
persistence:
enabled: true
existingClaim: "harbor-jobservice-pvc" # 需要创建这个PVC
# 5. Trivy配置(如果需要)
trivy:
enabled: true # 根据你的需求启用或禁用
image:
repository: docker.io/goharbor/trivy-adapter-photon
tag: v2.14.1
persistence:
enabled: true
existingClaim: "harbor-trivy-pvc" # 需要创建这个PVC
# -----------------------
# 其他组件配置
# -----------------------
core:
image:
repository: docker.io/goharbor/harbor-core
tag: v2.14.1
portal:
image:
repository: docker.io/goharbor/harbor-portal
tag: v2.14.1
nginx:
image:
repository: docker.io/goharbor/nginx-photon
tag: v2.14.1
chartmuseum:
enabled: false
clair:
enabled: false
# 镜像拉取密钥(离线环境)
imagePullSecrets: []