【摘要】使用Helm包管理工具将harbor部署在kubernetes集群中。
【文章来源】《Harbor进阶实战》公众号
开源摘星计划(WeOpen Star) 是由腾源会 2022 年推出的全新项目,旨在为开源人提供成长激励,为开源项目提供成长支持,助力开发者更好地了解开源,更快地跨越鸿沟,参与到开源的具体贡献与实践中。
不管你是开源萌新,还是希望更深度参与开源贡献的老兵,跟随“开源摘星计划”开启你的开源之旅,从一篇学习笔记、到一段代码的提交,不断挖掘自己的潜能,最终成长为开源社区的“闪亮之星”。
我们将同你一起,探索更多的可能性!
项目地址: WeOpen-Star:github.com/weopenproje…
前言
我在前面的文章中介绍了离线安装、在线安装等Harbor的部署方式,但其缺点都是无法做高可用,在实际的业务场景中一旦Harbor服务器异常,将会造成很大的影响。
对应前面的几种部署方式,官方也并没有给出高可用的支持方案,如果要支持,则需要对Harbor有一定程度上的了解。# 「开源摘星计划」
对于Harbor的高可用方案,可将Harbor部署在kubernetes集群中,利用其特点即可实现Harbor的高可用。
环境准备
1.1 创建命名空间
在kubernetes集群的master
节点操作。
$ kubectl create namespace harbor
namespace/harbor created
1.2 部署Helm
helm是命令行客户端工具,主要用于 Kubernetes 应用中的 chart 的创建、打包、发布和管理。
$ wget https://get.helm.sh/helm-v3.7.2-linux-amd64.tar.gz
$ tar zxvf helm-v3.7.2-linux-amd64.tar.gz
$ cd linux-amd64/
$ cp helm /usr/local/bin/
$ helm version
version.BuildInfo{Version:"v3.7.2", GitCommit:"663a896f4a815053445eec4153677ddc24a0a361", GitTreeState:"clean", GoVersion:"go1.16.10"}
1.3 部署NFS服务端
使用nfs网络共享为Harbor提供持久化存储,需要部署NFS服务端并创建共享目录。
1)部署NFS服务
$ yum install -y nfs-utils
$ systemctl start nfs && systemctl enable nfs && systemctl status nfs
$ chkconfig nfs on #设置为开机自启
注意:正在将请求转发到“systemctl enable nfs.service”。
2)配置共享目录
- 创建共享目录
$ mkdir -p /app/nfs/harbor
- 允许哪个网段的客户端使用指定共享目录
$ cat /etc/exports
/app/nfs/harbor 192.168.2.0/24(rw,no_root_squash
- 使配置文件生效
$ exportfs -arv
exporting 192.168.2.0/24:/app/nfs/harbor
$ systemctl restart nfs
- 检查共享目录信息
$ showmount -e localhost
Export list for localhost:
/app/nfs/harbor 192.168.2.0/24
3)安装客户端驱动
客户端使用NFS服务,则必须安装nfs客户端驱动。kubernetes集群的每个节点主机都需要安装。
$ yum -y install nfs-utils
$ systemctl start nfs-utils
$ systemctl enable nfs-utils
$ systemctl status nfs-utils
4)创建nfs-provisioner
$ kubectl apply -f nfs-provisioner.yaml
$ cat nfs-provisioner.yaml
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-provisioner
namespace: harbor
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: nfs-provisioner-runner
rules:
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get","list","watch","create","delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaimes"]
verbs: ["get","list","watch","update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get","list","watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["create","update","patch"]
- apiGroups: [""]
resources: ["services","endpoints"]
verbs: ["get"]
- apiGroups: ["extensions"]
resources: ["podsecuritypolicies"]
resourceNames: ["nfs-provisioner"]
verbs: ["use"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: run-nfs-provisioner
subjects:
- kind: ServiceAccount
name: nfs-provisioner
namespace: harbor
roleRef:
kind: ClusterRole
name: nfs-provisioner-runner
apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: leader-locking-nfs-provisioner
namespace: harbor
rules:
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: leader-locking-nfs-provisioner
namespace: harbor
roleRef:
kind: Role
name: leader-locking-nfs-provisioner
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: nfs-provisioner
namespace: harbor
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-provisioner
namespace: harbor
spec:
selector:
matchLabels:
app: nfs-provisioner
replicas: 1
strategy: #策略
type: Recreate
template:
metadata:
labels:
app: nfs-provisioner
spec:
serviceAccount: nfs-provisioner #sa账号名称
containers:
- name: nfs-provisioner
image: registry.cn-beijing.aliyuncs.com/mydlq/nfs-subdir-external-provisioner:v4.0.0
imagePullPolicy: IfNotPresent
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: example.com/nfs #供应商名称
- name: NFS_SERVER
value: 192.168.2.30 #NFS服务端地址
- name: NFS_PATH
value: /app/nfs/harbor #共享目录
volumes:
- name: nfs-client-root
nfs:
server: 192.168.2.30
path: /app/nfs/harbor
$ kubectl -n harbor get po
NAME READY STATUS RESTARTS AGE
nfs-provisioner-5b7f8884df-kfclm 1/1 Running 0 7s
$ kubectl -n harbor logs nfs-provisioner-5b7f8884df-kfclm
1.4 创建StorageClass
使用StorageClass动态为Harbor划分pv持久卷。
$ cat <<EOF > harbor-storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: harbor-storageclass
namespace: harbor
provisioner: example.com/nfs # 指定外部存储供应商
EOF
$ kubectl apply -f harbor-storageclass.yaml
$ kubectl -n harbor get storageclass
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
harbor-storageclass example.com/nfs Delete Immediate false 14s
Helm部署Harbor
2.1 添加Harbor 官方Helm Chart仓库
Harbor官方提供了Helm chart仓库,可使用其来部署Harbor。
$ helm repo add harbor https://helm.goharbor.io
$ helm repo list
NAME URL
bitnami https://charts.bitnami.com/bitnami
stable https://charts.helm.sh/stable
harbor https://helm.goharbor.io
2.2 下载载Chart包到本地
因为需要修改的参数比较多,在命令行直接helm install比较复杂,我就将Chart包下载到本地,再修改一些配置,这样比较直观,也比较符合实际工作中的业务环境(内外环境)。
1)搜索Chart包
列出最新3个版本的包
$ helm search repo harbor -l | grep harbor/harbor | head -4
harbor/harbor 1.10.0 2.6.0 An open source trusted cloud native registry th...
harbor/harbor 1.9.4 2.5.4 An open source trusted cloud native registry th...
harbor/harbor 1.9.3 2.5.3 An open source trusted cloud native registry th...
harbor/harbor 1.9.2 2.5.2 An open source trusted cloud native registry th...
2)下载Chart包
下载Chart包到本地。
$ helm pull harbor/harbor --version 1.10.0
$ ls
anaconda-ks.cfg harbor-1.10.0.tgz
通过--version
下载指定版本的Chart,这里下载最新版Harbor v2.6.0对应的为1.10.0
3)解压Chart包
将刚才下载到本地的Chart包解压。
$ tar zxvf harbor-1.10.0.tgz
$ cd harbor/
$ ls
cert Chart.yaml conf LICENSE README.md templates values.yaml
2.3 修改values.yaml配置
$
expose:
type: nodePort #将ingress修改为nodePort(我这没有Ingress环境,使用NodePort的服务访问方式)。
tls:
enabled: false #关闭tls安全加密认证(如果开启需要配置证书)
#使用nodePort且关闭tls认证,则此处需要修改为http协议和expose.nodePort.ports.http.nodePort指定的端口号,IP即为kubernetes的节点IP地址
externalURL: http:192.168.2.20:30006
# 持久化存储配置部分
persistence:
enabled: true # 开启持久化存储
resourcePolicy: "keep"
persistentVolumeClaim: # 定义Harbor各个组件的PVC持久卷部分
registry: # registry组件(持久卷)配置部分
existingClaim: ""
storageClass: "harbor-storageclass" # 前面创建的StorageClass,其它组件同样配置
subPath: ""
accessMode: ReadWriteMany # 卷的访问模式,需要修改为ReadWriteMany,允许多个组件读写,否则有的组件无法读取其它组件的数据
size: 5Gi
chartmuseum: #chartmuseum组件(持久卷)配置部分
existingClaim: ""
storageClass: "harbor-storageclass"
subPath: ""
accessMode: ReadWriteMany
size: 5Gi
jobservice: #异步任务组件(持久卷)配置部分
existingClaim: ""
storageClass: "harbor-storageclass" #修改,同上
subPath: ""
accessMode: ReadWriteOnce
size: 1Gi
database: # PostgreSQl数据库组件(持久卷)配置部分
existingClaim: ""
storageClass: "harbor-storageclass"
subPath: ""
accessMode: ReadWriteMany
size: 1Gi
redis: # Redis缓存组件(持久卷)配置部分
existingClaim: ""
storageClass: "harbor-storageclass"
subPath: ""
accessMode: ReadWriteMany
size: 1Gi
trivy: # Trity漏洞扫描插件(持久卷)配置部分
existingClaim: ""
storageClass: "harbor-storageclass"
subPath: ""
accessMode: ReadWriteMany
size: 5Gi
如果不需要持久化将persistence.enabled的值修改为false即可。
2.4 安装Harbor
$ helm install harbor . -n harbor
$ helm -n harbor ls
2.5 验证服务状态
验证服务状态是否正常!
$ kubectl -n harbor get po
$ kubectl -n harbor get svc
2.6 登录Harbor UI
在浏览器输入刚才配置的地址访问Harbor UI管理界面。
卸载Harbor集群
$ helm -n harbor ls
$ helm uninstall harbor -n harbor
These resources were kept due to the resource policy: