天天看點

Helm部署Harbor,實作高可用的鏡像倉庫(超詳細分享)~後附踩坑記錄

目錄

  • 前言:從業務場景看Harbor部署
  • 1、部署說明
  • 2、安裝Helm
  • 2.1 下載下傳helm二進制包
  • 2.2 檢視helm版本
  • 2.3 添加Harbor 官方Helm Chart倉庫
  • 2.4 下載下傳Chart包到本地
  • 3、建立命名空間
  • 4、建立NFS外部供應商
  • 4.1 部署NFS服務端
  • 4.2  安裝用戶端
  • 4.3 建立運作的sa賬号并做RBAC授權
  • 5、建立存儲類(StorageClass)
  • 6、修改values.yaml配置
  • 7、執行helm install安裝Harbor
  • 8、服務驗證
  • 9、登入Harbor UI界面
  • 10、那些我踩過的坑
  • 10.1 第一個坑、
  • 10.2 第二個坑、UI界面提示“使用者或者密碼不正确“

🐖大家好!我是李大白!

🐂本篇文章主要分享使用Helm在kubernetes叢集中部署Harbor詳細的操作方法。本文收錄于《Harbor大白話(企業級)》,更多Harbor相關的知識可檢視我首頁。

Helm部署Harbor,實作高可用的鏡像倉庫(超詳細分享)~後附踩坑記錄

前言:從業務場景看Harbor部署

我在前面的文章中介紹了離線安裝、線上安裝等Harbor的部署方式,但其缺點都是無法做高可用,在實際的業務場景中一旦Harbor伺服器異常,将會造成很大的影響。

對應前面的幾種部署方式,官方也并沒有給出高可用的支援方案,如果要支援,則需要對Harbor有一定程度上的了解。

      對于Harbor的高可用方案,可将Harbor部署在kubernetes叢集中,利用其 特點即可實作Harbor的高可用。

1、部署說明

  • 1台NFS伺服器(可使用kubernetes叢集任一節點做NFS服務端)
  • 1個kubernetes叢集(1master,2node組成的3節點叢集)
  • 作業系統: CentOS-7.8
  • Harbor版本:2.4.2
Helm部署Harbor,實作高可用的鏡像倉庫(超詳細分享)~後附踩坑記錄

2、安裝Helm

helm是指令行用戶端工具,主要用于 Kubernetes 應用中的 chart 的建立、打包、釋出和管理。

在kubernetes叢集master節點安裝

2.1 下載下傳helm二進制包

$ 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/      

2.2 檢視helm版本

$ helm version
version.BuildInfo{Version:"v3.6.3", GitCommit:"d506314abfb5d21419df8c7e7e68012379db2354", GitTreeState:"clean", GoVersion:"go1.16.5"}      

2.3 添加Harbor 官方Helm Chart倉庫

$ helm repo add harbor  https://helm.goharbor.io
"harbor" has been added to your repositories
$ helm repo  list                  # 檢視添加的Chart
NAME    URL                     
harbor  https://helm.goharbor.io      

2.4 下載下傳Chart包到本地

     因為需要修改的參數比較多,在指令行直接helm install比較複雜,我就将Chart包下載下傳到本地,再修改一些配置,這樣比較直覺,也比較符合實際工作中的業務環境。

$ helm search repo harbor         # 搜尋chart包
NAME          CHART VERSION APP VERSION DESCRIPTION                                       
harbor/harbor 1.8.2         2.4.2       An open source trusted cloud native registry th...
$ helm pull harbor/harbor   # 下載下傳Chart包
$ tar zxvf harbor-1.8.2.tgz   # 解壓包      
Helm部署Harbor,實作高可用的鏡像倉庫(超詳細分享)~後附踩坑記錄

3、建立命名空間

       建立harbor命名空間,将Harbor相關的服務都部署在該命名空間中。

$ kubectl create namespace harbor      

4、建立NFS外部供應商

本處使用NFS為存儲,需要提供外部供應商,如果你有該供應商,可跳過本步驟。

4.1 部署NFS服務端

在NFS伺服器(192.168.2.212)部署NFS服務

$ yum  install -y  nfs-utils 
$ systemctl start nfs && systemctl enable nfs  
$ systemctl status nfs
$ chkconfig nfs on              #設定為開機自啟
注意:正在将請求轉發到“systemctl enable nfs.service”。
$ mkdir  -p  /data/nfs/harbor        #建立共享目錄
$ cat /etc/exports
/data/nfs/harbor   192.168.2.0/24(rw,no_root_squash)
$ exportfs -arv            # 使配置檔案生效
exporting 192.168.2.0/24:/data/v1
$ systemctl restart nfs
$ showmount  -e localhost                     #檢查共享目錄資訊
Export list for localhost:
/data/nfs/harbor     192.168.2.0/24      

4.2  安裝用戶端

本處用戶端即為kubernets叢集的每一個節點,若Pod排程到的節點沒有該服務,則無法使用對應的存儲卷。

$ yum -y install nfs-utils
$ systemctl start nfs-utils &&  systemctl enable nfs-utils 
$ systemctl status  nfs-utils      

4.3 建立運作的sa賬号并做RBAC授權

$ vim 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-cr
rules:
 - apiGroups: [""]
   resources: ["persistentvolumes"]
   verbs: ["get", "list", "watch", "create", "delete"]
 - apiGroups: [""]
   resources: ["persistentvolumeclaims"]
   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"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: run-nfs-provisioner
subjects:
  - kind: ServiceAccount
    name: nfs-provisioner
    namespace: harbor
roleRef:
  kind: ClusterRole
  name: nfs-provisioner-cr
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: nfs-role
  namespace: harbor
rules:
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get","list","watch","create","update","patch"]

---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-provisioner
  namespace: harbor
subjects:
 - kind: ServiceAccount
   name: nfs-provisioner
   namespace: harbor
roleRef:
 kind: Role
 name: nfs-role
 apiGroup: rbac.authorization.k8s.io

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs-proversitioner
  namespace: harbor
spec:
  selector:
    matchLabels:
      app: nfs-provisioner
  replicas: 1
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: nfs-provisioner
    spec:
      serviceAccount: nfs-provisioner
      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.212
          - name: NFS_PATH
            value: /data/nfs/harbor
      volumes:
      - name: nfs-client-root
        nfs:
          server: 192.168.2.212   #  NFS服務端位址
          path: /data/nfs/harbor  # NFS共享目錄      

🐖:部署Deployment使用的鏡像是從阿裡雲拉取的。

建立資源對象:

$ kubectl apply -f nfs-provisioner.yaml
$ kubectl -n harbor get pod 
nfs-proversitioner-7b4c6cc9bf-s48ld     1/1     Running   1    10s      

5、建立存儲類(StorageClass)

Harbor的database和redis元件是為有狀态服務,需要對Harbor資料做持久化存儲。

本處基于NFS建立StorageClass存儲類,使用NFS外部供應商可閱讀我首頁文章,NFS伺服器和共享目錄為:

  • - NFS伺服器位址:192.168.2.212
  • - NFS共享目錄:/data/nfs/harbor
$ vim harbor-storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: harbor-storageclass
  namespace: harbor
provisioner: example.com/nfs    # 指定外部存儲供應商
$ 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                  5s      

6、修改values.yaml配置

Helm部署Harbor,實作高可用的鏡像倉庫(超詳細分享)~後附踩坑記錄

重點!重點!重點!  踩坑最多的地方來了!

$ cd harbor    
$ ls
cert  Chart.yaml  conf  LICENSE  README.md  templates  values.yaml
$ vim  values.yaml
expose:
  type: nodePort         # 我這沒有Ingress環境,使用NodePort的服務通路方式。   
  tls:
    enabled: false    # 關閉tls安全加密認證(如果開啟需要配置證書)
...
externalURL: http://192.168.2.11:30002   # 使用nodePort且關閉tls認證,則此處需要修改為http協定和expose.nodePort.ports.http.nodePort指定的端口号,IP即為kubernetes的節點IP位址

# 持久化存儲配置部分
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
...
harborAdminPassword: "Harbor12345"   # admin初始密碼,不需要修改
...
metrics:
  enabled: true  # 是否啟用監控元件(可以使用Prometheus監控Harbor名額,具體見本專欄文章),非必須操作
  core:
    path: /metrics
    port: 8001
  registry:
    path: /metrics
    port: 8001
  jobservice:
    path: /metrics
    port: 8001
  exporter:
    path: /metrics
    port: 8001
###以下的trace為2.4版本的功能,不需要修改。      
Helm部署Harbor,實作高可用的鏡像倉庫(超詳細分享)~後附踩坑記錄

擴充:

如果不希望安裝最新的版本,可以通過以下指令修改鏡像版本号來安裝指定的版本。

$ sed  -i   /tag/s/v2.4.2/v2.3.5/g  values.yaml      

7、執行helm install安裝Harbor

$ helm install  harbor  .  -n harbor        # 将安裝資源部署到harbor命名空間
NAME: harbor
LAST DEPLOYED: Mon Apr 11 23:32:18 2022
NAMESPACE: harbor
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Please wait for several minutes for Harbor deployment to complete.
Then you should be able to visit the Harbor portal at http://192.168.2.11:30002
For more details, please visit https://github.com/goharbor/harbor      

🐖:-n前有個點,表示目前路徑。

8、服務驗證

      安裝完成後,需要驗證相關元件的服務是否正常!

$ kubectl -n harbor get pod -owide
NAME                                    READY   STATUS    RESTARTS   AGE     IP               NODE       NOMINATED NODE   READINESS GATES
harbor-chartmuseum-b95bd8d89-z6b6b      1/1     Running   0          3m45s   10.244.242.191   sc-node2   <none>           <none>
harbor-core-6dc985545-gtv24             1/1     Running   0          3m45s   10.244.242.132   sc-node2   <none>           <none>
harbor-database-0                       1/1     Running   0          3m45s   10.244.242.187   sc-node2   <none>           <none>
harbor-exporter-6fcfb5f4cd-w2r7w        1/1     Running   0          3m45s   10.244.242.145   sc-node2   <none>           <none>
harbor-jobservice-77f9dff7dc-cpf55      1/1     Running   1          3m45s   10.244.242.186   sc-node2   <none>           <none>
harbor-nginx-8fc4874cb-lbj5p            1/1     Running   0          3m45s   10.244.242.189   sc-node2   <none>           <none>
harbor-notary-server-58c576f48f-lx9s5   1/1     Running   0          3m45s   10.244.242.188   sc-node2   <none>           <none>
harbor-notary-signer-c6cc544f5-dnvbl    1/1     Running   0          3m45s   10.244.119.235   sc-node1   <none>           <none>
harbor-portal-86bb5f6dd9-f4jhj          1/1     Running   0          3m45s   10.244.242.129   sc-node2   <none>           <none>
harbor-redis-0                          1/1     Running   0          3m45s   10.244.119.240   sc-node1   <none>           <none>
harbor-registry-6c69986589-gks8d        2/2     Running   0          3m45s   10.244.242.185   sc-node2   <none>           <none>
harbor-trivy-0                          1/1     Running   0          3m45s   10.244.119.233   sc-node1   <none>           <none>
nfs-proversitioner-7b4c6cc9bf-s48ld     1/1     Running   1          34h     10.244.242.137   sc-node2   <none>           <none>      

9、登入Harbor UI界面

檢視元件服務

$ kubectl -n harbor get  svc
NAME                   TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                       AGE
harbor                 NodePort    10.101.62.113    <none>        80:30002/TCP,4443:30004/TCP   5m39s
harbor-chartmuseum     ClusterIP   10.104.151.56    <none>        80/TCP                        5m39s
harbor-core            ClusterIP   10.104.102.203   <none>        80/TCP,8001/TCP               5m39s
harbor-database        ClusterIP   10.106.44.67     <none>        5432/TCP                      5m39s
harbor-exporter        ClusterIP   10.107.133.10    <none>        8001/TCP                      5m39s
harbor-jobservice      ClusterIP   10.105.117.160   <none>        80/TCP,8001/TCP               5m39s
harbor-notary-server   ClusterIP   10.111.124.94    <none>        4443/TCP                      5m39s
harbor-notary-signer   ClusterIP   10.101.166.147   <none>        7899/TCP                      5m39s
harbor-portal          ClusterIP   10.99.47.180     <none>        80/TCP                        5m39s
harbor-redis           ClusterIP   10.106.107.194   <none>        6379/TCP                      5m39s
harbor-registry        ClusterIP   10.105.154.142   <none>        5000/TCP,8080/TCP,8001/TCP    5m39s
harbor-trivy           ClusterIP   10.105.243.164   <none>        8080/TCP                      5m39s      

使用kubernetes任一節點主機IP和30002端口即可通路UI管理界面。

Helm部署Harbor,實作高可用的鏡像倉庫(超詳細分享)~後附踩坑記錄
Helm部署Harbor,實作高可用的鏡像倉庫(超詳細分享)~後附踩坑記錄

妥了!獎勵自己一包親嘴燒!

10、那些我踩過的坑

這些坑都是我在Helm安裝Harbor的時候踩過(隻列出部分),你們躺平就好,直接過。

10.1 第一個坑、

執行`helm install  harbor  . -n harbor`安裝出現的坑

Error: execution error at (harbor/templates/nginx/secret.yaml:3:12):

The "expose.tls.auto.commonName" is required!

Helm部署Harbor,實作高可用的鏡像倉庫(超詳細分享)~後附踩坑記錄

報錯原因:values.yaml檔案中expose.tls.auto.commonName是必填項。

解決:将expose.tls.enabled的值改為false,即不啟用tls加密通信,使用tls就需要配置相關證書了,該報錯是啟用tls但是又沒有配置證書,所有報錯!

10.2 第二個坑、UI界面提示“使用者名或者密碼不正确”

天知道我被這個問題困擾了多久,看了github上的issue也有很多人遇到,但是都沒有能解決,在1.x版本這是個bug,後來的版本說是修複了,可這是最新版,不應該呀!

Helm部署Harbor,實作高可用的鏡像倉庫(超詳細分享)~後附踩坑記錄
Helm部署Harbor,實作高可用的鏡像倉庫(超詳細分享)~後附踩坑記錄

issue編号635

原因: