Kubernetes——Helm

介紹

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

什么事Helm

在沒有使用Helm之前向Kubernetes部署應用,我們要依次部署deployment、svc等,步驟繁瑣,況且現在隨著很多項目微服務化,復雜的應用在容器中部署以及管理顯得較為復雜,Helm通過打包的方式,支持發布的版本管理與控制,很大程度上簡化了Kubernetes應用的部署與管理。

Helm本質就是讓Kubernetes的應用管理(Deployment、Service等)可配置,能動態生成。通過動態生成Kubernetes資源清單文件(deployment.yaml、service.yaml),然后調用Kubectl自動執行Kubernetes資源部署

Helm是官方提供的類似于YUM的包管理器,是部署環境的流程封裝??梢苑奖愕匕l現、共享和使用為Kubernetes構建的應用,它包含幾個基本概念:

  • Chart:一個 Helm 包,其中包含了運行一個應用所需要的鏡像、依賴和資源定義等,還可能包含 Kubernetes 集群中的服務定義,類似 Homebrew 中的 formula,APT 的 dpkg 或者 Yum 的 rpm 文件。
  • Release:在 Kubernetes 集群上運行的 Chart 的一個實例。在同一個集群上,一個 Chart 可以安裝很多次。每次安裝都會創建一個新的 release。例如一個 MySQL Chart,如果想在服務器上運行兩個數據庫,就可以把這個 Chart 安裝兩次。每次安裝都會生成自己的 Release,會有自己的 Release 名稱。
  • Repository:用于發布和存儲 Chart 的倉庫。

Helm包含兩個組件,Helm Client和Tiller Server:

Helm Client 是用戶命令行工具,其主要負責如下:

  • 本地 chart 開發
  • 倉庫管理
  • 與 Tiller sever 交互
  • 發送預安裝的 chart
  • 查詢 release 信息
  • 要求升級或卸載已存在的 release

Tiller Server是一個部署在Kubernetes集群內部的 server,其與 Helm client、Kubernetes API server 進行交互。Tiller server 主要負責如下:

  • 監聽來自 Helm client 的請求
  • 通過 chart 及其配置構建一次發布
  • 安裝 chart 到Kubernetes集群,并跟蹤隨后的發布
  • 通過與Kubernetes交互升級或卸載 chart
  • 簡單的說,client 管理 charts,而 server 管理發布 release

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

Helm 工作原理

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 的官方幫助文檔。

  • 使用官方提供的腳本一鍵安裝
$ curl https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get > get_helm.sh
$ chmod 700 get_helm.sh
$ ./get_helm.sh
  • 手動下載安裝
# 下載 Helm 
$ wget https://storage.googleapis.com/kubernetes-helm/helm-v2.13.1-linux-amd64.tar.gz
# 解壓 Helm
$ tar -zxvf helm-v2.13.1-linux-amd64.tar.gz
# 復制客戶端執行文件到 bin 目錄下
$ cp linux-amd64/helm /usr/local/bin/
  • 創建配置文件
    因為Kubernetes APIServer開啟了RBAC訪問控制,所以需要創建tiller使用的service account: tiller并分配合適的角色給它。 詳細內容可以查看helm文檔中的Role-based Access Control。 這里簡單起見直接分配 cluster-admin 這個集群內置的 ClusterRole 給它。創建 rbac-config.yaml 文件:
#vim rbac-config.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: tiller
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: tiller
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - kind: ServiceAccount
    name: tiller
    namespace: kube-system

執行配置文件,創建ServiceAccount

#kubectl apply -f rbac-config.yaml

Helm 服務端安裝Tiller

注意:先在 K8S 集群上每個節點安裝 socat 軟件(yum install -y socat ),不然會報如下錯誤:

E0522 22:22:15.492436   24409 portforward.go:331] an error occurred forwarding 38398 -> 44134: error forwarding port 44134 to pod dc6da4ab99ad9c497c0cef1776b9dd18e0a612d507e2746ed63d36ef40f30174, uid : unable to do port forwarding: socat not found.
Error: cannot connect to Tiller

部署tiller

由于 Helm 默認會去 storage.googleapis.com 拉取鏡像,如果你當前執行的機器不能訪問該域名的話可以使用以下命令來安裝:

# 先下載鏡像
#docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:v2.13.1

#helm init --service-account tiller --skip-refresh --tiller-image=registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:v2.13.1

或者

helm init --client-only --stable-repo-url https://aliacs-app-catalog.oss-cn-hangzhou.aliyuncs.com/charts/
helm repo add incubator https://aliacs-app-catalog.oss-cn-hangzhou.aliyuncs.com/charts-incubator/
helm repo update
# 創建服務端
helm init --service-account tiller --upgrade -i registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:v2.13.1  --stable-repo-url https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
 
# 創建TLS認證服務端,參考地址:https://github.com/gjmzj/kubeasz/blob/master/docs/guide/helm.md
helm init --service-account tiller --upgrade -i registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:v2.13.1 --tiller-tls-cert /etc/kubernetes/ssl/tiller001.pem --tiller-tls-key /etc/kubernetes/ssl/tiller001-key.pem --tls-ca-cert /etc/kubernetes/ssl/ca.pem --tiller-namespace kube-system --stable-repo-url https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts

在 Kubernetes 中安裝 Tiller 服務,因為官方的鏡像因為某些原因無法拉取,使用-i指定自己的鏡像,可選鏡像:registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:v2.13.1(阿里云),該鏡像的版本與helm客戶端的版本相同,使用helm version可查看helm客戶端版本。

如果在用helm init安裝tiller server時一直部署不成功,檢查deployment,根據描述解決問題。

三、給 Tiller 授權

因為 Helm 的服務端 Tiller 是一個部署在 Kubernetes 中 Kube-System Namespace 下 的 Deployment,它會去連接 Kube-Api 在 Kubernetes 里創建和刪除應用。

而從 Kubernetes 1.6 版本開始,API Server 啟用了 RBAC 授權。目前的 Tiller 部署時默認沒有定義授權的 ServiceAccount,這會導致訪問 API Server 時被拒絕。所以我們需要明確為 Tiller 部署添加授權。

  • 創建 Kubernetes 的服務帳號和綁定角色
$ 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 設置帳號
# 使用 kubectl patch 更新 API 對象
$ kubectl patch deploy --namespace kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}'
deployment.extensions "tiller-deploy" patched
  • 查看是否授權成功
$ 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-6d68f5c78f-nql2z          1/1       Running   0          5m

$ helm version
Client: &version.Version{SemVer:"v2.13.1", GitCommit:"20adb27c7c5868466912eebdf6664e7390ebe710", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.13.1", GitCommit:"20adb27c7c5868466912eebdf6664e7390ebe710", GitTreeState:"clean"}

卸載 Helm 服務器端 Tiller

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

$ helm reset

構建一個 Helm Chart

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

創建一個名為 mychart 的 Chart

$ helm create mychart

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

$ 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 中定義的容器鏡像。

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

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

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

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

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

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

編寫應用的介紹信息

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

$ 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 文件的內容:

$ 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: {}

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

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

1 chart(s) linted, no failures

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

將應用打包

$ 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 參數來查看打包的輸出,輸出內容應該類似如下:

$ 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包。

$ helm search mychart
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

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

$ 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 文件。

$ 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 上了。

# 部署時需指定 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 實例。

$ 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

$ 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           NAMESPACE
mike-test   1           Mon Jul 23 10:41:20 2018    DEPLOYED    mychart-0.1.0   default

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

$ 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 命令打包并發布到本地倉庫。

$ 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 有兩個版本。
$ 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 參數指定需要升級的版本號,如果沒有指定版本號,則缺省使用最新版本。
$ 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 版本。

$ 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 的所有變更記錄。
$ 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

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

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

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

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

$ 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 命令來完成刪除。

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

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

$ 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

$ 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 的歷史信息還是繼續被保存的。

$ 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 的歷史記錄,可以用如下命令:

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

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

$ 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 的相關信息我們會在后續的相關文章進行講解。

$ 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

部署完成后,我們可以通過上面的提示信息生成相應的訪問地址和用戶名、密碼等相關信息。

# 生成 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 請執行:
$ 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/mychart --name mike-test --namespace mynamespace
  • 如何查看已部署應用的詳細信息?
helm get wordpress-test

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

$ helm get  --revision 1  wordpress-test

參考:
https://www.cnblogs.com/guigujun/p/10550256.html

https://www.cnblogs.com/xzkzzz/p/10445807.html

https://www.cnblogs.com/tylerzhou/p/11130137.html

https://blog.51cto.com/536410/2373843?source=dra

https://www.hi-linux.com/posts/21466.html

https://www.cnblogs.com/zy09/p/11528651.html

https://blog.csdn.net/bbwangj/article/details/81087911

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容