您可以閱讀有關 helmfile 本身及其使用示例的信息
我們將熟悉在 helmfile 中描述版本的非顯而易見的方式
假設我們有一組 Helm Charts(例如,Postgres 和一些後端應用程序)和幾個環境(幾個 kubernetes 集群、幾個命名空間或兩者兼而有之)。 我們獲取 helmfile,閱讀文檔並開始描述我們的環境和版本:
.
├── envs
│ ├── devel
│ │ └── values
│ │ ├── backend.yaml
│ │ └── postgres.yaml
│ └── production
│ └── values
│ ├── backend.yaml
│ └── postgres.yaml
└── helmfile.yaml
helmfile.yaml
environments:
devel:
production:
releases:
- name: postgres
labels:
app: postgres
wait: true
chart: stable/postgresql
version: 8.4.0
values:
- envs/{{ .Environment.Name }}/values/postgres.yaml
- name: backend
labels:
app: backend
wait: true
chart: private-helm-repo/backend
version: 1.0.5
needs:
- postgres
values:
- envs/{{ .Environment.Name }}/values/backend.yaml
我們最終得到了 2 個環境: 開發, 生產 — 每個都包含其自己的 helm 發布圖表值。 我們將像這樣部署到他們:
helmfile -n <namespace> -e <env> apply
不同環境下不同版本的 Helm Chart
如果我們需要將不同版本的後端部署到不同的環境怎麼辦? 如何參數化發布版本? 環境價值可通過 {{ .Values }}
helmfile.yaml
environments:
devel:
+ values:
+ - charts:
+ versions:
+ backend: 1.1.0
production:
+ values:
+ - charts:
+ versions:
+ backend: 1.0.5
...
- name: backend
labels:
app: backend
wait: true
chart: private-helm-repo/backend
- version: 1.0.5
+ version: {{ .Values.charts.versions.backend }}
...
不同環境下的不同應用程序集
很好,但是如果我們不需要怎麼辦? production
推出 postgres,因為我們知道我們不需要將數據庫推送到 k8s,並且我們有一個很棒的獨立 postgres 集群可供出售? 為了解決這個問題我們有標籤
helmfile -n <namespace> -e devel apply
helmfile -n <namespace> -e production -l app=backend apply
這很棒,但我個人更喜歡不使用啟動參數,而是在環境本身的描述中描述要在環境中部署哪些應用程序。 該怎麼辦? 您可以將版本描述放在單獨的文件夾中,在環境描述中創建必要版本的列表,然後僅“選取”必要的版本,忽略其餘版本
.
├── envs
│ ├── devel
│ │ └── values
│ │ ├── backend.yaml
│ │ └── postgres.yaml
│ └── production
│ └── values
│ ├── backend.yaml
│ └── postgres.yaml
+ ├── releases
+ │ ├── backend.yaml
+ │ └── postgres.yaml
└── helmfile.yaml
helmfile.yaml
environments:
devel:
values:
- charts:
versions:
backend: 1.1.0
- apps:
- postgres
- backend
production:
values:
- charts:
versions:
backend: 1.0.5
- apps:
- backend
- releases:
- - name: postgres
- labels:
- app: postgres
- wait: true
- chart: stable/postgresql
- version: 8.4.0
- values:
- - envs/{{ .Environment.Name }}/values/postgres.yaml
- - name: backend
- labels:
- app: backend
- wait: true
- chart: private-helm-repo/backend
- version: {{ .Values.charts.versions.backend }}
- needs:
- - postgres
- values:
- - envs/{{ .Environment.Name }}/values/backend.yaml
+ ---
+ bases:
+ {{- range .Values.apps }}
+ - releases/{{ . }}.yaml
+ {{- end }}
releases/postgres.yaml
releases:
- name: postgres
labels:
app: postgres
wait: true
chart: stable/postgresql
version: 8.4.0
values:
- envs/{{ .Environment.Name }}/values/postgres.yaml
releases/backend.yaml
releases:
- name: backend
labels:
app: backend
wait: true
chart: private-helm-repo/backend
version: {{ .Values.charts.versions.backend }}
needs:
- postgres
values:
- envs/{{ .Environment.Name }}/values/backend.yaml
筆記
當使用 bases:
需要使用yaml分隔符 ---
,以便您可以使用環境中的值來模板發布(以及其他部分,例如 helmDefaults)
在這種情況下,postgres 版本甚至不會包含在生產描述中。 很舒服!
發布的可重寫全局值
當然,您可以為每個環境設置 helm 圖表的值,但是如果我們描述了多個環境,並且我們希望為所有環境設置相同的值,該怎麼辦? affinity
,但我們不想在存儲在蘿蔔中的圖表本身中默認配置它。
在這種情況下,對於每個版本,我們可以指定2 個帶有值的文件:第一個帶有默認值,它將確定圖表本身的值,第二個帶有環境值,這反過來將覆蓋圖表本身的值。默認的。
.
├── envs
+ │ ├── default
+ │ │ └── values
+ │ │ ├── backend.yaml
+ │ │ └── postgres.yaml
│ ├── devel
│ │ └── values
│ │ ├── backend.yaml
│ │ └── postgres.yaml
│ └── production
│ └── values
│ ├── backend.yaml
│ └── postgres.yaml
├── releases
│ ├── backend.yaml
│ └── postgres.yaml
└── helmfile.yaml
releases/backend.yaml
releases:
- name: backend
labels:
app: backend
wait: true
chart: private-helm-repo/backend
version: {{ .Values.charts.versions.backend }}
needs:
- postgres
values:
+ - envs/default/values/backend.yaml
- envs/{{ .Environment.Name }}/values/backend.yaml
envs/default/values/backend.yaml
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- backend
topologyKey: "kubernetes.io/hostname"
在環境級別定義所有版本的 Helm Chart 的全局值
假設我們在多個版本中創建多個入口 - 我們可以為每個圖表手動定義 hosts:
,但在我們的例子中,域是相同的,那麼為什麼不將其放入某個全局變量中並簡單地將其值替換到圖表中呢? 為此,那些具有我們想要參數化值的文件必須具有擴展名 .gotmpl
,這樣helmfile就知道它需要通過模板引擎來運行。
.
├── envs
│ ├── default
│ │ └── values
- │ │ ├── backend.yaml
- │ │ ├── postgres.yaml
+ │ │ ├── backend.yaml.gotmpl
+ │ │ └── postgres.yaml.gotmpl
│ ├── devel
│ │ └── values
│ │ ├── backend.yaml
│ │ └── postgres.yaml
│ └── production
│ └── values
│ ├── backend.yaml
│ └── postgres.yaml
├── releases
│ ├── backend.yaml
│ └── postgres.yaml
└── helmfile.yaml
helmfile.yaml
environments:
devel:
values:
- charts:
versions:
backend: 1.1.0
- apps:
- postgres
- backend
+ - global:
+ ingressDomain: k8s.devel.domain
production:
values:
- charts:
versions:
backend: 1.0.5
- apps:
- backend
+ - global:
+ ingressDomain: production.domain
---
bases:
{{- range .Values.apps }}
- releases/{{ . }}.yaml
{{- end }}
envs/default/values/backend.yaml.gotmpl
ingress:
enabled: true
paths:
- /api
hosts:
- {{ .Values.global.ingressDomain }}
envs/default/values/postgres.yaml.gotmpl
ingress:
enabled: true
paths:
- /
hosts:
- postgres.{{ .Values.global.ingressDomain }}
筆記
顯然,postgres 圖表中的 ingress 是非常可疑的東西,因此本文僅作為真空中的球形示例給出,以免僅僅為了描述 ingress 而在文章中引入一些新版本
用環境值替換秘密
類比上面的例子,你可以使用加密的來替換
.
├── envs
│ ├── default
│ │ └── values
│ │ ├── backend.yaml
│ │ └── postgres.yaml
│ ├── devel
│ │ ├── values
│ │ │ ├── backend.yaml
│ │ │ └── postgres.yaml
+ │ │ └── secrets.yaml
│ └── production
│ ├── values
│ │ ├── backend.yaml
│ │ └── postgres.yaml
+ │ └── secrets.yaml
├── releases
│ ├── backend.yaml
│ └── postgres.yaml
└── helmfile.yaml
helmfile.yaml
environments:
devel:
values:
- charts:
versions:
backend: 1.1.0
- apps:
- postgres
- backend
- global:
ingressDomain: k8s.devel.domain
+ secrets:
+ - envs/devel/secrets.yaml
production:
values:
- charts:
versions:
backend: 1.0.5
- apps:
- backend
- global:
ingressDomain: production.domain
+ secrets:
+ - envs/production/secrets.yaml
---
bases:
{{- range .Values.apps }}
- releases/{{ . }}.yaml
{{- end }}
envs/devel/secrets.yaml
secrets:
elastic:
password: ENC[AES256_GCM,data:hjCB,iv:Z1P6/6xBJgJoKLJ0UUVfqZ80o4L84jvZfM+uH9gBelc=,tag:dGqQlCZnLdRAGoJSj63rBQ==,type:int]
...
envs/production/secrets.yaml
secrets:
elastic:
password: ENC[AES256_GCM,data:ZB/VpTFk8f0=,iv:EA//oT1Cb5wNFigTDOz3nA80qD9UwTjK5cpUwLnEXjs=,tag:hMdIUaqLRA8zuFBd82bz6A==,type:str]
...
envs/default/values/backend.yaml.gotmpl
elasticsearch:
host: elasticsearch
port: 9200
password: {{ .Values | getOrNil "secrets.elastic.password" | default "password" }}
envs/devel/values/backend.yaml
elasticsearch:
host: elastic-0.devel.domain
envs/production/values/backend.yaml
elasticsearch:
host: elastic-0.production.domain
筆記
順便說一句, getOrNil
- helmfile 中 go 模板的特殊函數,即使 .Values.secrets
將不存在,不會拋出錯誤,但將允許使用該函數的結果 default
替換默認值
結論
描述的事情看起來很明顯,但是關於使用 helmfile 方便地描述部署到多個環境的信息非常稀缺,而且我喜歡 IaC(基礎設施即代碼)並且希望對部署狀態有清晰的描述。
最後,我想補充一點,默認環境的變量可以反過來用將啟動部署的某個運行器的操作系統的環境變量進行參數化,從而獲得動態環境
helmfile.yaml
environments:
default:
values:
- global:
clusterDomain: {{ env "CLUSTER_DOMAIN" | default "cluster.local" }}
ingressDomain: {{ env "INGRESS_DOMAIN" }}
來源: www.habr.com