13個(gè)使用Helm部署應(yīng)用程序的實(shí)踐
譯文【51CTO.com快譯】Helm 是 Kubernetes 的包管理器。由于其模板方法和可重用和生產(chǎn)就緒包(也稱為 Helm charts))的豐富生態(tài)系統(tǒng),它減少了部署復(fù)雜應(yīng)用程序的工作量。有了Helm可以將打包的應(yīng)用程序部署為一組版本化、預(yù)配置的 Kubernetes 資源。
假設(shè)你正在使用 Kubernetes 部署一個(gè)數(shù)據(jù)庫(kù),包括多個(gè)部署、容器、服務(wù)等。Helm 允許你使用單個(gè)命令和一組值安裝相同的數(shù)據(jù)庫(kù)。其聲明性和冪等性命令使 Helm 成為持續(xù)交付 (CD) 的理想工具。
隨著最新版本的Helm 3的發(fā)布,它與Kubernetes的生態(tài)系統(tǒng)融合得更加緊密。
本文介紹了創(chuàng)建Helm Chart來(lái)管理在Kubernetes中運(yùn)行的應(yīng)用程序的13個(gè)實(shí)踐案例。
1.充分利用Helm生態(tài)系統(tǒng)
Helm為你提供了豐富的社區(qū)專業(yè)知識(shí)——這可能是該工具最大的好處。它從世界各地的開(kāi)發(fā)人員那里收集圖表,然后通過(guò)圖表庫(kù)進(jìn)行共享。你可以將官方穩(wěn)定圖表庫(kù)添加到本地,設(shè)置如下:
$ helm repo add stable https://charts.helm.sh/stable
"stable" has been added to your repositories
Then you can search for charts, for example, MySQL:
$ helm search hub mysql
URL CHART VERSION APP VERSION DESCRIPTION
https://hub.helm.sh/charts/bitnami/mysql 8.2.3 8.0.22 Chart to create a Highly available MySQL cluster
https://hub.helm.sh/charts/t3n/mysql 0.1.0 8.0.22 Fast, reliable, scalable, and easy to use open-...
你會(huì)看到一長(zhǎng)串的結(jié)果列表,可以看得出Helm圖表的生態(tài)系統(tǒng)有多大。
2. 使用子圖來(lái)管理你的依賴
由于部署到Kubernetes的應(yīng)用程序由細(xì)粒度的、相互依賴的部分組成,因此它們的Helm圖表具有各種資源模板和依賴項(xiàng)。例如,假設(shè)后端依賴于數(shù)據(jù)庫(kù)和消息隊(duì)列。數(shù)據(jù)庫(kù)和消息隊(duì)列已經(jīng)是獨(dú)立的應(yīng)用(如PostgreSQL和RabbitMQ)。因此,建議為獨(dú)立應(yīng)用程序創(chuàng)建或使用單獨(dú)的圖表,并將它們添加到父圖表中。依賴的應(yīng)用程序在這里被命名為子圖表。
創(chuàng)建和配置子圖表有三個(gè)基本要素:
- 文件夾結(jié)構(gòu)的順序如下:
backend-chart
- Chart.yaml
- charts
- message-queue
- Chart.yaml
- templates
- values.yaml
- database
- Chart.yaml
- templates
- values.yaml
- values.yaml
- Chart.yaml
另外Chart.yaml在父圖表中應(yīng)該列出任何依賴關(guān)系和條件:
apiVersion: v2
name: backend-chart
description: A Helm chart for backend
...
dependencies:
- name: message-queue
condition: message-queue.enabled
- name: database
condition: database.enabled
- values.yaml
最后,你可以使用以下 values.yaml 文件設(shè)置或覆蓋父圖表中子圖表的值:
message-queue:
enabled: true
image:
repository: acme/rabbitmq
tag: latest
database:
enabled: false
創(chuàng)建和使用子圖表在父應(yīng)用程序和依賴程序之間建立了一個(gè)抽象層。這些單獨(dú)的圖表使Kubernetes中的應(yīng)用程序易于部署、調(diào)試和更新,這些應(yīng)用程序具有各自的值和升級(jí)生命周期。你可以在像??bitnami/wordpress??這樣的示例圖表中瀏覽文件夾結(jié)構(gòu)、依賴項(xiàng)和值文件。
3.使用標(biāo)簽輕松找到資源
標(biāo)簽對(duì)于Kubernetes的內(nèi)部運(yùn)營(yíng)和Kubernetes運(yùn)營(yíng)商的日常工作至關(guān)重要。Kubernetes中的幾乎每個(gè)資源都為不同的目的提供了標(biāo)簽,例如分組、資源分配、負(fù)載平衡或調(diào)度。
一個(gè)Helm命令將允許你安裝多個(gè)資源。但重要的是要知道這些資源的來(lái)源。標(biāo)簽可以讓你快速找到由Helm版本創(chuàng)建的資源。
最常用的方法是在 中定義標(biāo)簽`helpers.tpl`,如下所示:
{{/*
Common labels
*/}}
{{- define "common.labels" -}}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}
然后你需要在資源模板中使用帶標(biāo)簽的" include "函數(shù):
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-queue
labels:
{{ include "labels" . | indent 4 }}
...
現(xiàn)在你應(yīng)該能夠使用標(biāo)簽選擇器列出所有資源。例如,您可以使用該`kubectl get pods -l app.kubernetes.io/instance=[Name of the Helm Release]`命令列出 my-queue 部署的所有 pod 。這一步對(duì)于定位和調(diào)試 Helm 管理的資源至關(guān)重要。
4. 記錄你的圖表
文檔對(duì)于確保可維護(hù)的 Helm 圖表至關(guān)重要。在資源模板和 README 中添加注釋可幫助團(tuán)隊(duì)開(kāi)發(fā)和使用 Helm 圖表。
你應(yīng)該使用以下三個(gè)選項(xiàng)來(lái)記錄你的圖表:
- 注釋:模板和值文件是 YAML 文件。你可以添加注釋,并提供有關(guān)YAML文件中的字段的有用信息。
- README:圖表的README是一個(gè)解釋如何使用圖表的標(biāo)記文件。你可以使用以下命令檢查 README 文件的內(nèi)容:`helm show readme [Name of the Chart]`
- NOTES.txt:這是一個(gè)位于`templates/NOTES.txt` 中的特殊文件,提供有關(guān)版本部署的有用信息。`NOTES.txt`文件的內(nèi)容也可以使用類似于資源模板的函數(shù)和值進(jìn)行模板化:
You have deployed the following release: {{ .Release.Name }}.
To get further information, you can run the commands:
$ helm status {{ .Release.Name }}
$ helm get all {{ .Release.Name }}
在 helm install 或 helm upgrade 命令結(jié)束時(shí),Helm 會(huì)打印出 NOTES.txt 的內(nèi)容,如下所示:
RESOURCES:
==> v1/Secret
NAME TYPE DATA AGE
my-secret Opaque 1 0s
==> v1/ConfigMap
NAME DATA AGE
db-configmap 3 0s
NOTES:
You have deployed the following release: precious-db.
To get further information, you can run the commands:
$ helm status precious-db
$ helm get all precious-db
5. 測(cè)試你的 Charts
Helm charts 由多個(gè)要部署到集群的資源組成。必須檢查是否在集群中創(chuàng)建的所有資源都具有正確的值。例如,在部署數(shù)據(jù)庫(kù)時(shí),你應(yīng)該檢查數(shù)據(jù)庫(kù)密碼設(shè)置是否正確。
幸運(yùn)的是,Helm提供了一個(gè)測(cè)試功能,可以在集群中運(yùn)行一些容器,以驗(yàn)證應(yīng)用程序。例如,注解的資源模板`"helm.sh/hook": test-success`由 Helm 作為測(cè)試用例運(yùn)行。
讓我們假設(shè)你正在部署帶有MariaDB數(shù)據(jù)庫(kù)的WordPress。Bitnami維護(hù)的Helm圖表有一個(gè)pod來(lái)驗(yàn)證數(shù)據(jù)庫(kù)連接,定義如下:
...
apiVersion: v1
kind: Pod
metadata:
name: "{{ .Release.Name }}-credentials-test"
annotations:
"helm.sh/hook": test-success
...
env:
- name: MARIADB\_HOST
value: {{ include "wordpress.databaseHost" . | quote }}
- name: MARIADB\_PORT
value: "3306"
- name: WORDPRESS\_DATABASE\_NAME
value: {{ default "" .Values.mariadb.auth.database | quote }}
- name: WORDPRESS\_DATABASE\_USER
value: {{ default "" .Values.mariadb.auth.username | quote }}
- name: WORDPRESS\_DATABASE\_PASSWORD
valueFrom:
secretKeyRef:
name: {{ include "wordpress.databaseSecretName" . }}
key: mariadb-password
command:
- /bin/bash
- -ec
- |
mysql --host=$MARIADB\_HOST --port=$MARIADB\_PORT --user=$WORDPRESS\_DATABASE\_USER --password=$WORDPRESS\_DATABASE\_PASSWORD
restartPolicy: Never
{{- end }}
...
建議為你的圖表編寫(xiě)測(cè)試并在安裝后運(yùn)行它們。例如,你可以使用 helm test`<RELEASE_NAME>`命令運(yùn)行測(cè)試。這些測(cè)試對(duì)于驗(yàn)證和發(fā)現(xiàn)與Helm安裝的應(yīng)用程序中的問(wèn)題是很有價(jià)值的資產(chǎn)。
6.確保你的秘密安全
敏感數(shù)據(jù),如密鑰或密碼,在Kubernetes中作為機(jī)密存儲(chǔ)。盡管在Kubernetes方面保護(hù)機(jī)密是可能的,但它們大多存儲(chǔ)為文本文件,作為Helm模板和值的一部分。
helm-secrets插件為您的關(guān)鍵信息提供秘密管理和保護(hù)。它將秘密加密委托給Mozilla sop,后者支持AWS KMS、GCP上的Cloud KMS、Azure Key Vault和PGP。
假設(shè)你已將敏感數(shù)據(jù)收集在名為 secrets.yaml 的文件中,如下所示:
postgresql: postgresqlUsername: postgres postgresqlPassword: WoZpCAlBsg postgresqlDatabase: wp
你可以使用插件加密文件:
$ helm secrets enc secrets.yamlEncrypting secrets.yamlEncrypted secrets.yaml
現(xiàn)在,文件將被更新并且所有值都將被加密:
postgresql: postgresqlUsername: ENC\[AES256\_GCM,data:D14/CcA3WjY=,iv...==,type:str\] postgresqlPassword: ENC\[AES256\_GCM,data:Wd7VEKSoqV...,type:str\] postgresqlDatabase: ENC\[AES256\_GCM,data:8ur9pqDxUA==,iv:R...,type:str\]sops: ...
上面secrets.yaml 中的數(shù)據(jù)并不安全,helm-secrets 解決了將敏感數(shù)據(jù)存儲(chǔ)為Helm charts 的一部分問(wèn)題。
7.使用模板函數(shù)使圖表可重用
Helm支持超過(guò)60個(gè)函數(shù),可以在模板中使用。這些函數(shù)在Go模板語(yǔ)言和Sprig模板庫(kù)中定義。模板文件中的函數(shù)顯著簡(jiǎn)化了Helm操作。
讓我們以下面的模板文件為例:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
environment: {{ .Values.environment | default "dev" | quote }}
region: {{ .Values.region | upper | quote }}
當(dāng)沒(méi)有提供環(huán)境值時(shí),模板函數(shù)會(huì)默認(rèn)。當(dāng)檢查區(qū)域字段時(shí),你會(huì)看到模板中沒(méi)有定義默認(rèn)值。但是,該字段有另一個(gè)名為 upper 的函數(shù),用于將提供的值轉(zhuǎn)換為大寫(xiě)。
另一個(gè)重要且有用的功能是`required`. 它使您能夠根據(jù)模板渲染的需要設(shè)置一個(gè)值。例如,假設(shè)你需要使用以下模板為 ConfigMap 命名:
...metadata: name: {{ required "Name is required" .Values.configName }}...
如果該條目為空,則模板渲染將失敗并顯示錯(cuò)誤 Name is required。創(chuàng)建 Helm 圖表時(shí),模板函數(shù)非常有用。它們可以改進(jìn)模板、減少代碼重復(fù),并可用于在將應(yīng)用程序部署到 Kubernetes 之前驗(yàn)證值。
8.當(dāng) ConfigMaps 或 Secrets 改變時(shí)更新你的部署
將 ConfigMaps 或 Secrets 安裝到容器是很常見(jiàn)的。盡管部署和容器映像會(huì)隨著新版本而變化,但 ConfigMap 或機(jī)密不會(huì)經(jīng)常更改。以下注釋可以在 ConfigMap 更改時(shí)推出新部署:
kind: Deployment
spec:
template:
metadata:
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
...
ConfigMap 中的任何更改都將計(jì)算`sha256sum`新的部署版本并創(chuàng)建新版本。這確保部署中的容器將使用新的 ConfigMap 重新啟動(dòng)。
9. 使用資源策略選擇退出資源刪除
在典型的設(shè)置中,安裝 Helm chart 后,Helm 將在集群中創(chuàng)建多個(gè)資源。然后,您可以通過(guò)更改值以及添加或刪除資源來(lái)升級(jí)它。一旦您不再需要該應(yīng)用程序,您可以將其刪除,這會(huì)從集群中移除所有資源。
但是,即使在運(yùn)行 Helm 卸載之后,某些資源也應(yīng)保留在集群中。假設(shè)您已經(jīng)使用 PersistentVolumeClaim 部署了一個(gè)數(shù)據(jù)庫(kù),并且即使您要?jiǎng)h除數(shù)據(jù)庫(kù)版本也希望存儲(chǔ)卷。對(duì)于此類資源,您需要使用資源策略注釋,如下所示:
kind: Secretmetadata: annotations: "helm.sh/resource-policy": keep...
Helm 命令(例如卸載、升級(jí)或回滾)會(huì)導(dǎo)致刪除上述機(jī)密。但是通過(guò)使用如上所示的資源策略,Helm 將跳過(guò)秘密的刪除并允許它成為孤立的。因此,應(yīng)該非常小心地使用注釋,并且僅用于在 Helm Releases 被刪除后所需的資源。
10. 調(diào)試 Helm Chart 的有用命令
Helm 模板文件帶有許多不同的功能和用于創(chuàng)建 Kubernetes 資源的多個(gè)值來(lái)源。了解部署到集群的內(nèi)容是用戶的基本職責(zé)。因此,你需要學(xué)習(xí)如何調(diào)試模板和驗(yàn)證圖表。有四個(gè)基本命令可用于調(diào)試:
- helm lint:linter 工具進(jìn)行一系列測(cè)試以確保您的圖表正確形成。
- helm install —dry-run — debug:此函數(shù)呈現(xiàn)模板并顯示生成的資源清單。您還可以在部署之前檢查所有資源,并確保設(shè)置了值并且模板功能按預(yù)期工作。
- helm get manifest:此命令檢索安裝到集群的資源的清單。如果發(fā)布未按預(yù)期運(yùn)行,這應(yīng)該是您用來(lái)找出集群中正在運(yùn)行的內(nèi)容的第一個(gè)命令。
- helm get values:此命令用于檢索安裝到集群的版本值。如果您對(duì)計(jì)算值或默認(rèn)值有任何疑問(wèn),這絕對(duì)應(yīng)該在您的工具帶中。
11.使用查找功能避免秘密再生
Helm 函數(shù)用于生成隨機(jī)數(shù)據(jù),例如密碼、密鑰和證書(shū)。隨機(jī)生成會(huì)在每次部署和升級(jí)時(shí)創(chuàng)建新的任意值并更新集群中的資源。例如,它可以在每次版本升級(jí)時(shí)替換集群中的數(shù)據(jù)庫(kù)密碼。這會(huì)導(dǎo)致客戶端在更改密碼后無(wú)法連接到數(shù)據(jù)庫(kù)。
為了解決這個(gè)問(wèn)題,建議隨機(jī)生成值并覆蓋集群中已有的值。例如:
{{- $rootPasswordValue := (randAlpha 16) | b64enc | quote }}
{{- $secret := (lookup "v1" "Secret" .Release.Namespace "db-keys") }}
{{- if $secret }}
{{- $rootPasswordValue = index $secret.data "root-password" }}
{{- end -}}
apiVersion: v1
kind: Secret
metadata:
name: db-keys
namespace: {{ .Release.Namespace }}
type: Opaque
data:
root-password: {{ $rootPasswordValue}}
上面的模板首先創(chuàng)建一個(gè) 16 個(gè)字符的 randAlpha 值,然后檢查集群中的秘密及其對(duì)應(yīng)的字段。如果找到,它會(huì)覆蓋并重用 rootPasswordValue 作為 root-password。
12. 遷移到 Helm 3 以獲得更簡(jiǎn)單、更安全的 Kubernetes 應(yīng)用程序
最新的Helm版本Helm 3提供了許多新功能,使其成為一個(gè)更輕、更精簡(jiǎn)的工具。Helm v3由于其增強(qiáng)的安全性和簡(jiǎn)單性而推薦使用。這包括:
- 刪除 Tiller:Tiller 是 Helm 服務(wù)器端組件,但由于在早期版本中對(duì)集群進(jìn)行更改所需的詳盡權(quán)限已從 v3 中刪除。這也造成了安全風(fēng)險(xiǎn),因?yàn)槿魏潍@得 Tiller 訪問(wèn)權(quán)限的人都會(huì)對(duì)您的集群擁有過(guò)多的權(quán)限。
- 改進(jìn)的圖表升級(jí)策略:Helm v2 依賴于雙向策略合并補(bǔ)丁。它將新版本與 ConfigMap 存儲(chǔ)中的版本進(jìn)行比較并應(yīng)用更改。相反,Helm v3 比較舊清單、集群中的狀態(tài)和新版本。因此,在升級(jí) Helm 版本時(shí),您的手動(dòng)更改不會(huì)丟失。這簡(jiǎn)化了升級(jí)過(guò)程并增強(qiáng)了應(yīng)用程序的可靠性。
有一個(gè)helm-2to3插件,你可以用以下命令安裝:
$ helm3 plugin install https://github.com/helm/helm-2to3
它是一個(gè)小但有用的插件,帶有清理、轉(zhuǎn)換和移動(dòng)命令,幫助你遷移和清理v2配置,并創(chuàng)建v3版本。
13. 保持持續(xù)交付管道的冪等性
Kubernetes 資源是聲明性的,因?yàn)樗鼈兊囊?guī)范和狀態(tài)存儲(chǔ)在集群中。同樣,Helm 需要?jiǎng)?chuàng)建聲明性模板和發(fā)布。因此,你需要在使用 Helm 時(shí)將持續(xù)交付和發(fā)布管理設(shè)計(jì)為冪等的。冪等操作是您可以多次應(yīng)用而不會(huì)改變第一次運(yùn)行后的結(jié)果的操作。
有兩個(gè)基本規(guī)則需要遵循:
- 始終使用該`helm upgrade --install`命令。如果圖表尚未安裝,它會(huì)安裝圖表。如果它們已經(jīng)安裝,它會(huì)升級(jí)它們。
- 使用`--atomic`標(biāo)志在 helm 升級(jí)期間操作失敗時(shí)回滾更改。這確保 Helm 版本不會(huì)停留在失敗狀態(tài)。
概括
Helm 是將應(yīng)用程序部署到 Kubernetes 集群不可或缺的工具。但是,只有遵循最佳實(shí)踐,您才能真正獲得 Helm 的好處。
本文中介紹的實(shí)踐將幫助你和你的團(tuán)隊(duì)創(chuàng)建、操作和升級(jí)生產(chǎn)級(jí)分布式應(yīng)用程序。從開(kāi)發(fā)的角度來(lái)看,你的 Helm 圖表將更易于維護(hù)和保護(hù)。在操作方面,你將享受自動(dòng)更新的部署、從刪除中節(jié)省資源,并學(xué)習(xí)如何測(cè)試和調(diào)試。
Helm的官方指南是檢查Helm命令和理解其設(shè)計(jì)理念的另一個(gè)很好的資源。有了這些資源以及本文中概述的最佳實(shí)踐和示例,就已經(jīng)準(zhǔn)備好創(chuàng)建和管理在Kubernetes上運(yùn)行的生產(chǎn)級(jí)Helm應(yīng)用程序了。
【51CTO譯稿,合作站點(diǎn)轉(zhuǎn)載請(qǐng)注明原文譯者和出處為51CTO.com】