今天要來講說 Helm 這個工具
因為 Helm 版本會不斷推陳出新, 因此在今天的內容著重再概念上的說明
而實作的部份不太多琢磨
對 k8s 叢集來說, Helm 是一個套件管理工具
如同 apt 之於 Debain, yum 之於 Fedora, Homebrew 之於 MacOS
假設今天要佈署一個 Elastic stack for logging 在一個已發佈的 app 上
基本上會需要一個 StatefulSet 因為需要紀錄狀態
可能還需要一個 Secret 來儲存機敏資料
一個 ConfigMap 來儲存共用變數
可能還會需要設定 k8s User Permission 來限制存取權限等等
當然 應該會佈署幾個 Service 來做運行
要做這些設定其實不是很容易
假設今天工作團隊中的其他人也要做類似的功能
這時我們就可以透過 Helm 把這些發佈過的設定檔 (yaml files) 打包成一個 Package (Chart) 放到某個 Chart Repository 讓其他團隊成員使用
讓降低其他團隊成員要佈署類似功能的複雜度
參考 Helm Chart Repostiory 官方文件定義
這本篇文章提到 Repository 都是指 Chart Repository
Chart Repositroy 是一個 HTTP 的伺服器, 用來存放打包好的 Chart 供其他人使用
因為 Chart Repository 主要是支援放置打包過的 yaml 或是 tar 這類打包檔案, 因此以下都是可以用來當作 Chart Repository 的選項, GCS(Google Cloud Storage), AWS S3 Bucket, Github Pages, 或是自己建立的 Web Serser.
個別設定內容可以參考官方設定
在這邊這個 Registry 就筆者理解是跟 Docker Registry 一樣的概念
Helm 在 v3.x.x 開始支援 OCI-based 的存放 Chart 方式
docker run -dp 5000:5000 --restart=always --name registry registry
如果你希望這個 Registry 可以再重開之後保存狀態可以在上面指令後加入 -v $(pwd)/registry:/var/lib/registry 參數, 讓狀態用 docker volume 掛載在 host 機器上
首先, 建立 auth.htpasswd 檔案使用以下指令:
htpasswd -cB -b auth.htpasswd myuser mypass
然後透過以下指令跑 Docker
docker run -dp 5000:5000 --restart=always --name registry \
-v $(pwd)/auth.htpasswd:/etc/docker/registry/auth.htpasswd \
-e REGISTRY_AUTH="{htpasswd: {realm: localhost, path: /etc/docker/registry/auth.htpasswd}}" \
registry
把多個設定檔(yaml files) 針對某個功能打包成的 Package 就是所謂的 Helm Chart
而產生出來的 Helm Chart 會放到 Chart Repository 讓其他人使用
有一些常用到 database app(mongodb, mysql), elastic search, monitoring app(promothes)這些都可以在 Helm repository找到
都可以透過 Helm 工具快速建制使用
建制 app 的時候, 可以使用 helm search hub $功能關鍵字
來查詢是否已經有建制過的 Helm Charts 可以直接拿到使用
或者到 artifact hub 搜索
而這些 Helm Charts 可以放在公開的 Repository 或是私有的
因為有些公司內部建制內部使用的 Package 不會公開
Helm 的另一個功用是用來做範本引擎
舉例來說:
假設我們要發佈的多個容器服務建制內容只有差在名稱跟版本其他是一樣的
就可以一樣的地方寫出一個建立範本, 然後在不同的地方使用變數代入
如 container-pod-template.yaml
apiVersion: v1
kind: Pod
metadata:
name: {{ .Values.name }}
spec:
containers:
- name: {{ .Values.container.name }}
image: {{ .Values.container.image }}
port: {{ .Values.container.port }}
還有對應的 values.yaml
name: my-app
container:
name: my-app-container
image: my-app-image
port: 9001
注意的是, 這邊的 Values 物件除了可以透過 yaml 來設定也可以使用 helm install 指令加上 --set 來設定
另外一個使用 Helm 的情境是在不同建制環境中佈署相同的應用
只要把原本的應用打包成一個 Chart, 然後發佈在不同環境的 k8s 叢集上
Helm 在發佈之後, 都會紀錄每次發佈的版本
可以用以下指令查看過去發佈的歷史
helm history $release_name
透過以下指令察看 $release_name 目前狀況
helm status $release_name
如果這個 $release_name 狀態不好
可以使用以下指令做回復到上一個版本
helm rollback $release_name
要注意的是, 當已經做 helm install 某個 chart 之後
下一次, 如果要對 chart 做更新會使用 helm upgrade 這樣就會只更新修改的部份
而不是重新起一個新的 Deployment 產生過多的 Deployment
這邊想對於注入值的機制做一些說明
因為基本上, values.yaml 的值是 .Value 物件的預設值
然而, 這個預設值可以在 helm install 指令透過以下兩個方式複寫掉
1 指定 values 參數到另一個設定值 my-values.yaml
helm install --values=my-values.yaml $chart_name
2 加入 --set 指定參數值
helm install --set version=2.0.0
ref https://helm.sh/docs/intro/install/
這邊是以 v3.7.0 版本來說明
筆者這邊以 snap 在 Ubuntu 20.04 做安裝指令為範例如下:
sudo snap install helm --classic
其他 OS 的安裝方式可以參考 官方網站
在 v2.x.x 的版本
Helm 分成 client 與 server 的部份
而 server 又被稱為 Tiller
主要由 client 發送指令給 Tiller, Tiller 負責實際發佈 service
在這樣架構下, Tiller 可以對 k8s 叢集新增修改服務, 具有極大的掌控權
因此會擔心當 Tiller 被攻擊時, 會有資安疑慮
所以在 v3.x.x 的版本移除掉了 Tiller, 只剩下 client 的部份
這邊指令, 以 v3.7.0 版來說明
直接從 https://artifiacthub.io 來搜尋
helm search hub $chart_name
舉例來說: 搜尋 elasticsearch 的 chart
helm search hub elasticsearch
另外可以自行設定要搜尋的 Repository
helm repo add $repo_name $repo_url
在已經加入的 Repository 搜尋 chart
helm search repo $chart_name
在 v3.7.0 可以透過以下指令來建立 chart
helm create $chart_name [flag]
本文以 v3.7.0 為範例:
每個chart 本身會已 Chart 的名稱為資料夾
而內部會有幾個重要的檔案:
1 Chart.yaml
記載關於 Chart 一些 metadata, 比如說 apiVersion, kubeversion 之類
2 values.yaml
預設的一些 .Value 物件的一些參數值
3 charts 資料夾
有所有跟這個 Chart 有依賴的 chart yaml 檔案
4 templates 資料夾
保存這個 Chart 有用到的範本檔案, 這些範本檔案可以存取 values.yaml 裡面的設定值
5 crds 資料夾
保存可以自訂資源定義檔, 這個在 v2.x.x 版本沒有這個資料夾
6 README.md
關於這個 Chart 的說明檔, 非必要存在
7 LICENSE
關於這個 Chart 的授權聲明檔, 非必要存在
舉 wordpress 這個 chart 為例:
wordpress/
Chart.yaml # A YAML file containing information about the chart
LICENSE # OPTIONAL: A plain text file containing the license for the chart
README.md # OPTIONAL: A human-readable README file
values.yaml # The default configuration values for this chart
values.schema.json # OPTIONAL: A JSON Schema for imposing a structure on the values.yaml file
charts/ # A directory containing any charts upon which this chart depends.
crds/ # Custom Resource Definitions
templates/ # A directory of templates that, when combined with values,
# will generate valid Kubernetes manifest files.
templates/NOTES.txt # OPTIONAL: A plain text file containing short usage notes
在 v3.7.0 可以透過以下指令來儲存目前 chart 到 local cache
helm chart save $chart_directory $repo_url_with_chart_name_and_version
在 v3.7.0 可以透過以下指令來把建立好的 chart 推送到 Repository
helm chart push $repo_url_with_chart_name_and_version