β een wrapper voor , die het mogelijk maakt om op één plek meerdere helm-releases te beschrijven, hun charts te parameteriseren voor verschillende omgevingen en ook de volgorde van hun deployment vast te stellen.
Over helmfile zelf en voorbeelden van het gebruik ervan kun je lezen in de en .
We zullen kennismaken met minder voor de hand liggende manieren om releases in helmfile te beschrijven.
Stel dat we een reeks helm-charts hebben (bijvoorbeeld postgres en een backend-applicatie) en verschillende omgevingen (meerdere Kubernetes-clusters, meerdere namespaces of een combinatie van beiden). We pakken helmfile, lezen de documentatie en beginnen onze omgevingen en releases te beschrijven:
.
βββ envs
βΒ Β βββ devel
βΒ Β βΒ Β βββ values
βΒ Β βΒ Β βββ backend.yaml
βΒ Β βΒ Β βββ postgres.yaml
βΒ Β βββ production
βΒ Β βββ values
βΒ Β βββ backend.yaml
βΒ Β βββ postgres.yaml
βββ helmfile.yamlhelmfile.yaml
omgevingen:
devel:
production:
releases:
- naam: postgres
labels:
app: postgres
wait: true
chart: stable/postgresql
versie: 8.4.0
waarden:
- envs/{{ .Environment.Name }}/values/postgres.yaml
- naam: backend
labels:
app: backend
wait: true
chart: private-helm-repo/backend
versie: 1.0.5
behoeftes:
- postgres
waarden:
- envs/{{ .Environment.Name }}/values/backend.yamlWe hebben 2 omgevingen gekregen: devel, production β in elke omgeving bevinden zich eigen waarden voor de helm-charts van de releases. We zullen ze als volgt deployen:
helmfile -n -e applyVerschillende versies van helm-charts in verschillende omgevingen
Wat te doen als we verschillende versies van de backend in verschillende omgevingen moeten uitrollen? Hoe de versie van de release parameteriseren? De omgevingswaarden, toegankelijk via {{ .Values }}
helmfile.yaml
omgevingen:
devel:
+ waarden:
+ - charts:
+ versies:
+ backend: 1.1.0
production:
+ waarden:
+ - charts:
+ versies:
+ backend: 1.0.5
...
- naam: backend
labels:
app: backend
wait: true
chart: private-helm-repo/backend
- versie: 1.0.5
+ versie: {{ .Values.charts.versies.backend }}
...Verschillende sets applicaties in verschillende omgevingen
Prima, maar wat als we geen production postgres hoeven uit te rollen, omdat we weten dat we geen database in k8s moeten stoppen en we voor de productie een geweldige aparte postgres-cluster hebben? Voor dit probleem hebben we labels (labels).
helmfile -n -e devel apply
helmfile -n -e production -l app=backend applyDat is geweldig, maar persoonlijk geef ik er de voorkeur aan om te beschrijven welke applicaties in een omgeving moeten worden uitgerold, niet met startup-argumenten, maar in de beschrijvingen van de omgevingen zelf. Wat te doen? We kunnen de releasebeschrijvingen in een aparte map plaatsen, in de omschrijving van de omgeving een lijst maken met de benodigde releases en alleen de benodigde releases 'aanhaken', waarbij de anderen worden genegeerd.
.
βββ envs
β βββ devel
β β βββ values
β β βββ backend.yaml
β β βββ postgres.yaml
β βββ production
β βββ values
β βββ backend.yaml
β βββ postgres.yaml
+ βββ releases
+ β βββ backend.yaml
+ β βββ postgres.yaml
βββ helmfile.yaml
helmfile.yaml
omgevingen:
devel:
waarden:
- charts:
versies:
backend: 1.1.0
- apps:
- postgres
- backend
productie:
waarden:
- charts:
versies:
backend: 1.0.5
- apps:
- backend
- releases:
- - naam: postgres
- labels:
- app: postgres
- wacht: true
- chart: stable/postgresql
- versie: 8.4.0
- waarden:
- - envs/{{ .Environment.Name }}/values/postgres.yaml
- - naam: backend
- labels:
- app: backend
- wacht: true
- chart: private-helm-repo/backend
- versie: {{ .Values.charts.versions.backend }}
- needs:
- - postgres
- waarden:
- - envs/{{ .Environment.Name }}/values/backend.yaml
+ ---
+ bases:
+ {{- range .Values.apps }}
+ - releases/{{ . }}.yaml
+ {{- end }}releases/postgres.yaml
releases:
- naam: postgres
labels:
app: postgres
wacht: true
chart: stable/postgresql
versie: 8.4.0
waarden:
- envs/{{ .Environment.Name }}/values/postgres.yamlreleases/backend.yaml
releases:
- naam: backend
labels:
app: backend
wacht: true
chart: private-helm-repo/backend
versie: {{ .Values.charts.versions.backend }}
needs:
- postgres
waarden:
- envs/{{ .Environment.Name }}/values/backend.yamlNotitie
Bij het gebruik van bases: het is noodzakelijk om de yaml-scheidingsteken te gebruiken ---, zodat we releases (en andere delen, zoals helmDefaults) kunnen sjabloniseren met waarden uit omgevingen
In dat geval zal de release postgres zelfs niet in de beschrijving voor productie verschijnen. Erg handig!
Globale waarden voor releases zijn overschrijfbaar
Het is natuurlijk geweldig dat we voor elke omgeving waarden voor helm-charts kunnen opgeven, maar wat als we meerdere omgevingen hebben beschreven en we bijvoorbeeld hetzelfde voor allemaal willen instellen affinity, maar het niet als standaard in de charts zelf willen configureren, die in de repositories worden opgeslagen.
In dat geval zouden we voor elke release 2 bestanden met waarden kunnen opgeven: de eerste met standaardwaarden die de waarden van de chart bepalen, en de tweede met omgevingswaarden die op hun beurt de standaardwaarden zullen overschrijven.
.
βββ 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"Globale waarden definiΓ«ren voor helm charts van alle releases op omgevingsniveau
Stel dat we in verschillende releases meerdere ingress maken β we zouden handmatig voor elke chart kunnen definiΓ«ren hosts:, maar in ons geval is het domein hetzelfde, waarom zouden we dat niet in een globale variabele kunnen onderbrengen en gewoon de waarde ervan in de charts kunnen gebruiken? De bestanden met waarden die we willen parameteriseren, moeten de extensie hebben .gotmpl, zodat helmfile weet dat ze door de sjabloondel moeten.
.
βββ 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
omgevingen:
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 }}Notitie
Het is duidelijk dat ingress in de Postgres-chart iets zeer twijfelachtig is, daarom wordt dit in het artikel simpelweg gegeven als een sferisch voorbeeld in een vacuΓΌm en om te voorkomen dat er een nieuwe release in het artikel wordt opgenomen alleen voor de beschrijving van ingress.
Vervanging van geheimen (secrets) vanuit omgevingswaarden.
Op dezelfde manier als het bovenstaande voorbeeld kunnen ook versleutelde waarden worden ingevoegd met behulp van. waarden. In plaats van voor elke release een apart secrets-bestand aan te maken, waarin de versleutelde waarden voor de chart worden gedefinieerd, kunnen we eenvoudig de waarden definiΓ«ren in de release default.yaml.gotmpl, die worden gehaald uit de variabelen die op omgevingsniveau zijn opgegeven. En de waarden die we niet verborgen hoeven te houden, kunnen we rustig overschrijven in de release-waarden in de specifieke omgeving.
.
βββ 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
omgevingen:
devel:
waarden:
- charts:
versies:
backend: 1.1.0
- apps:
- postgres
- backend
- global:
ingressDomain: k8s.devel.domain
+ secrets:
+ - envs/devel/secrets.yaml
productie:
waarden:
- charts:
versies:
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.domainenvs/production/values/backend.yaml
elasticsearch:
host: elastic-0.production.domainNotitie
Overigens, getOrNil β een speciale functie voor Go-templates in helmfile, die, zelfs als .Values.secrets niet bestaat, geen fout zal geven, maar in staat zal stellen om uiteindelijk met behulp van de functie default een standaardwaarde in te voegen.
Conclusie
De beschreven zaken lijken vrij voor de hand liggend, maar informatie over een handige beschrijving van een deployment in meerdere omgevingen met behulp van helmfile is beperkt, en ik hou van IaC (Infrastructure-as-Code) en wil een duidelijke beschrijving van de staat van de deployment hebben.
Tot slot wil ik toevoegen dat de variabelen voor de default omgeving kunnen worden geparameteriseerd met de omgevingsvariabelen van een bepaalde runner, van waaruit de deployment zal worden uitgevoerd, en zo dynamische omgevingen kunnen worden verkregen.
helmfile.yaml
omgevingen:
standaard:
waarden:
- globaal:
clusterDomein: {{ env "CLUSTER_DOMAIN" | default "cluster.local" }}
ingressDomein: {{ env "INGRESS_DOMAIN" }}Bron: habr.com
