chart 是 Helm 的應用打包格式。chart 由一系列文件組成,這些文件描述了 Kubernetes 部署應用時所需要的資源,比如 Service、Deployment、PersistentVolumeClaim、Secret、ConfigMap 等。
單個的 chart 可以非常簡單,只用於部署一個服務,比如 Memcached;chart 也可以很復雜,部署整個應用,比如包含 HTTP Servers、 Database、消息中間件、cache 等。
chart 將這些文件放置在預定義的目錄結構中,通常整個 chart 被打成 tar 包,而且標注上版本信息,便於 Helm 部署。
下面我們將詳細討論 chart 的目錄結構以及包含的各類文件。
1.chart 目錄結構
以前面 MySQL chart 為例。一旦安裝了某個 chart,我們就可以在 ~/.helm/cache/archive 中找到 chart 的 tar 包。
解壓后,MySQL chart 目錄結構如下:
目錄名就是 chart 的名字(不帶版本信息),這里是 mysql
,包含如下內容:
Chart.yaml
YAML 文件,描述 chart 的概要信息
name
和 version
是必填項,其他都是可選。
templates 目錄
各類 Kubernetes 資源的配置模板都放置在這里。Helm 會將 values.yaml 中的參數值注入到模板中生成標准的 YAML 配置文件。
模板是 chart 最重要的部分,也是 Helm 最強大的地方。模板增加了應用部署的靈活性,能夠適用不同的環境,我們后面會詳細討論。
templates/NOTES.txt
chart 的簡易使用文檔,chart 安裝成功后會顯示此文檔內容。
與模板一樣,可以在 NOTE.txt 中插入配置參數,Helm 會動態注入參數值。
2.chart模板
Helm 通過模板創建 Kubernetes 能夠理解的 YAML 格式的資源配置文件,我們將通過例子來學習如何使用模板。
以 templates/secrets.yaml
為例:
從結構看,文件的內容非常像 Secret 配置,只是大部分屬性值變成了{{ xxx }}
。這些 {{ xxx }}
實際上是模板的語法。Helm 采用了 Go 語言的模板來編寫 chart。Go 模板非常強大,支持變量、對象、函數、流控制等功能。下面我們通過解析 templates/secrets.yaml
快速學習模板。
① {{ template "mysql.fullname" . }}
定義 Secret 的 name
。
關鍵字 template
的作用是引用一個子模板 mysql.fullname
。這個子模板是在 templates/_helpers.tpl
文件中定義的。
這個定義還是很復雜的,因為它用到了模板語言中的對象、函數、流控制等概念。現在看不懂沒關系,這里我們學習的重點是:如果存在一些信息多個模板都會用到,則可在 templates/_helpers.tpl
中將其定義為子模板,然后通過 templates
函數引用。
這里 mysql.fullname
是由 release 與 chart 二者名字拼接組成。
根據 chart 的最佳實踐,所有資源的名稱都應該保持一致,對於我們這個 chart,無論 Secret 還是 Deployment、PersistentVolumeClaim、Service,它們的名字都是子模板 mysql.fullname
的值。
② Chart
和 Release
是 Helm 預定義的對象,每個對象都有自己的屬性,可以在模板中使用。如果使用下面命令安裝 chart:
helm install stable/mysql -n my
那么:
{{ .Chart.Name }}
的值為 mysql
。{{ .Chart.Version }}
的值為 0.10.2
。{{ .Release.Name }}
的值為 my
。{{ .Release.Service }}
始終取值為 Tiller
。{{ template "mysql.fullname" . }}
計算結果為 my-mysql
。
③ 這里指定 mysql-root-password
的值,不過使用了 if-else
的流控制,其邏輯為:
如果 .Values.mysqlRootPassword
有值,則對其進行 base64 編碼;否則隨機生成一個 10 位的字符串並編碼。
Values
也是預定義的對象,代表的是 values.yaml
文件。而 .Values.mysqlRootPassword
則是 values.yaml
中定義的 mysqlRootPassword
參數:
因為 mysqlRootPassword
被注釋掉了,沒有賦值,所以邏輯判斷會走 else
,即隨機生成密碼。
randAlphaNum
、b64enc
、quote
都是 Go 模板語言支持的函數,函數之間可以通過管道 |
連接。{{ randAlphaNum 10 | b64enc | quote }}
的作用是首先隨機產生一個長度為 10 的字符串,然后將其 base64 編碼,最后兩邊加上雙引號。
templates/secrets.yaml
這個例子展示了 chart 模板主要的功能,我們最大的收獲應該是:模板將 chart 參數化了,通過 values.yaml
可以靈活定制應用。
無論多復雜的應用,用戶都可以用 Go 模板語言編寫出 chart。無非是使用到更多的函數、對象和流控制。對於初學者,我的建議是盡量參考官方的 chart。根據二八定律,這些 chart 已經覆蓋了絕大部分情況,而且采用了最佳實踐。如何遇到不懂的函數、對象和其他語法,可參考官網文檔 https://docs.helm.sh
3.MySQL chart實踐
3.1chart 安裝前的准備
作為准備工作,安裝之前需要先清楚 chart 的使用方法。這些信息通常記錄在 values.yaml 和 README.md 中。除了下載源文件查看,執行 helm inspect values
可能是更方便的方法。
輸出的實際上是 values.yaml 的內容。閱讀注釋就可以知道 MySQL chart 支持哪些參數,安裝之前需要做哪些准備。其中有一部分是關於存儲的:
chart 定義了一個 PersistentVolumeClaim,申請 8G 的 PersistentVolume。由於我們的實驗環境不支持動態供給,所以得預先創建好相應的 PV,其配置文件 mysql-pv.yml
內容為:
helm安裝不會指定storageclassname,這個pvc就會看當前的namespace有沒有default的storageclass,所以配置文件中storageClass不需要指定。
創建PV mysql-pv
接下來就可以安裝 chart 了。
3.2定制化安裝 chart
除了接受 values.yaml 的默認值,我們還可以定制化 chart,比如設置 mysqlRootPassword
。
Helm 有兩種方式傳遞配置參數:
-
指定自己的 values 文件。
通常的做法是首先通過helm inspect values mysql > myvalues.yaml
生成 values 文件,然后設置mysqlRootPassword
,之后執行helm install --values=myvalues.yaml mysql
。 -
通過
--set
直接傳入參數值,比如:
helm install ali/mysql --set mysqlRootPassword=admin123 -n my
mysqlRootPassword
設置為 abc123
。另外,-n
設置 release 為 my
,各類資源的名稱即為my-mysql
。
通過 helm list
和 helm status
可以查看 chart 的最新狀態。
通過kubectl get 命令查看 pv pvc pod的狀態
PVC 已經 Bound
,Deployment 也 AVAILABLE
。
4.升級和回滾 release
release 發布后可以執行 helm upgrade
對其升級,通過 --values
或 --set
應用新的配置。比如將當前的 MySQL 版本升級到 5.7.15:
helm upgrade --set imageTag=5.7.15 my ali/mysql
等待一些時間,升級成功。
helm history
可以查看 release 所有的版本。通過 helm rollback
可以回滾到任何版本。
回滾成功,MySQL 恢復到 5.7.14。