â eine Wrapper fĂŒr , die es ermöglicht, an einem Ort zahlreiche Helm-Releases zu beschreiben, ihre Charts fĂŒr verschiedene Umgebungen zu parametrisieren und die Reihenfolge ihrer Bereitstellung festzulegen.
Ăber helmfile und Beispiele seiner Anwendung können Sie im und .
lesen. Wir werden uns mit weniger offensichtlichen Methoden beschÀftigen, um Releases in helmfile zu beschreiben.
Angenommen, wir haben eine Reihe von Helm-Charts (nehmen wir als Beispiel postgres und eine Backend-Anwendung) sowie mehrere Umgebungen (einige Kubernetes-Cluster, mehrere Namespaces oder auch beides). Wir nehmen helmfile, lesen die Dokumentation und beginnen, unsere Umgebungen und Releases zu beschreiben:
.
âââ envs
â âââ devel
â â âââ values
â â âââ backend.yaml
â â âââ postgres.yaml
â âââ production
â âââ values
â âââ backend.yaml
â âââ postgres.yaml
âââ helmfile.yamlhelmfile.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.yamlWir haben 2 Umgebungen erstellt: devel, production â in jeder befinden sich spezifische Werte fĂŒr die Helm-Chart-Releases. Wir werden sie so deployen:
helmfile -n -e applyVerschiedene Versionen von Helm-Charts in unterschiedlichen Umgebungen
Was tun, wenn wir verschiedene Backend-Versionen in unterschiedlichen Umgebungen bereitstellen mĂŒssen? Wie parametrieren wir die Release-Version? Hier kommen die Umgebungswerte ins Spiel, die ĂŒber {{ .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 }}
...Unterschiedlicher Satz von Anwendungen in verschiedenen Umgebungen
Das ist gut, aber was ist, wenn wir nicht production Postgres bereitstellen mĂŒssen, weil wir wissen, dass wir die Datenbank nicht in k8s packen sollten und fĂŒr die Produktion haben wir einen ausgezeichneten separaten Postgres-Cluster? Um dieses Problem zu lösen, haben wir Labels (labels)
helmfile -n -e devel apply
helmfile -n -e production -l app=backend applyDas ist groĂartig, aber persönlich wĂŒrde ich es vorziehen, die zu verwendenden Anwendungen in der Umgebung nicht ĂŒber Startargumente, sondern ĂŒber die Beschreibung der Umgebungen zu definieren. Was kann man tun? Man könnte die Release-Beschreibungen in einen separaten Ordner legen, in der Umgebungsbeschreibung eine Liste der benötigten Releases fĂŒhren und nur die relevanten Releases âeinbindenâ, wĂ€hrend die anderen ignoriert werden.
.
âââ envs
â  âââ devel
â  â  âââ values
â  â  âââ backend.yaml
â  â  âââ postgres.yaml
â  âââ production
â  âââ values
â  âââ backend.yaml
â  âââ postgres.yaml
+ âââ releases
+ â  âââ backend.yaml
+ â  âââ postgres.yaml
âââ helmfile.yaml
helmfile.yaml
umgebungen:
devel:
werte:
- charts:
versionen:
backend: 1.1.0
- apps:
- postgres
- backend
produktion:
werte:
- charts:
versionen:
backend: 1.0.5
- apps:
- backend
- releases:
- - name: postgres
- labels:
- app: postgres
- warten: true
- chart: stable/postgresql
- version: 8.4.0
- werte:
- - envs/{{ .Environment.Name }}/values/postgres.yaml
- - name: backend
- labels:
- app: backend
- warten: true
- chart: private-helm-repo/backend
- version: {{ .Values.charts.versions.backend }}
- needs:
- - postgres
- werte:
- - envs/{{ .Environment.Name }}/values/backend.yaml
+ ---
+ grundlagen:
+ {{- 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.yamlreleases/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.yamlHinweis
Bei der Nutzung Basen: Es muss unbedingt der YAML-Trenner verwendet werden ---, um Releases (und andere Teile wie helmDefaults) mit Werten aus den Umgebungen zu templatisieren
In diesem Fall wird das Postgres-Release nicht einmal in die Beschreibung fĂŒr die Produktion aufgenommen. Sehr praktisch!
Ăberschreibbare globale Werte fĂŒr Releases
Es ist natĂŒrlich groĂartig, dass wir fĂŒr jede Umgebung Werte fĂŒr Helm-Charts festlegen können, aber was ist, wenn wir mehrere Umgebungen beschrieben haben und zum Beispiel denselben Wert fĂŒr alle festlegen möchten? Affinity, aber wir möchten ihn nicht standardmĂ€Ăig in den Charts einstellen, die in den Repositories gespeichert sind.
In diesem Fall könnten wir fĂŒr jedes Release zwei Dateien mit Werten angeben: eine mit den Standardwerten, die die Werte des Charts bestimmen, und eine zweite mit den Werten fĂŒr die Umgebung, die wiederum die Standardwerte ĂŒberschreiben wird.
.
âââ 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.yamlreleases/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.yamlenvs/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"Festlegen globaler Werte fĂŒr Helm-Charts aller Releases auf Umgebungsniveau
Angenommen, wir erstellen in mehreren Releases mehrere Ingress â wir könnten manuell fĂŒr jedes Chart definieren hosts:, aber in unserem Fall ist die Domain die gleiche. Warum also nicht in eine globale Variable auslagern und einfach ihren Wert in die Charts einsetzen? DafĂŒr mĂŒssen die Dateien mit den Werten, die wir parametrisieren möchten, die Erweiterung haben .gotmpl, damit helmfile weiĂ, dass sie durch den Template-Renderer verarbeitet werden mĂŒssen.
.
âââ 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.yamlhelmfile.yaml
Umgebungen:
devel:
Werte:
- Charts:
Versionen:
backend: 1.1.0
- Apps:
- postgres
- backend
+ - global:
+ ingressDomain: k8s.devel.domain
produktion:
Werte:
- Charts:
Versionen:
backend: 1.0.5
- Apps:
- backend
+ - global:
+ ingressDomain: production.domain
---
Basen:
{{- range .Values.apps }}
- releases/{{ . }}.yaml
{{- end }}envs/default/values/backend.yaml.gotmpl
ingress:
aktiviert: true
pfade:
- /api
hosts:
- {{ .Values.global.ingressDomain }}envs/default/values/postgres.yaml.gotmpl
ingress:
enabled: true
paths:
- /
hosts:
- postgres.{{ .Values.global.ingressDomain }}Hinweis
Offensichtlich ist das Ingress in dem Postgres-Chart etwas, was in Frage gestellt werden kann. Daher wird es in diesem Artikel lediglich als theoretisches Beispiel ohne konkreten Bezug genutzt, um die Notwendigkeit eines neuen Releases nur zur Beschreibung des Ingress zu vermeiden.
EinfĂŒgen von Geheimnissen (Secrets) aus Umgebungswerten.
Ăhnlich wie im obigen Beispiel können auch verschlĂŒsselte Werte eingefĂŒgt werden. Werte. Anstatt fĂŒr jedes Release eine eigene Secrets-Datei zu erstellen, in der die verschlĂŒsselten Werte fĂŒr das Chart definiert sind, können wir einfach die im Release default.yaml.gotmpl definierten Werte verwenden, die aus auf Umgebungen festgelegten Variablen entnommen werden. Werte, die wir nicht geheim halten mĂŒssen, können in den Release-Werten des spezifischen Umfelds problemlos ĂŒberschrieben werden.
.
âââ 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.yamlhelmfile.yaml
Umgebungen:
devel:
Werte:
- Charts:
Versionen:
backend: 1.1.0
- Apps:
- postgres
- backend
- global:
ingressDomain: k8s.devel.domain
+ secrets:
+ - envs/devel/secrets.yaml
production:
Werte:
- Charts:
Versionen:
backend: 1.0.5
- Apps:
- backend
- global:
ingressDomain: production.domain
+ secrets:
+ - envs/production/secrets.yaml
---
basen:
{{- range .Values.apps }}
- releases/{{ . }}.yaml
{{- end }}envs/devel/secrets.yaml
secrets:
elastic:
passwort: ENC[AES256_GCM,data:hjCB,iv:Z1P6/6xBJgJoKLJ0UUVfqZ80o4L84jvZfM+uH9gBelc=,tag:dGqQlCZnLdRAGoJSj63rBQ==,type:int]
...envs/production/secrets.yaml
secrets:
elastic:
passwort: ENC[AES256_GCM,data:ZB/VpTFk8f0=,iv:EA//oT1Cb5wNFigTDOz3nA80qD9UwTjK5cpUwLnEXjs=,tag:hMdIUaqLRA8zuFBd82bz6A==,type:str]
...envs/default/values/backend.yaml.gotmpl
elasticsearch:
host: elasticsearch
port: 9200
passwort: {{ .Values | getOrNil "secrets.elastic.password" | default "password" }}envs/devel/values/backend.yaml
elasticsearch:
host: elastic-0.devel.domainenvs/production/values/backend.yaml
elasticsearch:
host: elastic-0.production.domainHinweis
Ăbrigens, getOrNil â eine spezielle Funktion fĂŒr Go-Templates in Helmfile, die, selbst wenn .Values.secrets nicht existiert, keinen Fehler ausgibt, sondern es ermöglicht, mit einer Funktion default einen Standardwert einzufĂŒgen.
Fazit
Die beschriebenen Punkte erscheinen recht offensichtlich, jedoch gibt es nur wenig Informationen ĂŒber eine komfortable Beschreibung von Deployments in mehreren Umgebungen mit Helmfile. Ich schĂ€tze IaC (Infrastructure-as-Code) und möchte eine klare Beschreibung des Deployment-Status haben.
AbschlieĂend möchte ich hinzufĂŒgen, dass die Variablen fĂŒr die Standardumgebung wiederum durch Umgebungsvariablen des Betriebssystems eines bestimmten Runners, von dem das Deployment gestartet wird, parametrisiert werden können, wodurch dynamische Umgebungen entstehen.
helmfile.yaml
environments:
default:
values:
- global:
clusterDomain: {{ env "CLUSTER_DOMAIN" | default "cluster.local" }}
ingressDomain: {{ env "INGRESS_DOMAIN" }}Quelle: habr.com
