Helm


認識Helm
  1. 為什么有helm?

  2. Helm是什么?

    kubernetes的包管理器,“可以將Helm看作Linux系統下的apt-get/yum”。

    • 對於應用發布者而言,可以通過Helm打包應用,管理應用依賴關系,管理應用版本並發布應用到軟件倉庫。

    • 對於使用者而言,使用Helm后不用需要了解Kubernetes的Yaml語法並編寫應用部署文件,可以通過Helm下載並在kubernetes上安裝需要的應用。

    除此以外,Helm還提供了kubernetes上的軟件部署,刪除,升級,回滾應用的強大功能。

  3. Helm的版本

    • helm2
      image
      C/S架構,helm通過Tiller與k8s交互

    • helm3
      image

      • 從安全性和易用性方面考慮,移除了Tiller服務端,helm3直接使用kubeconfig文件鑒權訪問APIServer服務器

      • 由二路合並升級成為三路合並補丁策略( 舊的配置,線上狀態,新的配置 )

        helm install very_important_app ./very_important_app
        

        這個應用的副本數量設置為 3 。現在,如果有人不小心執行了 kubectl edit 或:

        kubectl scale -replicas=0 deployment/very_important_app
        

        然后,團隊中的某個人發現 very_important_app 莫名其妙宕機了,嘗試執行命令:

        helm rollback very_important_app
        

        在 Helm 2 中,這個操作將比較舊的配置與新的配置,然后生成一個更新補丁。由於,誤操作的人僅修改了應用的線上狀態(舊的配置並未更新)。Helm 在回滾時,什么事情也不會做。因為舊的配置與新的配置沒有差別(都是 3 個副本)。然后,Helm 不執行回滾,副本數繼續保持為 0

      • 移除了helm serve本地repo倉庫

      • 創建應用時必須指定名字(或者--generate-name隨機生成)

  4. Helm的重要概念

    • chart,應用的信息集合,包括各種對象的配置模板、參數定義、依賴關系、文檔說明等
    • Repoistory,chart倉庫,存儲chart的地方,並且提供了一個該 Repository 的 Chart 包的清單文件以供查詢。Helm 可以同時管理多個不同的 Repository。
    • release, 當 chart 被安裝到 kubernetes 集群,就生成了一個 release , 是 chart 的運行實例,代表了一個正在運行的應用

helm 是包管理工具,包就是指 chart,helm 能夠:

  • 從零創建chart
  • 與倉庫交互,拉取、保存、更新 chart
  • 在kubernetes集群中安裝、卸載 release
  • 更新、回滾、測試 release
安裝與快速入門實踐

下載最新的穩定版本:https://get.helm.sh/helm-v3.2.4-linux-amd64.tar.gz

更多版本可以參考: https://github.com/helm/helm/releases

# k8s-master節點
$ wget https://get.helm.sh/helm-v3.2.4-linux-amd64.tar.gz
$ tar -zxf helm-v3.2.4-linux-amd64.tar.gz

$ cp linux-amd64/helm /usr/local/bin/

# 驗證安裝
$ helm version
version.BuildInfo{Version:"v3.2.4", GitCommit:"0ad800ef43d3b826f31a5ad8dfbb4fe05d143688", GitTreeState:"clean", GoVersion:"go1.13.12"}
$ helm env

# 添加倉庫
$ helm repo add stable http://mirror.azure.cn/kubernetes/charts/
# 同步最新charts信息到本地
$ helm repo update


快速入門實踐:

示例一:使用helm安裝mysql應用

# helm 搜索chart包
$ helm search repo mysql

# 從倉庫安裝
$ helm install mysql stable/mysql

$ helm ls
$ kubectl get all 

# 從chart倉庫中把chart包下載到本地
$ helm pull stable/mysql
$ tree mysql

示例二:新建nginx的chart並安裝

$ helm create nginx

# 從本地安裝
$ helm install nginx ./nginx

# 安裝到別的命名空間luffy
$ helm -n luffy install ./nginx

# 查看
$ helm ls
$ helm -n luffy ls

#
$ kubectl get all 
$ kubectl -n luffy get all
Chart的模板語法及開發
nginx的chart實現分析

格式:

$ tree nginx/
nginx/
├── charts						# 存放子chart
├── Chart.yaml					# 該chart的全局定義信息
├── templates					# chart運行所需的資源清單模板,用於和values做渲染
│   ├── deployment.yaml
│   ├── _helpers.tpl			# 定義全局的命名模板,方便在其他模板中引入使用
│   ├── hpa.yaml
│   ├── ingress.yaml
│   ├── NOTES.txt				# helm安裝完成后終端的提示信息
│   ├── serviceaccount.yaml
│   ├── service.yaml
│   └── tests
│       └── test-connection.yaml
└── values.yaml					# 模板使用的默認值信息

很明顯,資源清單都在templates中,數據來源於values.yaml,安裝的過程就是將模板與數據融合成k8s可識別的資源清單,然后部署到k8s環境中。

分析模板文件的實現:

  • 引用命名模板並傳遞作用域

    {{ include "nginx.fullname" . }}
    

    include從_helpers.tpl中引用命名模板,並傳遞頂級作用域.

  • 內置對象

    .Values
    .Release.Name
    
    
    • Release:該對象描述了 release 本身的相關信息,它內部有幾個對象:
      • Release.Name:release 名稱
      • Release.Namespace:release 安裝到的命名空間
      • Release.IsUpgrade:如果當前操作是升級或回滾,則該值為 true
      • Release.IsInstall:如果當前操作是安裝,則將其設置為 true
      • Release.Revision:release 的 revision 版本號,在安裝的時候,值為1,每次升級或回滾都會增加
      • Reelase.Service:渲染當前模板的服務,在 Helm 上,實際上該值始終為 Helm
    • Values:從 values.yaml 文件和用戶提供的 values 文件傳遞到模板的 Values 值
    • Chart:獲取 Chart.yaml 文件的內容,該文件中的任何數據都可以訪問,例如 {{ .Chart.Name }}-{{ .Chart.Version}} 可以渲染成 mychart-0.1.0
  • 模板定義

    {{- define "nginx.fullname" -}}
    {{- if .Values.fullnameOverride }}
    {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
    {{- else }}
    {{- $name := default .Chart.Name .Values.nameOverride }}
    {{- if contains $name .Release.Name }}
    {{- .Release.Name | trunc 63 | trimSuffix "-" }}
    {{- else }}
    {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
    {{- end }}
    {{- end }}
    {{- end }}
    
    • {{- 去掉左邊的空格及換行,-}} 去掉右側的空格及換行

    • 示例

      apiVersion: v1
      kind: ConfigMap
      metadata:
        name: {{ .Release.Name }}-configmap
      data:
        myvalue: "Hello World"
        drink: {{ .Values.favorite.drink | default "tea" | quote }}
        food: {{ .Values.favorite.food | upper | quote }}
        {{ if eq .Values.favorite.drink "coffee" }}
        mug: true
        {{ end }}
      

      渲染完后是:

      apiVersion: v1
      kind: ConfigMap
      metadata:
        name: mychart-1575971172-configmap
      data:
        myvalue: "Hello World"
        drink: "coffee"
        food: "PIZZA"
      
        mug: true
      
  • 管道及方法

    • trunc表示字符串截取,63作為參數傳遞給trunc方法,trimSuffix表示去掉-后綴

      {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
      
    • nindent表示前面的空格數

        selector:
          matchLabels:
            {{- include "nginx.selectorLabels" . | nindent 6 }}
      
    • lower表示將內容小寫,quote表示用雙引號引起來

      value: {{ include "mytpl" . | lower | quote }}
      
  • 條件判斷語句每個if對應一個end

    {{- if .Values.fullnameOverride }}
    ...
    {{- else }}
    ...
    {{- end }}
    

    通常用來根據values.yaml中定義的開關來控制模板中的顯示:

    {{- if not .Values.autoscaling.enabled }}
      replicas: {{ .Values.replicaCount }}
    {{- end }}
    
  • 定義變量,模板中可以通過變量名字去引用

    {{- $name := default .Chart.Name .Values.nameOverride }}
    
  • 遍歷values的數據

          {{- with .Values.nodeSelector }}
          nodeSelector:
            {{- toYaml . | nindent 8 }}
          {{- end }}
    

    toYaml處理值中的轉義及特殊字符, "kubernetes.io/role"=master , name="value1,value2" 類似的情況

  • default設置默認值

    image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
    

hpa.yaml

{{- if .Values.autoscaling.enabled }}
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
  name: {{ include "nginx.fullname" . }}
  labels:
    {{- include "nginx.labels" . | nindent 4 }}
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: {{ include "nginx.fullname" . }}
  minReplicas: {{ .Values.autoscaling.minReplicas }}
  maxReplicas: {{ .Values.autoscaling.maxReplicas }}
  metrics:
  {{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
    - type: Resource
      resource:
        name: cpu
        targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
  {{- end }}
  {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
    - type: Resource
      resource:
        name: memory
        targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
  {{- end }}
{{- end }}
創建應用的時候賦值
  • set的方式
# 改變副本數和resource值
$ helm install nginx-2 ./nginx --set replicaCount=2 --set resources.limits.cpu=200m --set resources.limits.memory=256Mi

  • value文件的方式

    $ cat nginx-values.yaml
    resources:
      limits:
        cpu: 100m
        memory: 128Mi
      requests:
        cpu: 100m
        memory: 128Mi
    autoscaling:
      enabled: true
      minReplicas: 1
      maxReplicas: 3
      targetCPUUtilizationPercentage: 80
    ingress:
      enabled: true
      hosts:
        - host: chart-example.luffy.com
          paths:
          - /
    
    $ helm install -f nginx-values.yaml nginx-3 ./nginx
    

更多語法參考:

https://helm.sh/docs/topics/charts/

部署mysql失敗的問題

使用Helm部署Harbor鏡像及chart倉庫
harbor踩坑部署

架構 https://github.com/goharbor/harbor/wiki/Architecture-Overview-of-Harbor
image

  • Core,核心組件
    • API Server,接收處理用戶請求
    • Config Manager :所有系統的配置,比如認證、郵件、證書配置等
    • Project Manager:項目管理
    • Quota Manager :配額管理
    • Chart Controller:chart管理
    • Replication Controller :鏡像副本控制器,可以與不同類型的倉庫實現鏡像同步
    • Distribution (docker registry)
    • Docker Hub
    • ...
    • Scan Manager :掃描管理,引入第三方組件,進行鏡像安全掃描
    • Registry Driver :鏡像倉庫驅動,目前使用docker registry
  • Job Service,執行異步任務,如同步鏡像信息
  • Log Collector,統一日志收集器,收集各模塊日志
  • GC Controller
  • Chart Museum,chart倉庫服務,第三方
  • Docker Registry,鏡像倉庫服務
  • kv-storage,redis緩存服務,job service使用,存儲job metadata
  • local/remote storage,存儲服務,比較鏡像存儲
  • SQL Database,postgresl,存儲用戶、項目等元數據

通常用作企業級鏡像倉庫服務,實際功能強大很多。

組件眾多,因此使用helm部署

# 添加harbor chart倉庫
$ helm repo add harbor https://helm.goharbor.io

# 搜索harbor的chart
$ helm search repo harbor

# 不知道如何部署,因此拉到本地
$ helm pull harbor/harbor --version 1.4.1

創建pvc

$ kubectl create namespace harbor
$ cat harbor-pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: harbor-pvc
  namespace: harbor
spec:
  accessModes:     
    - ReadWriteOnce
  storageClassName: dynamic-cephfs
  resources:
    requests:
      storage: 20Gi

修改harbor配置:

  • 開啟ingress訪問
  • externalURL,web訪問入口,和ingress的域名相同
  • 持久化,使用PVC對接的cephfs
  • harborAdminPassword: "Harbor12345",管理員默認賬戶 admin/Harbor12345
  • 開啟chartmuseum
  • clair和trivy漏洞掃描組件,暫不啟用

helm創建:

# 使用本地chart安裝
$ helm install harbor ./harbor -n harbor 

踩坑一:redis持久化數據目錄權限導致無法登錄

redis數據目錄,/var/lib/redis,需要設置redis的用戶及用戶組權限

      initContainers:
      - name: "change-permission-of-directory"
        image: {{ .Values.database.internal.initContainerImage.repository }}:{{ .Values.database.internal.initContainerImage.tag }}
        imagePullPolicy: {{ .Values.imagePullPolicy }}
        command: ["/bin/sh"]
        args: ["-c", "chown -R 999:999 /var/lib/redis"]
        volumeMounts:
        - name: data
          mountPath: /var/lib/redis
          subPath: {{ $redis.subPath }}

踩坑二:registry組件的鏡像存儲目錄權限導致鏡像推送失敗

registry的鏡像存儲目錄,需要設置registry用戶的用戶及用戶組,不然鏡像推送失敗

      initContainers:
      - name: "change-permission-of-directory"
        image: {{ .Values.database.internal.initContainerImage.repository }}:{{ .Values.database.internal.initContainerImage.tag }}
        imagePullPolicy: {{ .Values.imagePullPolicy }}
        command: ["/bin/sh"]
        args: ["-c", "chown -R 10000:10000 {{ .Values.persistence.imageChartStorage.filesystem.rootdirectory }}"]
        volumeMounts:
        - name: registry-data
          mountPath: {{ .Values.persistence.imageChartStorage.filesystem.rootdirectory }}
          subPath: {{ .Values.persistence.persistentVolumeClaim.registry.subPath }}

踩坑三:chartmuseum存儲目錄權限,導致chart推送失敗

      initContainers:
      - name: "change-permission-of-directory"
        image: {{ .Values.database.internal.initContainerImage.repository }}:{{ .Values.database.internal.initContainerImage.tag }}
        imagePullPolicy: {{ .Values.imagePullPolicy }}
        command: ["/bin/sh"]
        args: ["-c", "chown -R 10000:10000 /chart_storage"]
        volumeMounts:
        - name: chartmuseum-data
          mountPath: /chart_storage
          subPath: {{ .Values.persistence.persistentVolumeClaim.chartmuseum.subPath }}

更新內容后,執行更新release

$ helm upgrade harbor -n harbor ./
推送鏡像到Harbor倉庫

配置hosts及docker非安全倉庫:

$ cat /etc/hosts
...
192.168.136.10 k8s-master core.harbor.domain
...

$ cat /etc/docker/daemon.json
{                                            
  "insecure-registries": [                   
    "192.168.136.10:5000",                   
    "core.harbor.domain"                     
  ],                                         
  "registry-mirrors" : [                     
    "https://8xpk5wnt.mirror.aliyuncs.com"   
  ]                                          
}                           

#
$ systemctl restart docker

# 使用賬戶密碼登錄admin/Harbor12345
$ docker login core.harbor.domain

$ docker tag nginx:alpine core.harbor.domain/library/nginx:alpine
$ docker push core.harbor.domain/library/nginx:alpine
推送chart到Harbor倉庫

helm3默認沒有安裝helm push插件,需要手動安裝。插件地址 https://github.com/chartmuseum/helm-push

安裝插件:

$ helm plugin install https://github.com/chartmuseum/helm-push

離線安裝:

$ helm plugin install ./helm-push

添加repo

$ helm repo add myharbor https://core.harbor.domain/chartrepo/library 
# x509錯誤

# 添加證書信任,根證書為配置給ingress使用的證書
$ kubectl get secret harbor-harbor-ingress -n harbor -o jsonpath="{.data.ca\.crt}" | base64 -d >harbor.ca.crt

$ cp harbor.ca.crt /etc/pki/ca-trust/source/anchors
$ update-ca-trust enable; update-ca-trust extract

# 再次添加
$ helm repo add myharbor https://core.harbor.domain/chartrepo/library --ca-file=harbor.ca.crt

$ helm repo ls

推送chart到倉庫:

$ helm push harbor myharbor --ca-file=harbor.ca.crt -u admin -p Harbor12345

查看harbor倉庫的chart


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM