Helm學習筆記


介紹:

  Helm 是 Kubernetes 生態系統中的一個軟件包管理工具。本文將介紹 Helm 中的相關概念和基本工作原理,並通過一個具體的示例學習如何使用 Helm 打包、分發、安裝、升級及回退 Kubernetes 應用。

Kubernetes 應用部署的挑戰

Kubernetes 是一個提供了基於容器的應用集群管理解決方案,Kubernetes 為容器化應用提供了部署運行、資源調度、服務發現和動態伸縮等一系列完整功能。

Kubernetes 的核心設計理念是: 用戶定義要部署的應用程序的規則,而 Kubernetes 則負責按照定義的規則部署並運行應用程序。如果應用程序出現問題導致偏離了定義的規格,Kubernetes 負責對其進行自動修正。例如:定義的應用規則要求部署兩個實例(Pod),其中一個實例異常終止了,Kubernetes 會檢查到並重新啟動一個新的實例。

用戶通過使用 Kubernetes API 對象來描述應用程序規則,包括 Pod、Service、Volume、Namespace、ReplicaSet、Deployment、Job等等。一般這些資源對象的定義需要寫入一系列的 YAML 文件中,然后通過 Kubernetes 命令行工具 Kubectl 調 Kubernetes API 進行部署。

以一個典型的三層應用 Wordpress 為例,該應用程序就涉及到多個 Kubernetes API 對象,而要描述這些 Kubernetes API 對象就可能要同時維護多個 YAML 文件。

從上圖可以看到,在進行 Kubernetes 軟件部署時,我們面臨下述幾個問題:

  • 如何管理、編輯和更新這些這些分散的 Kubernetes 應用配置文件。
  • 如何把一套相關的配置文件作為一個應用進行管理。
  • 如何分發和重用 Kubernetes 的應用配置。

Helm 的出現就是為了很好地解決上面這些問題。

一、Helm 是什么?

Helm 是 Deis 開發的一個用於 Kubernetes 應用的包管理工具,主要用來管理 Charts。有點類似於 Ubuntu 中的 APT 或 CentOS 中的 YUM。
Helm Chart 是用來封裝 Kubernetes 原生應用程序的一系列 YAML 文件。可以在你部署應用的時候自定義應用程序的一些 Metadata,以便於應用程序的分發。
對於應用發布者而言,可以通過 Helm 打包應用、管理應用依賴關系、管理應用版本並發布應用到軟件倉庫。
對於使用者而言,使用 Helm 后不用需要編寫復雜的應用部署文件,可以以簡單的方式在 Kubernetes 上查找、安裝、升級、回滾、卸載應用程序。

  • 基礎概念


    Helm:客戶端,主要負責管理本地的 Charts、repositories 以及與tiller服務器交互,發送Chart,實例安裝、查詢、卸載等操作;
    Tiller:安裝在 k8s 集群中的服務端,是實際用來管理安裝在 k8s 中應用的,就是將模板與 values 合並,當然實際開發過程中, 也可以安裝在 k8s 集群之外 ;接收helm發來的Charts與Config,合並生產relase;
    Chart:是用來管理模板與默認 values 的項目,也可以認為是一個 package,可以發布到專門的 repository;
    Repository: Chart倉庫,https/http服務器;
    Release:特定的Chart部署於目標集群上的一個實例;
    Release:使用 helm install 命令在 Kubernetes 集群中部署的 Chart 稱為 Release。

  • Helm 工作原理


這張圖描述了 Helm 的幾個關鍵組件 Helm(客戶端)、Tiller(服務器)、Repository(Chart 軟件倉庫)、Chart(軟件包)之間的關系。

 

  • Chart Install 過程


    Helm 從指定的目錄或者 TAR 文件中解析出 Chart 結構信息。
    Helm 將指定的 Chart 結構和 Values 信息通過 gRPC 傳遞給 Tiller。
    Tiller 根據 Chart 和 Values 生成一個 Release。
    Tiller 將 Release 發送給 Kubernetes 用於生成 Release。

  • Chart Update 過程


    Helm 從指定的目錄或者 TAR 文件中解析出 Chart 結構信息。
    Helm 將需要更新的 Release 的名稱、Chart 結構和 Values 信息傳遞給 Tiller。
    Tiller 生成 Release 並更新指定名稱的 Release 的 History。
    Tiller 將 Release 發送給 Kubernetes 用於更新 Release。

  • Chart Rollback 過程


    Helm 將要回滾的 Release 的名稱傳遞給 Tiller。
    Tiller 根據 Release 的名稱查找 History。
    Tiller 從 History 中獲取上一個 Release。
    Tiller 將上一個 Release 發送給 Kubernetes 用於替換當前 Release。

Chart 處理依賴說明

Tiller 在處理 Chart 時,直接將 Chart 以及其依賴的所有 Charts 合並為一個 Release,同時傳遞給 Kubernetes。因此 Tiller 並不負責管理依賴之間的啟動順序。Chart 中的應用需要能夠自行處理依賴關系。

二、Helm部署

安裝 Helm 客戶端
# 下載 Helm
$ wget https://storage.googleapis.com/kubernetes-helm/helm-v2.13.1-linux-amd64.tar.gz
# 解壓 Helm
$ tar -xf helm-v2.13.1-linux-amd64.tar.gz
# 復制客戶端執行文件到 bin 目錄下就可以用了
$ cp linux-amd64/helm /usr/local/bin/

安裝 Helm 服務器端 Tiller
官方地址:https://github.com/helm/helm/blob/master/docs/rbac.md
給 Tiller 授權
因為 Helm 的服務端 Tiller 是一個部署在 Kubernetes 中 Kube-System Namespace 下 的 Deployment,它會去連接 Kube-Api 在 Kubernetes 里創建和刪除應用。
而從 Kubernetes 1.6 版本開始,API Server 啟用了 RBAC 授權。目前的 Tiller 部署時默認沒有定義授權的 ServiceAccount,這會導致訪問 API Server 時被拒絕。所以我們需要明確為 Tiller 部署添加授權。
創建 Kubernetes 的服務帳號和綁定角色

[root@master helm]# cat rbac-config.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: tiller
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: tiller
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - kind: ServiceAccount
    name: tiller
    namespace: kube-system

$ kubectl create -f rbac-config.yaml

Tiller 是以 Deployment 方式部署在 Kubernetes 集群中的,只需使用以下指令便可簡單的完成安裝。

$ helm init --service-account tiller --history-max 200
$ kubectl get deployment --all-namespaces
NAMESPACE     NAME                   DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
kube-system   tiller-deploy          1         1         1            1           1h
$ kubectl create serviceaccount --namespace kube-system tiller
$ kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller

查看是否授權成功

$ kubectl get deploy --namespace kube-system   tiller-deploy  --output yaml|grep  serviceAccount
serviceAccount: tiller
serviceAccountName: tiller

驗證 Tiller 是否安裝成功

$ kubectl -n kube-system get pods|grep tiller
tiller-deploy-76cc4d8dd7-9npql   1/1       Running   0          13m

如下報錯:

[root@master helm]# helm version
Client: &version.Version{SemVer:"v2.13.1", GitCommit:"618447cbf203d147601b4b9bd7f8c37a5d39fbb4", GitTreeState:"clean"}
E0324 20:31:08.975504   25692 portforward.go:391] an error occurred forwarding 21997 -> 44134: error forwarding port 44134 to pod 22949bd678ee460bf0ca7d42a39e9d0b2f7a3e43793fc73f584240c3072bdb71, uid : unable
to do port forwarding: socat not found.E0324 20:31:09.979645   25692 portforward.go:391] an error occurred forwarding 21997 -> 44134: error forwarding port 44134 to pod 22949bd678ee460bf0ca7d42a39e9d0b2f7a3e43793fc73f584240c3072bdb71, uid : unable
to do port forwarding: socat not found.

解決辦法:在k8s的node節點安裝ssocat即可解決

$sudo yum install socat

 
卸載 Helm 服務器端 Tiller

如果你需要在 Kubernetes 中卸載已部署的 Tiller,可使用以下命令完成卸載。

$ helm reset

更新鏡像

$ helm  repo update

Helm常用命令:

    release管理:
        install
        delete
        upgrade/rollback
        list
        history
        status:獲取release狀態信息

    chart管理:
        create
        fetch
        get
        inspect
        package
        verify

三、構建一個 Helm Chart

Kubernetes官方鏡像地址:https://hub.kubeapps.com/
下面我們通過一個完整的示例來學習如何使用 Helm 創建、打包、分發、安裝、升級及回退Kubernetes應用。
創建一個名為 myapp 的 Chart

$ helm create myapp

該命令創建了一個 myapp 目錄,該目錄結構如下所示。這里我們主要關注目錄中的 Chart.yaml、values.yaml、NOTES.txt 和 Templates 目錄。

$ tree myapp/
myapp/
├── charts
├── Chart.yaml
├── templates
│   ├── deployment.yaml
│   ├── _helpers.tpl
│   ├── ingress.yaml
│   ├── NOTES.txt
│   └── service.yaml
└── values.yaml

2 directories, 7 files
  1.     Chart.yaml 用於描述這個 Chart的相關信息,包括名字、描述信息以及版本等。
  2.     values.yaml 用於存儲 templates 目錄中模板文件中用到變量的值。
  3.     NOTES.txt 用於介紹 Chart 部署后的一些信息,例如:如何使用這個 Chart、列出缺省的設置等。
  4.     Templates 目錄下是 YAML 文件的模板,該模板文件遵循 Go template 語法。

Templates 目錄下 YAML 文件模板的值默認都是在 values.yaml 里定義的,比如在 deployment.yaml 中定義的容器鏡像。

image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"

其中的 .Values.image.repository 的值就是在 values.yaml 里定義的 nginx,.Values.image.tag 的值就是 stable。

$ cat myapp/values.yaml|grep repository
repository: nginx

$ cat myapp/values.yaml|grep tag
tag: stable

以上兩個變量值是在 create chart 的時候就自動生成的默認值,你可以根據實際情況進行修改。

 如果你需要了解更多關於 Go 模板的相關信息,可以查看 Hugo 的一個關於 Go 模板 的介紹。

編寫應用的介紹信息

打開 Chart.yaml, 填寫你部署的應用的詳細信息,以 myapp 為例:

$ cat myapp/Chart.yaml
apiVersion: v1
appVersion: "1.0"
description: A Helm chart for Kubernetes
name: myapp
version: 0.1.0

編寫應用具體部署信息

編輯 values.yaml,它默認會在 Kubernetes 部署一個 Nginx。下面是 myapp 應用的 values.yaml 文件的內容:

$ cat myapp/values.yaml
# Default values for myapp.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

replicaCount: 1

image:
  repository: nginx
  tag: stable
  pullPolicy: IfNotPresent

service:
  type: ClusterIP
  port: 80

ingress:
  enabled: false
  annotations: {}
    # kubernetes.io/ingress.class: nginx
    # kubernetes.io/tls-acme: "true"
  path: /
  hosts:
    - chart-example.local
  tls: []
  #  - secretName: chart-example-tls
  #    hosts:
  #      - chart-example.local

resources: {}
  # We usually recommend not to specify default resources and to leave this as a conscious
  # choice for the user. This also increases chances charts run on environments with little
  # resources, such as Minikube. If you do want to specify resources, uncomment the following
  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
  # limits:
  #  cpu: 100m
  #  memory: 128Mi
  # requests:
  #  cpu: 100m
  #  memory: 128Mi

nodeSelector: {}

tolerations: []

affinity: {}

檢查依賴和模板配置是否正確

$ helm lint myapp/
==> Linting .
[INFO] Chart.yaml: icon is recommended

1 chart(s) linted, no failures

如果文件格式錯誤,可以根據提示進行修改。
將應用打包

$ helm package myapp
Successfully packaged chart and saved it to: /root/k8s_yaml/helm/myapp-0.1.0.tgz

myapp 目錄會被打包為一個 myapp-0.1.0.tgz 格式的壓縮包,該壓縮包會被放到當前目錄下,並同時被保存到了 Helm 的本地缺省倉庫目錄中。

如果你想看到更詳細的輸出,可以加上 --debug 參數來查看打包的輸出,輸出內容應該類似如下:

$ helm package myapp --debug
Successfully packaged chart and saved it to: /root/k8s_yaml/helm/myapp-0.1.0.tgz
[debug] Successfully saved /root/k8s_yaml/helm/myapp-0.1.0.tgz to /root/.helm/repository/local

將應用發布到 Repository

雖然我們已經打包了 Chart 並發布到了 Helm 的本地目錄中,但通過 helm search 命令查找,並不能找不到剛才生成的 myapp包。

$ helm search myapp
No results found

這是因為 Repository 目錄中的 Chart 包還沒有被 Helm 管理。通過 helm repo list 命令可以看到目前 Helm 中已配置的 Repository 的信息。

$ helm repo list
NAME    URL
stable  https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts

    注:新版本中執行 helm init 命令后默認會配置一個名為 local 的本地倉庫。

我們可以在本地啟動一個 Repository Server,並將其加入到 Helm Repo 列表中。Helm Repository 必須以 Web 服務的方式提供,這里我們就使用 helm serve 命令啟動一個 Repository Server,該 Server 缺省使用 $HOME/.helm/repository/local 目錄作為 Chart 存儲,並在 8879 端口上提供服務。

$ helm serve &
Now serving you on 127.0.0.1:8879

默認情況下該服務只監聽 127.0.0.1,如果你要綁定到其它網絡接口,可使用以下命令:

$ helm serve --address 192.168.100.211:8879 &

如果你想使用指定目錄來做為 Helm Repository 的存儲目錄,可以加上 --repo-path 參數:

$ helm serve --address 192.168.100.211:8879 --repo-path /data/helm/repository/ --url http://192.168.100.211:8879/charts/

通過 helm repo index 命令將 Chart 的 Metadata 記錄更新在 index.yaml 文件中:

# 更新 Helm Repository 的索引文件

$ cd /home/k8s/.helm/repository/local
$ helm repo index --url=http://192.168.100.211:8879 .

完成啟動本地 Helm Repository Server 后,就可以將本地 Repository 加入 Helm 的 Repo 列表。

$ helm repo add local http://127.0.0.1:8879
"local" has been added to your repositories

現在再次查找 myapp 包,就可以搜索到了。

$ helm repo update
$ helm search myapp
NAME             CHART VERSION    APP VERSION    DESCRIPTION
local/myapp    0.1.0            1.0            A Helm chart for Kubernetes

四、在 Kubernetes 中部署應用

部署一個應用
Chart 被發布到倉儲后,就可以通過 helm install 命令部署該 Chart。

  檢查配置和模板是否有效

當使用 helm install 命令部署應用時,實際上就是將 templates 目錄下的模板文件渲染成 Kubernetes 能夠識別的 YAML 格式。

在部署前我們可以使用 helm install --dry-run --debug <chart_dir> --name <release_name>命令來驗證 Chart 的配置。該輸出中包含了模板的變量配置與最終渲染的 YAML 文件。

[root@master ~]# helm install --dry-run --debug local/myapp --name myapp-test
[debug] Created tunnel using local port: '21619'

[debug] SERVER: "127.0.0.1:21619"

[debug] Original chart version: ""
[debug] Fetched local/myapp to /root/.helm/cache/archive/myapp-0.1.0.tgz

[debug] CHART PATH: /root/.helm/cache/archive/myapp-0.1.0.tgz

NAME:   myapp-test
REVISION: 1
RELEASED: Fri Apr  5 11:17:02 2019
CHART: myapp-0.1.0
USER-SUPPLIED VALUES:
{}

COMPUTED VALUES:
affinity: {}
fullnameOverride: ""
image:
  pullPolicy: IfNotPresent
  repository: nginx
  tag: stable
ingress:
  annotations: {}
  enabled: false
  hosts:
  - host: chart-example.local
    paths: []
  tls: []
nameOverride: ""
nodeSelector: {}
replicaCount: 1
resources: {}
service:
  port: 80
  type: ClusterIP
tolerations: []

HOOKS:
---
# myapp-test-test-connection
apiVersion: v1
kind: Pod
metadata:
  name: "myapp-test-test-connection"
  labels:
    app.kubernetes.io/name: myapp
    helm.sh/chart: myapp-0.1.0
    app.kubernetes.io/instance: myapp-test
    app.kubernetes.io/managed-by: Tiller
  annotations:
    "helm.sh/hook": test-success
spec:
  containers:
    - name: wget
      image: busybox
      command: ['wget']
      args:  ['myapp-test:80']
  restartPolicy: Never
MANIFEST:

---
# Source: myapp/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: myapp-test
  labels:
    app.kubernetes.io/name: myapp
    helm.sh/chart: myapp-0.1.0
    app.kubernetes.io/instance: myapp-test
    app.kubernetes.io/managed-by: Tiller
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app.kubernetes.io/name: myapp
    app.kubernetes.io/instance: myapp-test
---
# Source: myapp/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-test
  labels:
    app.kubernetes.io/name: myapp
    helm.sh/chart: myapp-0.1.0
    app.kubernetes.io/instance: myapp-test
    app.kubernetes.io/managed-by: Tiller
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: myapp
      app.kubernetes.io/instance: myapp-test
  template:
    metadata:
      labels:
        app.kubernetes.io/name: myapp
        app.kubernetes.io/instance: myapp-test
    spec:
      containers:
        - name: myapp
          image: "nginx:stable"
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /
              port: http
          readinessProbe:
            httpGet:
              path: /
              port: http
          resources:
            {}

驗證完成沒有問題后,我們就可以使用以下命令將其部署到 Kubernetes 上了。
# 部署時需指定 Chart 名及 Release(部署的實例)名。

[root@master ~]# helm install local/myapp --name myapp-test
NAME:   myapp-test
LAST DEPLOYED: Fri Apr  5 11:19:02 2019
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/Deployment
NAME        READY  UP-TO-DATE  AVAILABLE  AGE
myapp-test  0/1    0           0          0s

==> v1/Service
NAME        TYPE       CLUSTER-IP  EXTERNAL-IP  PORT(S)  AGE
myapp-test  ClusterIP  10.10.10.3  <none>       80/TCP   0s


NOTES:
1. Get the application URL by running these commands:
  export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=myapp,app.kubernetes.io/instance=myapp-test" -o jsonpath="{.items[0].metadata.name}")
  echo "Visit http://127.0.0.1:8080 to use your application"
  kubectl port-forward $POD_NAME 8080:80

    注:helm install 默認會用到 socat,需要在所有節點上安裝 socat 軟件包。

完成部署后,現在 Nginx 就已經部署到 Kubernetes 集群上。在本地主機上執行提示中的命令后,就可在本機訪問到該 Nginx 實例。

$ export POD_NAME=$(kubectl get pods --namespace default -l "app=myapp,release=myapp-test" -o jsonpath="{.items[0].metadata.name}")
$ echo "Visit http://127.0.0.1:8080 to use your application"
$ kubectl port-forward $POD_NAME 8080:80

在本地訪問 Nginx

$ curl http://127.0.0.1:8080
.....
<title>Welcome to nginx!</title>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
......

使用下面的命令列出的所有已部署的 Release 以及其對應的 Chart。

$ helm list
NAME          REVISION    UPDATED                     STATUS      CHART          APP VERSION    NAMESPACE
myapp-test    1           Fri Apr  5 11:19:02 2019    DEPLOYED    myapp-0.1.0    1.0            default

你還可以使用 helm status 查詢一個特定的 Release 的狀態。

[root@master k8s_yaml]# helm status myapp-test
LAST DEPLOYED: Fri Apr  5 11:19:02 2019
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/Deployment
NAME        READY  UP-TO-DATE  AVAILABLE  AGE
myapp-test  1/1    1           1          16m

==> v1/Pod(related)
NAME                         READY  STATUS   RESTARTS  AGE
myapp-test-854fbbc6dc-6h7sm  1/1    Running  0         16m

==> v1/Service
NAME        TYPE       CLUSTER-IP  EXTERNAL-IP  PORT(S)  AGE
myapp-test  ClusterIP  10.10.10.3  <none>       80/TCP   16m


NOTES:
1. Get the application URL by running these commands:
  export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=myapp,app.kubernetes.io/instance=myapp-test" -o jsonpath="{.items[0].metadata.name}")
  echo "Visit http://127.0.0.1:8080 to use your application"
  kubectl port-forward $POD_NAME 8080:80

升級和回退一個應用

從上面 helm list 輸出的結果中我們可以看到有一個 Revision(更改歷史)字段,該字段用於表示某一個 Release 被更新的次數,我們可以用該特性對已部署的 Release 進行回滾。

    修改 Chart.yaml 文件

將版本號從 0.1.0 修改為 0.2.0, 然后使用 helm package 命令打包並發布到本地倉庫。

$ cat myapp/Chart.yaml
apiVersion: v1
appVersion: "1.0"
description: A Helm chart for Kubernetes
name: myapp
version: 0.2.0

$ helm package myapp
Successfully packaged chart and saved it to: /root/k8s_yaml/helm/myapp-0.2.0.tgz

    查詢本地倉庫中的 Chart 信息

我們可以看到在本地倉庫中 myapp 有兩個版本。

$ helm search myapp -l
NAME             CHART VERSION    APP VERSION    DESCRIPTION
local/myapp    0.2.0            1.0            A Helm chart for Kubernetes
local/myapp    0.1.0            1.0            A Helm chart for Kubernetes

 升級一個應用
現在用 helm upgrade 命令將已部署的 mike-test 升級到新版本。你可以通過 --version 參數指定需要升級的版本號,如果沒有指定版本號,則缺省使用最新版本。

[root@master helm]# helm upgrade myapp-test local/myapp
Release "myapp-test" has been upgraded. Happy Helming!
LAST DEPLOYED: Fri Apr  5 11:39:38 2019
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/Deployment
NAME        READY  UP-TO-DATE  AVAILABLE  AGE
myapp-test  1/1    1           1          20m

==> v1/Pod(related)
NAME                         READY  STATUS   RESTARTS  AGE
myapp-test-854fbbc6dc-6h7sm  1/1    Running  0         20m

==> v1/Service
NAME        TYPE       CLUSTER-IP  EXTERNAL-IP  PORT(S)  AGE
myapp-test  ClusterIP  10.10.10.3  <none>       80/TCP   20m


NOTES:
1. Get the application URL by running these commands:
  export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=myapp,app.kubernetes.io/instance=myapp-test" -o jsonpath="{.items[0].metadata.name}")
  echo "Visit http://127.0.0.1:8080 to use your application"
  kubectl port-forward $POD_NAME 8080:80

完成后,可以看到已部署的 mike-test 被升級到 0.2.0 版本。

[root@master helm]# helm list
NAME          REVISION    UPDATED                     STATUS      CHART          APP VERSION    NAMESPACE
myapp-test    2           Fri Apr  5 11:39:38 2019    DEPLOYED    myapp-0.2.0    1.0            default  

 回滾一個應用

如果更新后的程序由於某些原因運行有問題,需要回退到舊版本的應用。首先我們可以使用 helm history 命令查看一個 Release 的所有變更記錄。

[root@master helm]# helm history  myapp-test
REVISION    UPDATED                     STATUS        CHART          DESCRIPTION     
1           Fri Apr  5 11:19:02 2019    SUPERSEDED    myapp-0.1.0    Install complete
2           Fri Apr  5 11:39:38 2019    DEPLOYED      myapp-0.2.0    Upgrade complete

其次,我們可以使用下面的命令對指定的應用進行回退。

$ helm rollback myapp-test 1
Rollback was a success! Happy Helming!

    注:其中的參數 1 是 helm history 查看到 Release 的歷史記錄中 REVISION 對應的值。

最后,我們使用 helm list 和 helm history 命令都可以看到 myapp 的版本已經回退到 0.1.0 版本。

$ helm list
NAME          REVISION    UPDATED                     STATUS      CHART          APP VERSION    NAMESPACE
myapp-test    3           Fri Apr  5 11:42:13 2019    DEPLOYED    myapp-0.1.0    1.0            default  

$ helm history myapp-test
REVISION    UPDATED                     STATUS        CHART          DESCRIPTION     
1           Fri Apr  5 11:19:02 2019    SUPERSEDED    myapp-0.1.0    Install complete
2           Fri Apr  5 11:39:38 2019    SUPERSEDED    myapp-0.2.0    Upgrade complete
3           Fri Apr  5 11:42:13 2019    DEPLOYED      myapp-0.1.0    Rollback to 1 

刪除一個應用

如果需要刪除一個已部署的 Release,可以利用 helm delete 命令來完成刪除。

$ helm delete myapp-test
release "myapp-test" deleted

確認應用是否刪除,該應用已被標記為 DELETED 狀態。

$ helm ls -a myapp-test
NAME          REVISION    UPDATED                     STATUS     CHART          APP VERSION    NAMESPACE
myapp-test    3           Fri Apr  5 11:42:13 2019    DELETED    myapp-0.1.0    1.0            default  

也可以使用 --deleted 參數來列出已經刪除的 Release

$ helm ls --deleted
NAME          REVISION    UPDATED                     STATUS     CHART              APP VERSION    NAMESPACE
mem1          1           Sun Mar 24 20:58:18 2019    DELETED    memcached-2.7.0    1.5.12         default  
myapp-test    3           Fri Apr  5 11:42:13 2019    DELETED    myapp-0.1.0        1.0            default  
redis1        1           Sun Mar 24 21:03:33 2019    DELETED    redis-6.4.3        4.0.14         default  

從上面的結果也可以看出,默認情況下已經刪除的 Release 只是將狀態標識為 DELETED 了 ,但該 Release 的歷史信息還是繼續被保存的。

$ helm hist myapp-test
REVISION    UPDATED                     STATUS        CHART          DESCRIPTION      
1           Fri Apr  5 11:19:02 2019    SUPERSEDED    myapp-0.1.0    Install complete
2           Fri Apr  5 11:39:38 2019    SUPERSEDED    myapp-0.2.0    Upgrade complete
3           Fri Apr  5 11:42:13 2019    DELETED       myapp-0.1.0    Deletion complete

如果要移除指定 Release 所有相關的 Kubernetes 資源和 Release 的歷史記錄,可以用如下命令:

$ helm delete --purge myapp-test
release "myapp-test" deleted

再次查看已刪除的 Release,已經無法找到相關信息。

$ helm hist mike-test
Error: release: "myapp-test" not found

# helm ls 命令也已均無查詢記錄。

$ helm ls --deleted
$ helm ls -a mike-test
helm ls --all linuxhub-redis;
helm del --purge linuxhub-redis;

 

五、Helm 其它使用技巧

  如何設置 helm 命令自動補全?

為了方便 helm 命令的使用,Helm 提供了自動補全功能,如果使用 ZSH 請執行:

$ source <(helm completion zsh)

如果使用 BASH 請執行:

$ source <(helm completion bash)

    如何使用第三方的 Chart 存儲庫?

隨着 Helm 越來越普及,除了使用預置官方存儲庫,三方倉庫也越來越多了(前提是網絡是可達的)。你可以使用如下命令格式添加三方 Chart 存儲庫。

$ helm repo add 存儲庫名 存儲庫URL
$ helm repo update

一些三方存儲庫資源:

# Prometheus Operator
https://github.com/coreos/prometheus-operator/tree/master/helm

# Bitnami Library for Kubernetes
https://github.com/bitnami/charts

# Openstack-Helm
https://github.com/att-comdev/openstack-helm
https://github.com/sapcc/openstack-helm

# Tick-Charts
https://github.com/jackzampolin/tick-charts

六、Helm 如何結合 CI/CD ?

采用 Helm 可以把零散的 Kubernetes 應用配置文件作為一個 Chart 管理,Chart 源碼可以和源代碼一起放到 Git 庫中管理。通過把 Chart 參數化,可以在測試環境和生產環境采用不同的 Chart 參數配置。

下圖是采用了 Helm 的一個 CI/CD 流程


    Helm 如何管理多環境下 (Test、Staging、Production) 的業務配置?

Chart 是支持參數替換的,可以把業務配置相關的參數設置為模板變量。使用 helm install 命令部署的時候指定一個參數值文件,這樣就可以把業務參數從 Chart 中剝離了。例如: helm install --values=values-production.yaml wordpress。

    Helm 如何解決服務依賴?

在 Chart 里可以通過 requirements.yaml 聲明對其它 Chart 的依賴關系。如下面聲明表明 Chart 依賴 Apache 和 MySQL 這兩個第三方 Chart。

dependencies:
- name: mariadb
  version: 2.1.1
  repository: https://kubernetes-charts.storage.googleapis.com/
  condition: mariadb.enabled
  tags:
    - wordpress-database
- name: apache
    version: 1.4.0
    repository: https://kubernetes-charts.storage.googleapis.com/

    如何讓 Helm 連接到指定 Kubernetes 集群?

Helm 默認使用和 kubectl 命令相同的配置訪問 Kubernetes 集群,其配置默認在 ~/.kube/config 中。

    如何在部署時指定命名空間?

helm install 默認情況下是部署在 default 這個命名空間的。如果想部署到指定的命令空間,可以加上 --namespace 參數,比如:

$ helm install local/myapp --name mike-test --namespace mynamespace

    如何查看已部署應用的詳細信息?

$ helm get myapp-test

默認情況下會顯示最新的版本的相關信息,如果想要查看指定發布版本的信息可加上 --revision 參數。

$ helm get  --revision 1  myapp-test

 參考:
https://daemonza.github.io/2017/02/20/using-helm-to-deploy-to-kubernetes/


免責聲明!

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



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