Helm 是 Kubernetes 生態系統中的一個軟件包管理工具。本文將介紹 Helm 中的相關概念和基本工做原理,並經過一個具體的示例學習如何使用 Helm 打包、分發、安裝、升級及回退 Kubernetes 應用。node
Kubernetes 應用部署的挑戰
Kubernetes 是一個提供了基於容器的應用集羣管理解決方案,Kubernetes 爲容器化應用提供了部署運行、資源調度、服務發現和動態伸縮等一系列完整功能。linux
Kubernetes 的核心設計理念是: 用戶定義要部署的應用程序的規則,而 Kubernetes 則負責按照定義的規則部署並運行應用程序。若是應用程序出現問題致使偏離了定義的規格,Kubernetes 負責對其進行自動修正。例如:定義的應用規則要求部署兩個實例(Pod),其中一個實例異常終止了,Kubernetes 會檢查到並從新啓動一個新的實例。nginx
用戶經過使用 Kubernetes API 對象來描述應用程序規則,包括 Pod、Service、Volume、Namespace、ReplicaSet、Deployment、Job等等。通常這些資源對象的定義須要寫入一系列的 YAML 文件中,而後經過 Kubernetes 命令行工具 Kubectl 調 Kubernetes API 進行部署。git
以一個典型的三層應用 Wordpress 爲例,該應用程序就涉及到多個 Kubernetes API 對象,而要描述這些 Kubernetes API 對象就可能要同時維護多個 YAML 文件。github
![](http://static.javashuo.com/static/loading.gif)
從上圖能夠看到,在進行 Kubernetes 軟件部署時,咱們面臨下述幾個問題:web
- 如何管理、編輯和更新這些這些分散的 Kubernetes 應用配置文件。
- 如何把一套相關的配置文件做爲一個應用進行管理。
- 如何分發和重用 Kubernetes 的應用配置。
Helm 的出現就是爲了很好地解決上面這些問題。apache
Helm 是什麼?
Helm 是 Deis 開發的一個用於 Kubernetes 應用的包管理工具,主要用來管理 Charts。有點相似於 Ubuntu 中的 APT 或 CentOS 中的 YUM。json
Helm Chart 是用來封裝 Kubernetes 原生應用程序的一系列 YAML 文件。能夠在你部署應用的時候自定義應用程序的一些 Metadata,以便於應用程序的分發。api
對於應用發佈者而言,能夠經過 Helm 打包應用、管理應用依賴關係、管理應用版本併發布應用到軟件倉庫。bash
對於使用者而言,使用 Helm 後不用須要編寫複雜的應用部署文件,能夠以簡單的方式在 Kubernetes 上查找、安裝、升級、回滾、卸載應用程序。
Helm 組件及相關術語
Helm 是一個命令行下的客戶端工具。主要用於 Kubernetes 應用程序 Chart 的建立、打包、發布以及建立和管理本地和遠程的 Chart 倉庫。
Tiller 是 Helm 的服務端,部署在 Kubernetes 集羣中。Tiller 用於接收 Helm 的請求,並根據 Chart 生成 Kubernetes 的部署文件( Helm 稱爲 Release ),而後提交給 Kubernetes 建立應用。Tiller 還提供了 Release 的升級、刪除、回滾等一系列功能。
Helm 的軟件包,採用 TAR 格式。相似於 APT 的 DEB 包或者 YUM 的 RPM 包,其包含了一組定義 Kubernetes 資源相關的 YAML 文件。
Helm 的軟件倉庫,Repository 本質上是一個 Web 服務器,該服務器保存了一系列的 Chart 軟件包以供用戶下載,而且提供了一個該 Repository 的 Chart 包的清單文件以供查詢。Helm 能夠同時管理多個不一樣的 Repository。
使用 helm install
命令在 Kubernetes 集羣中部署的 Chart 稱爲 Release。
注:須要注意的是:Helm 中提到的 Release 和咱們一般概念中的版本有所不一樣,這裏的 Release 能夠理解爲 Helm 使用 Chart 包部署的一個應用實例。
Helm 工做原理
這張圖描述了 Helm 的幾個關鍵組件 Helm(客戶端)、Tiller(服務器)、Repository(Chart 軟件倉庫)、Chart(軟件包)之間的關係。
![](http://static.javashuo.com/static/loading.gif)
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 的安裝方式不少,這裏採用二進制的方式安裝。更多安裝方法能夠參考 Helm 的官方幫助文檔。
1 2 3
|
$ curl https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get > get_helm.sh $ chmod 700 get_helm.sh $ ./get_helm.sh
|
1 2 3 4 5 6
|
# 下載 Helm $ wget https://storage.googleapis.com/kubernetes-helm/helm-v2.9.1-linux-amd64.tar.gz # 解壓 Helm $ tar -zxvf helm-v2.9.1-linux-amd64.tar.gz # 複製客戶端執行文件到 bin 目錄下 $ cp linux-amd64/helm /usr/local/bin/
|
注:storage.googleapis.com 默認是不能訪問的,該問題請自行解決。
安裝 Helm 服務器端 Tiller
Tiller 是以 Deployment 方式部署在 Kubernetes 集羣中的,只需使用如下指令即可簡單的完成安裝。
因爲 Helm 默認會去 storage.googleapis.com 拉取鏡像,若是你當前執行的機器不能訪問該域名的話可使用如下命令來安裝:
1 2
|
# 使用阿里雲鏡像安裝並把默認倉庫設置爲阿里雲上的鏡像倉庫 $ helm init --upgrade --tiller-image registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:v2.9.1 --stable-repo-url https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
|
給 Tiller 受權
由於 Helm 的服務端 Tiller 是一個部署在 Kubernetes 中 Kube-System Namespace 下 的 Deployment,它會去鏈接 Kube-Api 在 Kubernetes 裏建立和刪除應用。
而從 Kubernetes 1.6 版本開始,API Server 啓用了 RBAC 受權。目前的 Tiller 部署時默認沒有定義受權的 ServiceAccount,這會致使訪問 API Server 時被拒絕。因此咱們須要明確爲 Tiller 部署添加受權。
1 2 3 4 5
|
$ 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
|
1 2 3
|
# 使用 kubectl patch 更新 API 對象 $ kubectl patch deploy --namespace kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}' deployment.extensions "tiller-deploy" patched
|
1 2 3
|
$ kubectl get deploy --namespace kube-system tiller-deploy --output yaml|grep serviceAccount serviceAccount: tiller serviceAccountName: tiller
|
驗證 Tiller 是否安裝成功
1 2 3 4 5 6
|
$ kubectl -n kube-system get pods|grep tiller tiller-deploy-6d68f5c78f-nql2z 1/1 Running 0 5m
$ helm version Client: &version.Version{SemVer:"v2.9.1", GitCommit:"20adb27c7c5868466912eebdf6664e7390ebe710", GitTreeState:"clean"} Server: &version.Version{SemVer:"v2.9.1", GitCommit:"20adb27c7c5868466912eebdf6664e7390ebe710", GitTreeState:"clean"}
|
卸載 Helm 服務器端 Tiller
若是你須要在 Kubernetes 中卸載已部署的 Tiller,可以使用如下命令完成卸載。
構建一個 Helm Chart
下面咱們經過一個完整的示例來學習如何使用 Helm 建立、打包、分發、安裝、升級及回退Kubernetes應用。
建立一個名爲 mychart 的 Chart
該命令建立了一個 mychart 目錄,該目錄結構以下所示。這裏咱們主要關注目錄中的 Chart.yaml、values.yaml、NOTES.txt 和 Templates 目錄。
1 2 3 4 5 6 7 8 9 10 11 12 13
|
$ tree mychart/ mychart/ ├── charts ├── Chart.yaml ├── templates │ ├── deployment.yaml │ ├── _helpers.tpl │ ├── ingress.yaml │ ├── NOTES.txt │ └── service.yaml └── values.yaml
2 directories, 7 files
|
- Chart.yaml 用於描述這個 Chart的相關信息,包括名字、描述信息以及版本等。
- values.yaml 用於存儲 templates 目錄中模板文件中用到變量的值。
- NOTES.txt 用於介紹 Chart 部署後的一些信息,例如:如何使用這個 Chart、列出缺省的設置等。
- Templates 目錄下是 YAML 文件的模板,該模板文件遵循 Go template 語法。
Templates 目錄下 YAML 文件模板的值默認都是在 values.yaml 裏定義的,好比在 deployment.yaml 中定義的容器鏡像。
1
|
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
|
其中的 .Values.image.repository
的值就是在 values.yaml 裏定義的 nginx,.Values.image.tag
的值就是 stable。
1 2 3 4 5
|
$ cat mychart/values.yaml|grep repository repository: nginx
$ cat mychart/values.yaml|grep tag tag: stable
|
以上兩個變量值是在 create chart
的時候就自動生成的默認值,你能夠根據實際狀況進行修改。
若是你須要瞭解更多關於 Go 模板的相關信息,能夠查看 Hugo 的一個關於 Go 模板 的介紹。
編寫應用的介紹信息
打開 Chart.yaml, 填寫你部署的應用的詳細信息,以 mychart 爲例:
1 2 3 4 5 6
|
$ cat mychart/Chart.yaml apiVersion: v1 appVersion: "1.0" description: A Helm chart for Kubernetes name: mychart version: 0.1.0
|
編寫應用具體部署信息
編輯 values.yaml,它默認會在 Kubernetes 部署一個 Nginx。下面是 mychart 應用的 values.yaml 文件的內容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
|
$ cat mychart/values.yaml # Default values for mychart. # 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: {}
|
檢查依賴和模板配置是否正確
1 2 3 4 5
|
$ helm lint mychart/ ==> Linting . [INFO] Chart.yaml: icon is recommended
1 chart(s) linted, no failures
|
若是文件格式錯誤,能夠根據提示進行修改。
將應用打包
1 2
|
$ helm package mychart Successfully packaged chart and saved it to: /home/k8s/mychart-0.1.0.tgz
|
mychart 目錄會被打包爲一個 mychart-0.1.0.tgz 格式的壓縮包,該壓縮包會被放到當前目錄下,並同時被保存到了 Helm 的本地缺省倉庫目錄中。
若是你想看到更詳細的輸出,能夠加上 --debug
參數來查看打包的輸出,輸出內容應該相似以下:
1 2 3
|
$ helm package mychart --debug Successfully packaged chart and saved it to: /home/k8s/mychart-0.1.0.tgz [debug] Successfully saved /home/k8s/mychart-0.1.0.tgz to /home/k8s/.helm/repository/local
|
將應用發佈到 Repository
雖然咱們已經打包了 Chart 併發布到了 Helm 的本地目錄中,但經過 helm search
命令查找,並不能找不到剛纔生成的 mychart包。
1 2
|
$ helm search mychart No results found
|
這是由於 Repository 目錄中的 Chart 包尚未被 Helm 管理。經過 helm repo list
命令能夠看到目前 Helm 中已配置的 Repository 的信息。
1 2 3
|
$ 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 端口上提供服務。
1 2
|
$ helm serve & Now serving you on 127.0.0.1:8879
|
默認狀況下該服務只監聽 127.0.0.1,若是你要綁定到其它網絡接口,可以使用如下命令:
1
|
$ helm serve --address 192.168.100.211:8879 &
|
若是你想使用指定目錄來作爲 Helm Repository 的存儲目錄,能夠加上 --repo-path
參數:
1
|
$ 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 文件中:
1 2 3
|
# 更新 Helm Repository 的索引文件 $ cd /home/k8s/.helm/repository/local $ helm repo index --url=http://192.168.100.211:8879 .
|
完成啓動本地 Helm Repository Server 後,就能夠將本地 Repository 加入 Helm 的 Repo 列表。
1 2
|
$ helm repo add local http://127.0.0.1:8879 "local" has been added to your repositories
|
如今再次查找 mychart 包,就能夠搜索到了。
1 2 3 4
|
$ helm repo update $ helm search mychart NAME CHART VERSION APP VERSION DESCRIPTION local/mychart 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 文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
|
$ helm install --dry-run --debug local/mychart --name mike-test [debug] Created tunnel using local port: '46649'
[debug] SERVER: "127.0.0.1:46649"
[debug] Original chart version: "" [debug] Fetched local/mychart to /home/k8s/.helm/cache/archive/mychart-0.1.0.tgz
[debug] CHART PATH: /home/k8s/.helm/cache/archive/mychart-0.1.0.tgz
NAME: mike-test REVISION: 1 RELEASED: Mon Jul 23 10:39:49 2018 CHART: mychart-0.1.0 USER-SUPPLIED VALUES: {}
COMPUTED VALUES: affinity: {} image: pullPolicy: IfNotPresent repository: nginx tag: stable ingress: annotations: {} enabled: false hosts: - chart-example.local path: / tls: [] nodeSelector: {} replicaCount: 1 resources: {} service: port: 80 type: ClusterIP tolerations: []
HOOKS: MANIFEST:
--- # Source: mychart/templates/service.yaml apiVersion: v1 kind: Service metadata: name: mike-test-mychart labels: app: mychart chart: mychart-0.1.0 release: mike-test heritage: Tiller spec: type: ClusterIP ports: - port: 80 targetPort: http protocol: TCP name: http selector: app: mychart release: mike-test --- # Source: mychart/templates/deployment.yaml apiVersion: apps/v1beta2 kind: Deployment metadata: name: mike-test-mychart labels: app: mychart chart: mychart-0.1.0 release: mike-test heritage: Tiller spec: replicas: 1 selector: matchLabels: app: mychart release: mike-test template: metadata: labels: app: mychart release: mike-test spec: containers: - name: mychart image: "nginx:stable" imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80 protocol: TCP livenessProbe: httpGet: path: / port: http readinessProbe: httpGet: path: / port: http resources: {}
|
驗證完成沒有問題後,咱們就可使用如下命令將其部署到 Kubernetes 上了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
# 部署時需指定 Chart 名及 Release(部署的實例)名。 $ helm install local/mychart --name mike-test NAME: mike-test LAST DEPLOYED: Mon Jul 23 10:41:20 2018 NAMESPACE: default STATUS: DEPLOYED
RESOURCES: ==> v1/Service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mike-test-mychart ClusterIP 10.254.120.177 <none> 80/TCP 1s
==> v1beta2/Deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE mike-test-mychart 1 0 0 0 0s
==> v1/Pod(related) NAME READY STATUS RESTARTS AGE mike-test-mychart-6d56f8c8c9-d685v 0/1 Pending 0 0s
NOTES: 1. Get the application URL by running these commands: export POD_NAME=$(kubectl get pods --namespace default -l "app=mychart,release=mike-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 實例。
1 2 3
|
$ export POD_NAME=$(kubectl get pods --namespace default -l "app=mychart,release=mike-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
1 2 3 4 5 6 7 8
|
$ 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。
1 2 3
|
$ helm list NAME REVISION UPDATED STATUS CHART NAMESPACE mike-test 1 Mon Jul 23 10:41:20 2018 DEPLOYED mychart-0.1.0 default
|
你還可使用 helm status
查詢一個特定的 Release 的狀態。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
$ helm status mike-test LAST DEPLOYED: Mon Jul 23 10:41:20 2018 NAMESPACE: default STATUS: DEPLOYED
RESOURCES: ==> v1/Pod(related) NAME READY STATUS RESTARTS AGE mike-test-mychart-6d56f8c8c9-d685v 1/1 Running 0 1m
==> v1/Service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mike-test-mychart ClusterIP 10.254.120.177 <none> 80/TCP 1m
==> v1beta2/Deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE mike-test-mychart 1 1 1 1 1m
NOTES: 1. Get the application URL by running these commands: export POD_NAME=$(kubectl get pods --namespace default -l "app=mychart,release=mike-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 進行回滾。
將版本號從 0.1.0 修改成 0.2.0, 而後使用 helm package
命令打包併發布到本地倉庫。
1 2 3 4 5 6 7 8 9
|
$ cat mychart/Chart.yaml apiVersion: v1 appVersion: "1.0" description: A Helm chart for Kubernetes name: mychart version: 0.2.0
$ helm package mychart Successfully packaged chart and saved it to: /home/k8s/mychart-0.2.0.tgz
|
咱們能夠看到在本地倉庫中 mychart 有兩個版本。
1 2 3 4
|
$ helm search mychart -l NAME CHART VERSION APP VERSION DESCRIPTION local/mychart 0.2.0 1.0 A Helm chart for Kubernetes local/mychart 0.1.0 1.0 A Helm chart for Kubernetes
|
如今用 helm upgrade
命令將已部署的 mike-test 升級到新版本。你能夠經過 --version
參數指定須要升級的版本號,若是沒有指定版本號,則缺省使用最新版本。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
$ helm upgrade mike-test local/mychart Release "mike-test" has been upgraded. Happy Helming! LAST DEPLOYED: Mon Jul 23 10:50:25 2018 NAMESPACE: default STATUS: DEPLOYED
RESOURCES: ==> v1/Pod(related) NAME READY STATUS RESTARTS AGE mike-test-mychart-6d56f8c8c9-d685v 1/1 Running 0 9m
==> v1/Service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mike-test-mychart ClusterIP 10.254.120.177 <none> 80/TCP 9m
==> v1beta2/Deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE mike-test-mychart 1 1 1 1 9m
NOTES: 1. Get the application URL by running these commands: export POD_NAME=$(kubectl get pods --namespace default -l "app=mychart,release=mike-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 版本。
1 2 3
|
$ helm list NAME REVISION UPDATED STATUS CHART NAMESPACE mike-test 2 Mon Jul 23 10:50:25 2018 DEPLOYED mychart-0.2.0 default
|
若是更新後的程序因爲某些緣由運行有問題,須要回退到舊版本的應用。首先咱們可以使用 helm history
命令查看一個 Release 的全部變動記錄。
1 2 3 4
|
$ helm history mike-test REVISION UPDATED STATUS CHART DESCRIPTION 1 Mon Jul 23 10:41:20 2018 SUPERSEDED mychart-0.1.0 Install complete 2 Mon Jul 23 10:50:25 2018 DEPLOYED mychart-0.2.0 Upgrade complete
|
其次,咱們可使用下面的命令對指定的應用進行回退。
1 2
|
$ helm rollback mike-test 1 Rollback was a success! Happy Helming!
|
注:其中的參數 1 是 helm history 查看到 Release 的歷史記錄中 REVISION 對應的值。
最後,咱們使用 helm list
和 helm history
命令均可以看到 mychart 的版本已經回退到 0.1.0 版本。
1 2 3 4 5 6 7 8 9
|
$ helm list NAME REVISION UPDATED STATUS CHART NAMESPACE mike-test 3 Mon Jul 23 10:53:42 2018 DEPLOYED mychart-0.1.0 default
$ helm history mike-test REVISION UPDATED STATUS CHART DESCRIPTION 1 Mon Jul 23 10:41:20 2018 SUPERSEDED mychart-0.1.0 Install complete 2 Mon Jul 23 10:50:25 2018 SUPERSEDED mychart-0.2.0 Upgrade complete 3 Mon Jul 23 10:53:42 2018 DEPLOYED mychart-0.1.0 Rollback to 1
|
刪除一個應用
如果須要刪除一個已部署的 Release,能夠利用 helm delete
命令來完成刪除。
1 2
|
$ helm delete mike-test release "mike-test" deleted
|
確認應用是否刪除,該應用已被標記爲 DELETED 狀態。
1 2 3
|
$ helm ls -a mike-test NAME REVISION UPDATED STATUS CHART NAMESPACE mike-test 3 Mon Jul 23 10:53:42 2018 DELETED mychart-0.1.0 default
|
也可使用 --deleted
參數來列出已經刪除的 Release
1 2 3
|
$ helm ls --deleted NAME REVISION UPDATED STATUS CHART NAMESPACE mike-test 3 Mon Jul 23 10:53:42 2018 DELETED mychart-0.1.0 default
|
從上面的結果也能夠看出,默認狀況下已經刪除的 Release 只是將狀態標識爲 DELETED 了 ,但該 Release 的歷史信息仍是繼續被保存的。
1 2 3 4 5
|
$ helm hist mike-test REVISION UPDATED STATUS CHART DESCRIPTION 1 Mon Jul 23 10:41:20 2018 SUPERSEDED mychart-0.1.0 Install complete 2 Mon Jul 23 10:50:25 2018 SUPERSEDED mychart-0.2.0 Upgrade complete 3 Mon Jul 23 10:53:42 2018 DELETED mychart-0.1.0 Deletion complete
|
若是要移除指定 Release 全部相關的 Kubernetes 資源和 Release 的歷史記錄,能夠用以下命令:
1 2
|
$ helm delete --purge mike-test release "mike-test" deleted
|
再次查看已刪除的 Release,已經沒法找到相關信息。
1 2 3 4 5 6
|
$ helm hist mike-test Error: release: "mike-test" not found
# helm ls 命令也已均無查詢記錄。 $ helm ls --deleted $ helm ls -a mike-test
|
Helm 部署應用實例
部署 Wordpress
這裏以一個典型的三層應用 Wordpress 爲例,包括 MySQL、PHP 和 Apache。
因爲測試環境沒有可用的 PersistentVolume(持久卷,簡稱 PV),這裏暫時將其關閉。關於 Persistent Volumes 的相關信息咱們會在後續的相關文章進行講解。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
|
$ helm install --name wordpress-test --set "persistence.enabled=false,mariadb.persistence.enabled=false,serviceType=NodePort" stable/wordpress
NAMESPACE: default STATUS: DEPLOYED
RESOURCES: ==> v1beta1/Deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE wordpress-test-mariadb 1 1 1 1 26m wordpress-test-wordpress 1 1 1 1 26m
==> v1/Pod(related) NAME READY STATUS RESTARTS AGE wordpress-test-mariadb-84b866bf95-n26ff 1/1 Running 1 26m wordpress-test-wordpress-5ff8c64b6c-sgtvv 1/1 Running 6 26m
==> v1/Secret NAME TYPE DATA AGE wordpress-test-mariadb Opaque 2 26m wordpress-test-wordpress Opaque 2 26m
==> v1/ConfigMap NAME DATA AGE wordpress-test-mariadb 1 26m wordpress-test-mariadb-tests 1 26m
==> v1/Service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE wordpress-test-mariadb ClusterIP 10.254.99.67 <none> 3306/TCP 26m wordpress-test-wordpress NodePort 10.254.175.16 <none> 80:8563/TCP,443:8839/TCP 26m
NOTES: 1. Get the WordPress URL:
Or running:
export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services wordpress-test-wordpress) export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}") echo http://$NODE_IP:$NODE_PORT/admin
2. Login with the following credentials to see your blog
echo Username: user echo Password: $(kubectl get secret --namespace default wordpress-test-wordpress -o jsonpath="{.data.wordpress-password}" | base64 --decode)
|
訪問 Wordpress
部署完成後,咱們能夠經過上面的提示信息生成相應的訪問地址和用戶名、密碼等相關信息。
1 2 3 4 5 6 7 8 9 10 11
|
# 生成 Wordpress 管理後臺地址 $ export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services wordpress-test-wordpress) $ export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}") $ echo http://$NODE_IP:$NODE_PORT/admin http://192.168.100.211:8433/admin
# 生成 Wordpress 管理賬號和密碼 $ echo Username: user Username: user $ echo Password: $(kubectl get secret --namespace default wordpress-test-wordpress -o jsonpath="{.data.wordpress-password}" | base64 --decode) Password: 9jEXJgnVAY
|
給一張訪問效果圖吧:
![](http://static.javashuo.com/static/loading.gif)
Helm 其它使用技巧
爲了方便 helm
命令的使用,Helm 提供了自動補全功能,若是使用 ZSH 請執行:
1
|
$ source <(helm completion zsh)
|
若是使用 BASH 請執行:
1
|
$ source <(helm completion bash)
|
隨着 Helm 愈來愈普及,除了使用預置官方存儲庫,三方倉庫也愈來愈多了(前提是網絡是可達的)。你可使用以下命令格式添加三方 Chart 存儲庫。
1 2
|
$ helm repo add 存儲庫名 存儲庫URL $ helm repo update
|
一些三方存儲庫資源:
1 2 3 4 5 6 7 8 9 10 11 12
|
# 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 能夠把零散的 Kubernetes 應用配置文件做爲一個 Chart 管理,Chart 源碼能夠和源代碼一塊兒放到 Git 庫中管理。經過把 Chart 參數化,能夠在測試環境和生產環境採用不一樣的 Chart 參數配置。
下圖是採用了 Helm 的一個 CI/CD 流程
![](http://static.javashuo.com/static/loading.gif)
- Helm 如何管理多環境下 (Test、Staging、Production) 的業務配置?
Chart 是支持參數替換的,能夠把業務配置相關的參數設置爲模板變量。使用 helm install
命令部署的時候指定一個參數值文件,這樣就能夠把業務參數從 Chart 中剝離了。例如: helm install --values=values-production.yaml wordpress
。
在 Chart 裏能夠經過 requirements.yaml 聲明對其它 Chart 的依賴關係。以下面聲明代表 Chart 依賴 Apache 和 MySQL 這兩個第三方 Chart。
1 2 3 4 5 6 7 8 9 10
|
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
參數,好比:
1
|
$ helm install local/mychart --name mike-test --namespace mynamespace
|
1
|
$ helm get wordpress-test
|
默認狀況下會顯示最新的版本的相關信息,若是想要查看指定發佈版本的信息可加上 --revision
參數。