Kubernetes 從零開始 - Helm Controller
Introduction to Helm Controller
如果你是使用 Helm Chart 來管理你的 Kubernetes 資源
一個常見的需求會是,你可能會需要更新你的 chart
不管是 image version 還是一些設定檔的更新
當然你可以手動 $ helm upgrade
來更新你的 chart
不過官方有提供一個更好的方式,就是使用 Helm Controller
Helm Controller 允許你用 declarative 的方式來管理 Helm Chart
並且主動監控任何 CRD(Custom Resource Definition) 的變化
因此你只需要透過更新 CRD 告訴他你想要的狀態,Helm Controller 會自己去更新相對應的 chart
可參考 Kubernetes 從零開始 - 從自幹 Controller 到理解狀態管理 | Shawn Hsu 以及 Kubernetes 從零開始 - Deployment 管理救星 Helm Chart | Shawn Hsu
Use Helm Controller
k3d(i.e. k3s) 預設就已經安裝了 Helm Controller 以及相對應的 CRD
所以不需要特別安裝就可以直接使用
HelmChart
以及HelmChartConfig
這兩個 CRD 可以用$ kubectl get crd
來查看
有關 CRD 可以參考 Kubernetes 從零開始 - client-go 實操 CRD | Shawn Hsu
如果是其他的 Kubernetes cluster,可以參考 k3s-io/helm-controller 給的設定檔進行操作
本文會使用 k3s-io/helm-controller
網路上也有其他的 Helm Controller 實作,例如 fluxcd/helm-controller
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: apps/v1
kind: Deployment
metadata:
name: helm-controller
labels:
app: helm-controller
spec:
replicas: 1
selector:
matchLabels:
app: helm-controller
template:
metadata:
labels:
app: helm-controller
spec:
containers:
- name: helm-controller
image: rancher/helm-controller:v0.12.1
command: ["helm-controller"]
Patching Helm Chart
Install Redis Helm Chart
以 bitnami/redis 為例,透過 HelmChart CRD 建立 Custom Resource(CR)
1
2
3
4
5
6
7
8
9
10
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
name: myredis
namespace: default
spec:
repo: https://charts.bitnami.com/bitnami
chart: redis
set:
replica.replicaCount: 5
以上就是一個基本的 Custom Resource 定義
我在 default
namespace 底下要建立一個名為 myredis
的 HelmChart Release
並且使用 https://charts.bitnami.com/bitnami
的 redis
chart
因為第三方的 Helm Chart 通常允許你更改一些參數
這裡我們想要覆蓋 replica.replicaCount
, 設定成 5 個 replica
參數的部份,是對應到 bitnami/redis/values.yaml 的設定值
安裝完成你應該會看到類似以下的結果
1
2
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
myredis default 1 2024-10-05 20:40:39.93388077 +0800 CST deployed redis-20.1.7 7.4.1
Kubectl Patch
所以到現在我們成功的建立了一個 HelmChart Release
假設我想要再次更新 replica 的數量,我們可以就透過 $ kubectl patch
來達成
前面說過,Helm Controller 會監控 CRD 的變化,所以我們可以透過更改 CR 觸發 Helm Controller 來更新 Helm Chart
patch 有三種方式,strategic merge patch
, JSON merge patch 以及 JSON patch
strategic merge patch 沒辦法用於 HelmChart CRD
JSON Merge Patch
JSON Merge Patch 定義於 RFC 7386
稱之為 merge patch 是因為它是將 patch 的內容合併到原本的資料上
也就是說原本不存在的會被新增,已經存在的會被更新,給 null 則會被刪除
1
2
3
spec:
set:
replica.replicaCount: 10
以上就是一個簡單的 JSON Merge Patch
然後透過 kubectl patch 執行
1
$ kubectl patch HelmChart myredis --type merge --patch-file ./patch.yaml
你可以檢查看他有沒有正確的更新成功
1
2
3
4
5
6
7
8
9
$ kubectl get HelmChart myredis -o yaml
...
spec:
chart: redis
repo: https://charts.bitnami.com/bitnami
set:
replica.replicaCount: 10
status:
jobName: helm-install-myredis
JSON Patch
JSON patch 定義於 RFC 6902
跟 JSON Merge Patch 類似,只是說你要指定 patch 的操作
JSON patch 是一個 array, 每個 object 包含 op
, path
, value
操作識別符號透過 op
來指定,比方說你要新增還是刪除
path
這個欄位的資料要特別注意的是,每個路徑是使用 /
進行分割的
以 myredis 為例,spec.set.replica.replicaCount
這個路徑就是 /spec/set/replica.replicaCount
為什麼 relica.replicaCount
這個路徑是使用 .
分割,而不是 /
呢?
因為他是一個 key 而不是一個路徑
所以寫起來會長這樣
1
2
3
4
5
6
7
[
{
"op": "replace",
"path": "/spec/set/replica.replicaCount",
"value": 10
}
]
如果是遇到 array, 假設是
1
2
3
4
5
apiVersion: v1
kind: Pod
spec:
containers:
- image: nginx:1.14.2
你想要換 image
他的 JSON patch 會是 /spec/containers/0/image
patch 的指令會長這樣
1
$ kubectl patch HelmChart myredis --type json --patch-file ./patch.json
如果你仔細去看它的 log, 你會發現它其實就真的只是做了 $ helm upgrade
1
+ helm_v3 upgrade --set replica.replicaCount=10 myredis myredis/redis
Leave a comment