Helm 入門指南

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

從上圖能夠看到,在進行 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

Helm 是一個命令行下的客戶端工具。主要用於 Kubernetes 應用程序 Chart 的建立、打包、發布以及建立和管理本地和遠程的 Chart 倉庫。

  • Tiller

Tiller 是 Helm 的服務端,部署在 Kubernetes 集羣中。Tiller 用於接收 Helm 的請求,並根據 Chart 生成 Kubernetes 的部署文件( Helm 稱爲 Release ),而後提交給 Kubernetes 建立應用。Tiller 還提供了 Release 的升級、刪除、回滾等一系列功能。

  • Chart

Helm 的軟件包,採用 TAR 格式。相似於 APT 的 DEB 包或者 YUM 的 RPM 包,其包含了一組定義 Kubernetes 資源相關的 YAML 文件。

  • Repoistory

Helm 的軟件倉庫,Repository 本質上是一個 Web 服務器,該服務器保存了一系列的 Chart 軟件包以供用戶下載,而且提供了一個該 Repository 的 Chart 包的清單文件以供查詢。Helm 能夠同時管理多個不一樣的 Repository。

  • Release

使用 helm install 命令在 Kubernetes 集羣中部署的 Chart 稱爲 Release。

注:須要注意的是:Helm 中提到的 Release 和咱們一般概念中的版本有所不一樣,這裏的 Release 能夠理解爲 Helm 使用 Chart 包部署的一個應用實例。

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 的安裝方式不少,這裏採用二進制的方式安裝。更多安裝方法能夠參考 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 集羣中的,只需使用如下指令即可簡單的完成安裝。

1
$ helm init

因爲 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 部署添加受權。

  • 建立 Kubernetes 的服務賬號和綁定角色
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
  • 爲 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,可以使用如下命令完成卸載。

1
$ helm reset

構建一個 Helm Chart

下面咱們經過一個完整的示例來學習如何使用 Helm 建立、打包、分發、安裝、升級及回退Kubernetes應用。

建立一個名爲 mychart 的 Chart

1
$ helm create mychart

該命令建立了一個 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 進行回滾。

  • 修改 Chart.yaml 文件

將版本號從 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
  • 查詢本地倉庫中的 Chart 信息

咱們能夠看到在本地倉庫中 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

給一張訪問效果圖吧:

Helm 其它使用技巧

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

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

1
$ source <(helm completion zsh)

若是使用 BASH 請執行:

1
$ source <(helm completion bash)
  • 如何使用第三方的 Chart 存儲庫?

隨着 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 如何結合 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。

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 參數。

相關文章
相關標籤/搜索