一、概述

Helm 是什么??
Helm 是 Kubernetes 的包管理器。包管理器類似於我們在 Ubuntu 中使用的apt、Centos中使用的yum 或者Python中的 pip 一樣,能快速查找、下載和安裝軟件包。Helm 由客戶端組件 helm 和服務端組件 Tiller 組成, 能夠將一組K8S資源打包統一管理, 是查找、共享和使用為Kubernetes構建的軟件的最佳方式。
Helm 解決了什么痛點?
在 Kubernetes中部署一個可以使用的應用,需要涉及到很多的 Kubernetes 資源的共同協作。比如你安裝一個 WordPress 博客,用到了一些 Kubernetes (下面全部簡稱k8s)的一些資源對象,包括 Deployment 用於部署應用、Service 提供服務發現、Secret 配置 WordPress 的用戶名和密碼,可能還需要 pv 和 pvc 來提供持久化服務。並且 WordPress 數據是存儲在mariadb里面的,所以需要 mariadb 啟動就緒后才能啟動 WordPress。這些 k8s 資源過於分散,不方便進行管理,直接通過 kubectl 來管理一個應用,你會發現這十分蛋疼。
所以總結以上,我們在 k8s 中部署一個應用,通常面臨以下幾個問題:
- 如何統一管理、配置和更新這些分散的 k8s 的應用資源文件
- 如何分發和復用一套應用模板
- 如何將應用的一系列資源當做一個軟件包管理
Helm 相關組件及概念
Helm 包含兩個組件,分別是 helm 客戶端 和 Tiller 服務器:
- helm 是一個命令行工具,用於本地開發及管理chart,chart倉庫管理等
- Tiller 是 Helm 的服務端。Tiller 負責接收 Helm 的請求,與 k8s 的 apiserver 交互,根據chart 來生成一個 release 並管理 release
- chart Helm的打包格式叫做chart,所謂chart就是一系列文件, 它描述了一組相關的 k8s 集群資源
- release 使用 helm install 命令在 Kubernetes 集群中部署的 Chart 稱為 Release
- Repoistory Helm chart 的倉庫,Helm 客戶端通過 HTTP 協議來訪問存儲庫中 chart 的索引文件和壓縮包
Helm 原理
下面兩張圖描述了 Helm 的幾個關鍵組件 Helm(客戶端)、Tiller(服務器)、Repository(Chart 軟件倉庫)、Chart(軟件包)之間的關系以及它們之間如何通信
helm 組件通信
helm 架構
創建release
- helm 客戶端從指定的目錄或本地tar文件或遠程repo倉庫解析出chart的結構信息
- helm 客戶端指定的 chart 結構和 values 信息通過 gRPC 傳遞給 Tiller
- Tiller 服務端根據 chart 和 values 生成一個 release
- Tiller 將install release請求直接傳遞給 kube-apiserver
刪除release
- helm 客戶端從指定的目錄或本地tar文件或遠程repo倉庫解析出chart的結構信息
- helm 客戶端指定的 chart 結構和 values 信息通過 gRPC 傳遞給 Tiller
- Tiller 服務端根據 chart 和 values 生成一個 release
- Tiller 將delete release請求直接傳遞給 kube-apiserver
更新release
- helm 客戶端將需要更新的 chart 的 release 名稱 chart 結構和 value 信息傳給 Tiller
- Tiller 將收到的信息生成新的 release,並同時更新這個 release 的 history
- Tiller 將新的 release 傳遞給 kube-apiserver 進行更新
chart 的基本結構
Helm的打包格式叫做chart,所謂chart就是一系列文件, 它描述了一組相關的 k8s 集群資源。Chart中的文件安裝特定的目錄結構組織, 最簡單的chart 目錄如下所示:
./ ├── charts ├── Chart.yaml ├── templates │ ├── deployment.yaml │ ├── _helpers.tpl │ ├── ingress.yaml │ ├── NOTES.txt │ ├── serviceaccount.yaml │ ├── service.yaml │ └── tests │ └── test-connection.yaml └── values.yaml
- charts 目錄存放依賴的chart
- Chart.yaml 包含Chart的基本信息,包括chart版本,名稱等
- templates 目錄下存放應用一系列 k8s 資源的 yaml 模板
- _helpers.tpl 此文件中定義一些可重用的模板片斷,此文件中的定義在任何資源定義模板中可用
- NOTES.txt 介紹chart 部署后的幫助信息,如何使用chart等
- values.yaml 包含了必要的值定義(默認值), 用於存儲 templates 目錄中模板文件中用到變量的值
二、安裝Helm
環境說明
系統 | k8s版本 | docker | ip | 主機名 | 配置 | 網絡驅動 |
---|---|---|---|---|---|---|
centos 7.6 | 1.18.1 | 19.03.5 | 192.168.128.130 | k8s-master | 2核4G | flannel |
centos 7.6 | 1.18.1 | 19.03.5 | 192.168.128.131 | k8s-node01 | 2核4G | flannel |
centos 7.6 | 1.18.1 | 19.03.5 | 192.168.128.132 | k8s-node02 | 2核4G | flannel |
安裝Helm
Helm 提供了幾種安裝方式,本文提供兩種安裝方式,想要查看更多安裝方式,請閱讀 Helm 的官方文檔:
目前最新穩定版為:2.16.6
通過 Helm 的 github 項目下找到你想要的 Helm 版本的二進制,然后通過手動安裝方式一樣安裝即可
wget https://get.helm.sh/helm-v2.16.6-linux-amd64.tar.gz tar zxvf helm-v2.16.6-linux-amd64.tar.gz -C /usr/src/ cp /usr/src/linux-amd64/helm /usr/local/bin/
安裝 Tiller
helm init --upgrade -i registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:v2.16.6 --stable-repo-url https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
執行上面命令后,可以通過 kubectl get po -n kube-system 來查看 tiller 的安裝情況。
由於 kubernetes 從1.6 版本開始加入了 RBAC 授權。當前的 Tiller 沒有定義用於授權的 ServiceAccount, 訪問 API Server 時會被拒絕,需要給 Tiller 加入授權。
創建 Kubernetes 的服務帳號和綁定角色
# kubectl create serviceaccount --namespace kube-system tiller serviceaccount/tiller created # kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller clusterrolebinding.rbac.authorization.k8s.io/tiller-cluster-rule created
給 Tiller 的 deployments 添加剛才創建的 ServiceAccount
# kubectl patch deploy --namespace kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}' deployment.apps/tiller-deploy patched
查看 Tiller deployments 資源是否綁定 ServiceAccount
# kubectl get deploy -n kube-system tiller-deploy -o yaml | grep serviceAccount f:serviceAccount: {} f:serviceAccountName: {} serviceAccount: tiller serviceAccountName: tiller
查看 Tiller 是否安裝成功
# helm version Client: &version.Version{SemVer:"v2.16.6", GitCommit:"dd2e5695da88625b190e6b22e9542550ab503a47", GitTreeState:"clean"} Server: &version.Version{SemVer:"v2.16.6", GitCommit:"dd2e5695da88625b190e6b22e9542550ab503a47", GitTreeState:"clean"}
三、使用 Helm 操作 Chart
這一節將介紹如何使用 helm 來操作 chart,包括創建、刪除、打包、安裝等使用。
先介紹一下 Helm 的核心命令:
helm create
創建一個 Chart 模板
# helm create test
Creating test
helm package
# helm package test Successfully packaged chart and saved it to: /root/test-0.1.0.tgz
helm search
查找可用的 Chart 模板
# helm search nginx NAME CHART VERSION APP VERSION DESCRIPTION stable/nginx-ingress 0.9.5 0.10.2 An nginx Ingress controller that uses ConfigMap to store ... stable/nginx-lego 0.3.1 Chart for nginx-ingress-controller and kube-lego stable/gcloud-endpoints 0.1.0 Develop, deploy, protect and monitor your APIs with Googl...
helm inspect
查看指定 Chart 的基本信息
# helm inspect test apiVersion: v1 appVersion: "1.0" description: A Helm chart for Kubernetes name: test version: 0.1.0 ...
四、Chart 模板示例
Chart 文件結構
wordpress ├── charts ├── Chart.yaml ├── README.md ├── requirements.lock ├── requirements.yaml ├── templates │ ├── deployment.yaml │ ├── externaldb-secrets.yaml │ ├── _helpers.tpl │ ├── ingress.yaml │ ├── NOTES.txt │ ├── pvc.yaml │ ├── secrets.yaml │ ├── svc.yaml │ └── tls-secrets.yaml └── values.yaml
一個 wordpress chart 如上(去除部分 test 和 charts 依賴), 基本結構由以下幾個部分組成:
- charts 存放子Chart (Subchart) 的定義,Subchart 指的是當前 Chart 依賴的 Chart , 在 requirements.yaml 中定義
- Chart.yaml 包含 Chart 信息的 YAML 文件, 包括 Chart 的版本、名稱等,在 DCE Helm 插件中還包含 Chart 的 團隊授權 信息 和 是否公開 的信息
- README.md 可選:Chart 的介紹信息等(該文件對於一個大型 Chart 來說十分重要)
- Requirements.yaml 可選:列舉當前 Chart 的需要依賴的 Chart
- templates
- 該目錄下存放 Chart 所有的 K8s 資源定義模板,通常不同的資源放在不同的文件中,DCE Helm 插件中自定義模板的 K8s 資源統一放在 all_sources.yaml 文件中
- _helpers.tpl , 通常這個文件存放可重用的模板片段,該文件中的定義可以在 Chart 其它資源定義模板中使用
- NOTES.txt,可選:一段簡短使用說明的文本文件,用於安裝 Release 后提示用戶使用
- values.yaml 當前 Chart 的默認配置的值
編寫一個簡單的 Chart 示例
本節以構建一個名稱為 nginx-test Chart 為示例,來描述一個 chart 必要條件。
# helm create nginx-test
Creating nginx-test
1、Chart.yaml 文件是 一個 chart 必要文件, 該文件可以簡單包括以下字段(具體字段請參考Helm官網)
# cat nginx-test/Chart.yaml apiVersion: v1 appVersion: "1.0" description: A Helm chart for Kubernetes name: nginx-test version: 0.1.0
2、values.yaml 文件是 chart 的必要文件,以 nginx 為示例:
# cat nginx-test/values.yaml # Default values for nginx-test. # This is a YAML-formatted file. # Declare variables to be passed into your templates. replicaCount: 1 ...
helm install --values=myvals.yaml nginx
注意:上面命令不要復制執行,執行會報錯的。請根據實際情況執行!!!
# cat nginx-test/templates/deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: {{ include "nginx-test.fullname" . }} labels: ...
上面定義了 一個 deployments.yaml 和 service.yaml 資源文件,里面使用 {{ }} 符號的是 Go 模板語言的標准。其中可以通過:
- .Values 對象訪問 values.yaml 文件的內容, 前面的dot(.) 表示從頂層命名空間開始,找到 Values 對象(下同)
- .Release、.Chart 開頭的預定義值可用於任何的模板中
- .Chart 對象用來訪問 Chart.yaml 文件的內容
- .Release 對象是 Helm的內置對象之一, 使用 Helm 安裝一個 release 時,由 Tiller 分配 release 的名稱
# cat nginx-test/templates/_helpers.tpl {{/* vim: set filetype=mustache: */}} {{/* Expand the name of the chart. */}} ...
該模板定義了 "nginx-test.name"、"nginx-test.fullname"、"nginx-test.chart" 等可重用模板部分,當模板引擎讀取該文件時,它存儲對 nginx-test.name等的引用, 直到調用 template "nginx-test.name" 為止。然后把值渲染到模板中。
注意 {{ template "nginx-test.chart" . }} 后面有個dot(.),這是因為一個已命名的模板(用於創建 define) 被渲染時,它將接收由該 template 調用傳入的范圍(scope)。沒有范圍傳入,在模板中無法訪問任何內容,因此在:
{{- define "nginx-test.chart" -}} 這里面的 .Chart 將無法訪問,導致在模板中無法看到內容,因為這里值為空 {{- end -}}
因此在模板中將 范圍(scope) 傳入即可正常使用:
# cat nginx-test/templates/service.yaml apiVersion: v1 kind: Service metadata: name: {{ include "nginx-test.fullname" . }}
在末尾傳遞了 . 這樣就可以使用 .Values 或者 .Chart 或其它范圍(scope)
dependencies: - name: mariadb version: 5.x.x repository: https://kubernetes-charts.storage.googleapis.com/ condition: mariadb.enabled tags: - wordpress-database
該文件列舉當前 Chart 所有的 依賴(subchart)。有幾個字段是必要的:
- name: 依賴 Chart 的名稱(必要)
- version: 依賴 Chart 的版本號(必要)
- repository: 依賴 Chart 的存儲庫完整URL,必須通過 helm repo add 添加 repository(存儲庫)到本地
本文參考鏈接:
https://www.jianshu.com/p/4bd853a8068b