了解 Helm 的用途與架構
安裝 Helm
Helm 的實作
部署他人分享的 Chart
Helm 的常用指令彙整
今天是「Basic Concept」章節的最後一篇,我們來看一個好用的套件管理工具:Helm。
本日內容不屬於 CKA 考試範圍。
Helm 是一項 CNCF 的專案,能將 k8s 中的應用打包起來,方便我們管理、部署、升級。
那為什麼應用需要打包?在實務中,一項 k8s 應用服務會由很多份 yaml 來組成,例如常聽見的微服務架構。而這會造成以下問題:
因為有很多的 yaml,所以部署整套應用時就要一直複製貼上、複製貼上,非常麻煩。
因為部署環境的不同,可能需要針對應用服務做一些微調。但如果這些微調的 yaml 都散落在不同的地方,就會讓管理變得很困難。
當整套應用需要升級時,一堆的 yaml 很難有效率的做到統一的管理與升級。
為了解決這些問題, Helm 將一套應用服務打包起來,形成一個叫做「chart」的檔案,我們就能針對 chart 來部署、管理、調整、升級整套應用服務。另外,chart 也可以透過 repository 來分享,讓其他人可以快速的部署應用服務,也有利於版本控制。
以官網的話來說,Helm 有以下四大特色:
以下以 Debian/Ubuntu 為例,其他作業系統請參考官網。
curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null
sudo apt-get install apt-transport-https --yes
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
sudo apt-get update
sudo apt-get install helm
安裝後查看是否安裝成功:
helm version
輸出:
version.BuildInfo{Version:"v3.15.4", GitCommit:"fa9efb07d9d8debbb4306d72af76a383895aa8c4", GitTreeState:"clean", GoVersion:"go1.22.6"}
我們來實際打包一個簡單的應用服務,並透過 Helm 來部署。
該應用服務包含兩個部分:一個是 Deployment,一個是 Service。
需要的檔案已經寫好了,將專案目錄 clone 下來即可:
git clone https://github.com/michaelchen1225/helm-demo.git
cd ./helm-demo
我們先看一下一個 Helm chart 的基本目錄結構:
helm-demo
|-- Chart.yaml
|-- charts
|-- templates
| |-- nginx-deploy.yaml
| |-- nginx-deploy-svc.yaml
| |-- NOTES.txt
|-- values.yaml
這個基本的目錄結構可以用
helm create
來生成,例如:
helm create helm-demo-2
首先,我們先撰寫 Chart.yaml:
apiVersion: v2
name: helm-demo
description: helm demo from day 11
type: application
version: 0.1.0
appVersion: "1.0.0"
接著,我們來看一下 nginx-deploy.yaml 的內容:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-deploy
name: nginx-deploy
spec:
replicas: 3
selector:
matchLabels:
app: nginx-deploy
template:
metadata:
labels:
app: nginx-deploy
spec:
containers:
- image: nginx:1.15
name: nginx
為了讓這個 yaml 能被彈性的應用,我們能將一些寫死的值改成以下格式:
{{ .Object.Parameter }}
這個「.Object」可以是以下幾種:
這樣說有點抽象,這裡直接實際把 nginx-deploy.yaml 修改成底下這樣:
vim templates/nginx-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-deploy
name: {{ .Release.Name }}-nginx-deploy
spec:
replicas: {{ .Values.replicas }}
selector:
matchLabels:
app: nginx-deploy
template:
metadata:
labels:
app: nginx-deploy
spec:
containers:
- image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
name: nginx
這樣一來,這個 Deployment 在部署實會被彈性調整的地方有:
實際的 values.yaml 的內容長這樣:
replicas: 3
image:
repository: nginx
tag: 1.15
設定好後,我們來檢查一下這個 chart 的設定是否正確:
# 要在 helm-demo 目錄下執行
helm lint .
輸出:
==> Linting .
[INFO] Chart.yaml: icon is recommended
1 chart(s) linted, 0 chart(s) failed
這樣就代表這個 chart 沒有問題,如果有誤你可能會看到一些錯誤訊息,例如:
==> Linting .
[INFO] Chart.yaml: icon is recommended
[ERROR] templates/nginx-deploy.yaml: unable to parse YAML: error converting YAML to JSON: yaml: line 19: mapping values are not allowed in this context
Error: 1 chart(s) linted, 1 chart(s) failed
接著可以檢查看看將「value.yaml」的值帶入後的 template yaml 是否符合預期:
helm template .
一切 OK 後,離開 helm-demo 目錄,我們就可以透過 Helm 部署這個 chart:
cd ~
helm install first-chart ./helm-demo
輸出:
LAST DEPLOYED: Thu Aug 29 10:24:04 2024
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Hi !
This is the helm demo from Day 11
這會建立一個名為 first-chart 的 release,並部署 helm-demo 這個 chart 在 default namespace 中。
檢查一下部署狀態:
kubectl get deploy,svc
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/first-chart-nginx-deploy 3/3 3 3 90s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 27d
service/nginx-deploy-svc ClusterIP 10.96.111.48 <none> 80/TCP 90s
查看一下目前安裝過的 release:
helm list
輸出:
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
first-chart default 1 2024-08-29 10:24:04.562088695 +0000 UTC deployed helm-demo-0.1.0 1.0.0
這樣就完成了一個簡單的 Helm chart 打包與部署,接著嘗試更新這個 chart,把 replicas 數量改成 1:
replicas: 1
...(略)
helm upgrade first-chart ./helm-demo
輸出:
Release "first-chart" has been upgraded. Happy Helming!
NAME: first-chart
LAST DEPLOYED: Thu Aug 29 10:25:15 2024
NAMESPACE: default
STATUS: deployed
REVISION: 2
TEST SUITE: None
NOTES:
Hi !
This is the helm demo from Day 11
REVISON 2 代表這是第二次更新。
kubectl get deploy first-chart-nginx-deploy
NAME READY UP-TO-DATE AVAILABLE AGE
first-chart-nginx-deploy 1/1 1 1 2m8s
helm rollback <release-name> <revision>
:helm rollback first-chart 1
輸出:
Rollback was a success! Happy Helming!
檢查後可以發現 replicas 數量又變回 3 了。我們可以用 helm history <release-name>
來查看 release 的歷史紀錄:
helm history first-chart
輸出:
REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION
1 Thu Aug 29 10:24:04 2024 superseded helm-demo-0.1.0 1.0.0 Install complete
2 Thu Aug 29 10:25:15 2024 superseded helm-demo-0.1.0 1.0.0 Upgrade complete
3 Thu Aug 29 10:27:19 2024 deployed helm-demo-0.1.0 1.0.0 Rollback to 1
如果想比對兩個 REVISON 的差異,可以使用 helm diff revision <release-name> <revision-1> <revision-2>
:
helm diff revision first-chart 2 3
最後我們將這個 release 刪除:
helm uninstall first-chart
除了直接修改 values.yaml 之外,我們也可以透過 --set
來修改 Helm 的 value 設定:
helm install first-chart ./helm-demo --set image.tag=1.16
kubectl get deploy first-chart-nginx-deploy -o jsonpath='{.spec.template.spec.containers[0].image}'
輸出:
nginx:1.16
也可以使用 --values
來指定一個 yaml 檔案來取代原本的 values.yaml,這樣就能更方便的管理不同環境的設定:
helm install new-value-chart ./helm-demo --values <path-to-other-values.yaml>
當我們完成一個 chart 的開發後,可以將這個 chart 打包成一個 .tgz 檔案,這樣就能夠分享給其他人使用。
helm package ./helm-demo
輸出:
Successfully packaged chart and saved it to: /root/helm-demo-0.1.0.tgz
Helm 的 chart 也有類似 Github 的平台來分享,來源分為以下兩者:
安裝 Artifact Hub 上的 Chart
nginx
。點進去後可以看到這個 Chart 的相關資訊,包含了安裝方式、相依性等。安裝自行加入的 repository
helm repo add <repo-name> <repo-url>
helm install <release-name> <repo-name>/<chart-name>
helm repo update
helm repo list
helm repo remove <repo-name>
有關其他的 helm 指令用法,可以用善用
-h
來查看。
以下將 helm 的常用指令彙整,方便日後查詢:
初始化一個 Chart,生成基本的目錄結構:
helm create <chart-name>
檢查 chart 的配置是否正確:
helm lint <chart-path>
查看 chart 的 template 是否符合預期:
helm template <chart-path>
安裝 Chart:
helm install <release-name> <chart-name>
從特定 repo 安裝 Chart:
helm install <release-name> <repo-name>/<chart-name>
安裝 Chart 並修改 value:
helm install <release-name> <chart-name> --set <key>=<value>
安裝 Chart 並帶入新的 value.yaml:
helm install <release-name> <chart-name> --values <path-to-other-values.yaml>
解除安裝 Chart:
helm uninstall <release-name>
列出已安裝的 release:
helm list
更新一個 release:
helm upgrade <release-name> <chart-name>
Rollback 一個 release 到指定 REVISION:
helm rollback <release-name> <revision>
檢查兩次 REVISION 的差異:
helm diff revision <release-name> <revision-1> <revision-2>
打包 Chart 成一個 tgz 檔:
helm package <chart-name>
加入新的 repo:
helm repo add <repo-name> <repo-url>
更新 repo:
helm repo udpate
列出目前可用的 repo:
helm repo list
移除 repo:
helm repo remove <repo-name>
今天是「Basic Concept」章節的最後一篇,前面我們已經掌握了 k8s 中基本的概念以及相關操作,而隨著面對的 yaml 越來越多,今天也介紹了 Helm 這個方便的套件管理工具,能夠讓我們更有效率的管理、部署、升級應用服務。另外,Helm 與 k8s 一樣,都有相當完整的官方文件可以參考,通常搜尋關鍵字都能找到相關資訊。
明天就會進入新的章節:「Storage」,將會介紹 k8s 中的儲存相關概念,例如 configMap、secret、volume 等,讓我們更了解如何在 k8s 中有效的管理與保存資料。
參考資料