「开源摘星计划」Helm部署高可用Harbor镜像仓库

1,381 阅读5分钟

【摘要】使用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: