使用 Kustomize 定制 Helm Chart
如果你經(jīng)常使用 Kubernetes,那么應(yīng)該對 Helm 和 Kustomize 不陌生,這兩個工具都是用來管理 Kubernetes 資源清單的,但是二者有著不同的工作方式。
Helm 使用的是模板,一個 Helm Chart 包中包含了很多模板和值文件,當(dāng)被渲染時模板中的變量會使用值文件中對應(yīng)的值替換。而 Kustomize 使用的是一種無模板的方式,它對 YAML 文件進(jìn)行修補(bǔ)和合并操作,此外 Kustomize 也已經(jīng)被原生內(nèi)置到 kubectl 中了。這兩個工具在 Kubernetes 的生態(tài)系統(tǒng)中都被廣泛使用,而且這兩個工具也可以一起結(jié)合使用。
我們知道很多項目其實都會為應(yīng)用程序提供 Helm Chart 包,而模板變量的值通過值文件來控制。一個長期存在的問題就是我們應(yīng)該如何定制上游的 Helm Chart 包,例如從 Helm Chart 包中添加或者一個 Kubernetes 資源清單,如果是通用的變更,最好的選擇當(dāng)然是直接貢獻(xiàn)給上游倉庫,但是如果是自定義的變更呢?
通常我們可以自己 fork 上游的 Helm Chart 倉庫,然后在自己的 repo 中對 Chart 包進(jìn)行額外的變動。但是這樣做,顯然會帶來額外的負(fù)擔(dān),特別是當(dāng) Chart 包只需要一點小改動的時候。
這個時候我們可以使用 Kustomize 來定制現(xiàn)有的 Helm Chart,而不需要執(zhí)行 fork 操作。
本文使用的 Helm 版本為 3.3.1、Kustomize 3.8.2,主要參考文檔:3 ways to customize off-the-shelf Helm charts with Kustomize[1]。
使用 Chart 插件自定義
Kustomize 提供了一個很好的插件生態(tài)系統(tǒng),允許擴(kuò)展 Kustomize 的功能。其中就有一個名為 ChartInflator[2] 的非內(nèi)置插件,它允許 Kustomize 來渲染 Helm Charts,并執(zhí)行任何需要的變更。
首先先安裝 ChartInflator 插件:
$?chartinflator_dir="./kustomize/plugin/kustomize.config.k8s.io/v1/chartinflator"
#?創(chuàng)建插件目錄
$?mkdir?-p?${chartinflator_dir}
#?下載插件
$?curl?-L?https://raw.githubusercontent.com/kubernetes-sigs/kustomize/kustomize/v3.8.2/plugin/someteam.example.com/v1/chartinflator/ChartInflator?>?${chartinflator_dir}/ChartInflator
#?設(shè)置插件執(zhí)行權(quán)限
$?chmod?u+x?${chartinflator_dir}/ChartInflator
比如我們要定制 Vault Helm Chart[3] 包,接下來創(chuàng)建 ChartInflator 資源清單和 Helm 的 values.yaml 值文件:
#?ChartInflator?資源清單
$?cat?<>?chartinflator-vault.yaml
apiVersion:?kustomize.config.k8s.io/v1
kind:?ChartInflator
metadata:
??name:?vault-official-helm-chart
chartRepo:?https://helm.releases.hashicorp.com??
chartName:?vault
chartRelease:?hashicorp
chartVersion:?0.7.0
releaseName:?vault
values:?values.yaml
EOF
#?創(chuàng)建?values?值文件
$?helm?repo?add?hashicorp?https://helm.releases.hashicorp.com?
$?helm?show?values?--version?0.7.0?hashicorp/vault?>?values.yaml
#?創(chuàng)建?Kustomize?文件
$?kustomize?init
$?cat?<>?kustomization.yaml
generators:
-?chartinflator-vault.yaml
EOF
#?為所有資源添加一個?label?標(biāo)簽
$?kustomize?edit?add?label?env:dev
#?最后生成的 kustomize 文件如下所示:
$?cat?kustomization.yaml
apiVersion:?kustomize.config.k8s.io/v1beta1
kind:?Kustomization
generators:
-?chartinflator-vault.yaml
commonLabels:
??env:?dev
#?整個資源清單目錄結(jié)構(gòu)
$?tree?.
.
├──?chartinflator-vault.yaml
├──?kustomization.yaml
├──?kustomize
│???└──?plugin
│???????└──?kustomize.config.k8s.io
│???????????└──?v1
│???????????????└──?chartinflator
│???????????????????└──?ChartInflator
└──?values.yaml
5?directories,?4?files
現(xiàn)在就可以來渲染 Chart 模板了,執(zhí)行如下所示的命令即可:
$?kustomize?build?--enable_alpha_plugins?.
正常渲染完成后我們可以看到所有的資源上都被添加了一個 env: dev 的標(biāo)簽,這是實時完成的,不需要維護(hù)任何額外的文件的。
用單個清單文件定制
另一種使用 Kustomize 定制 Chart 的方法是使用 helm template 命令來生成一個單一的資源清單,這種方式可以對 Chart 進(jìn)行更多的控制,但它需要更多的工作來出來處理更新該生成文件的版本控制。
通常我們可以使用 Make 來進(jìn)行輔助處理,如下示例所示:
#?Makefile
CHART_REPO_NAME???:=?hashicorp
CHART_REPO_URL????:=?https://helm.releases.hashicorp.com
CHART_NAME????????:=?vault
CHART_VERSION?????:=?0.7.0
CHART_VALUES_FILE?:=?values.yaml
add-chart-repo:
????helm?repo?add?${CHART_REPO_NAME}?${CHART_REPO_URL}
????helm?repo?update
generate-chart-manifest:
????helm?template?${CHART_NAME}?${CHART_REPO_NAME}/${CHART_NAME}?\
????????--version?${CHART_VERSION}?\
????????--values?${CHART_VALUES_FILE}?>?${CHART_NAME}.yaml
get-chart-values:
????@helm?show?values?--version?${CHART_VERSION}?\
????${CHART_REPO_NAME}/${CHART_NAME}
generate-chart-values:
????@echo?"Create?values?file:?${CHART_VALUES_FILE}"
????@$(MAKE)?-s?get-chart-values?>?${CHART_VALUES_FILE}
diff-chart-values:
????@echo?"Diff:?Local?<==>?Remote"
????@$(MAKE)?-s?get-chart-values?|?\
????diff?--suppress-common-lines?--side-by-side?${CHART_VALUES_FILE}?-?||?\
????exit?0
要定制上游的 Vault Helm Chart,我們可以做如下操作:
#?初始化?chart?文件
$?make?generate-chart-values?generate-chart-manifest?
#?創(chuàng)建?Kustomize?文件并添加一個?label?標(biāo)簽
$?kustomize?init
$?kustomize?edit?add?resource?vault.yaml
$?kustomize?edit?add?label?env:dev
#?最后生成的文件結(jié)構(gòu)如下所示
$?tree?.
.
├──?kustomization.yaml
├──?makefile
├──?values.yaml
└──?vault.yaml
0?directories,?4?files
#?kustomize?文件內(nèi)容如下所示
$?cat?kustomization.yaml
apiVersion:?kustomize.config.k8s.io/v1beta1
kind:?Kustomization
resources:
-?vault.yaml
commonLabels:
??env:?dev
最后同樣用 kustomize build 命令來渲染:
$?kustomize?build?.
在渲染的結(jié)果中同樣可以看到所有的資源里面都被添加進(jìn)了一個 env: dev 的標(biāo)簽。
這種方法,需要以某種方式運(yùn)行 make 命令來生成更新的一體化資源清單文件,另外,要將更新過程與你的 GitOps 工作流整合起來可能有點麻煩。
使用 Post Rendering 定制
Post Rendering[4] 是 Helm 3 帶來的一個新功能,在前面的2種方法中,Kustomize 是用來處理生成圖表清單的主要工具,但在這里,Kustomize 是作為 Helm 的輔助工具而存在的。
下面我們來看下如何使用這種方法來進(jìn)行定制:
#?創(chuàng)建?Kustomize?文件并添加一個?label?標(biāo)簽
$?kustomize?init
$?kustomize?edit?add?label?env:dev
#?創(chuàng)建一個包裝?Kustomize?的腳本文件,后面在?Helm?中會使用到
$?cat?<?kustomize-wrapper.sh
#!/bin/bash
cat?<&0?>?chart.yaml
kustomize?edit?add?resource?chart.yaml
kustomize?build?.?&&?rm?chart.yaml
EOF
$?chmod?+x?kustomize-wrapper.sh
然后我們可以直接使用 Helm 渲染或者安裝 Chart:
$?helm?repo?add?hashicorp?https://helm.releases.hashicorp.com?
$?helm?template?vault?hashicorp/vault?--post-renderer?./kustomize-wrapper.sh
正常情況下我們也可以看到最后渲染出來的每一個資源文件中都被添加進(jìn)了一個 env:dev 的標(biāo)簽。
這種方法就是需要管理一個額外的腳本,其余的和第一種方式基本上差不多,只是不使用 Kustomize 的插件,而是直接使用 Helm 本身的功能來渲染上游的 Chart 包。
總結(jié)
我們可以看到上面幾種方法都各有優(yōu)缺點,使用哪種方式主要還是取決于我們自己的工作環(huán)境和工作流程,不過至少我們已經(jīng)看到了 Kustomize 與 Helm 結(jié)合使用的高效了。
參考資料
3 ways to customize off-the-shelf Helm charts with Kustomize: https://tech.aabouzaid.com/2020/09/3-ways-to-customize-off-the-shelf-helm-charts-with-kustomize-kubernetes.html
[2]ChartInflator: https://github.com/kubernetes-sigs/kustomize/blob/v3.3.1/plugin/someteam.example.com/v1/chartinflator/ChartInflator
[3]Vault Helm Chart: https://github.com/hashicorp/vault-helm
[4]Post Rendering: https://helm.sh/docs/topics/advanced/#post-rendering
K8S進(jìn)階訓(xùn)練營,點擊下方圖片了解詳情

