â et wrapper til , som gør det muligt at beskrive mange helm releases pĂĽ ĂŠt sted, parametrisere deres charts til flere miljøer og ogsĂĽ angive rĂŚkken for deres deployment.
Om helmfile og eksempler pĂĽ dets brug kan lĂŚses i og .
Vi vil møde nogle uventede müder at beskrive releases i helmfile pü
Lad os sige, at vi har en rÌkke helm charts (for eksempel postgres og en backend applikation) og flere miljøer (flere Kubernetes klynger, flere namespaces eller en kombination af begge). Vi tager helmfile, lÌser dokumentationen og begynder at beskrive vores miljøer og releases:
.
âââ 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.yamlVi har fĂĽet 2 miljøer: devel, production â i hver af dem er der sine vĂŚrdier for helm charts af releases. Vi vil deploye i dem sĂĽdan her:
helmfile -n -e applyForskellige versioner af helm charts i forskellige miljøer
Hvad skal vi gøre, hvis vi skal rulle forskellige versioner af backend ud i forskellige miljøer? Hvordan kan vi parameterisere versionen af et release? Her kommer miljøvÌrdierne ind, der er tilgÌngelige via {{ .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 }}
...Forskellige sÌt af applikationer i forskellige miljøer
Godt, men hvad hvis vi ikke har brug for at production rulle postgres ud, fordi vi ved, at vi ikke skal have databasen i k8s, og til produktion har vi en fantastisk separat postgres klynge? For at løse dette problem har vi labels
helmfile -n -e devel apply
helmfile -n -e production -l app=backend applyDet er fantastisk, men personligt foretrÌkker jeg at beskrive, hvilke applikationer der skal implementeres i miljøet, ikke ved hjÌlp af opstartargumenter, men i selve miljøbeskrivelserne. Hvad gør man? Man kan placere versionbeskrivelserne i en separat mappe, oprette en liste over nødvendige versioner i miljøbeskrivelsen og "tilknytte" kun de nødvendige versioner og ignorere de øvrige.
.
âââ envs
â  âââ devel
â  â  âââ values
â  â  âââ backend.yaml
â  â  âââ postgres.yaml
â  âââ production
â  âââ values
â  âââ backend.yaml
â  âââ postgres.yaml
+ âââ releases
+ â  âââ backend.yaml
+ â  âââ postgres.yaml
âââ helmfile.yaml
helmfile.yaml
miljøer:
devel:
vĂŚrdier:
- charts:
versioner:
backend: 1.1.0
- apps:
- postgres
- backend
production:
vĂŚrdier:
- charts:
versioner:
backend: 1.0.5
- apps:
- backend
- releases:
- - navn: postgres
- labels:
- app: postgres
- vent: true
- chart: stable/postgresql
- version: 8.4.0
- vĂŚrdier:
- - envs/{{ .Environment.Name }}/values/postgres.yaml
- - navn: backend
- labels:
- app: backend
- vent: true
- chart: private-helm-repo/backend
- version: {{ .Values.charts.versions.backend }}
- behov:
- - postgres
- vĂŚrdier:
- - envs/{{ .Environment.Name }}/values/backend.yaml
+ ---
+ baser:
+ {{- range .Values.apps }}
+ - releases/{{ . }}.yaml
+ {{- end }}releases/postgres.yaml
releases:
- navn: postgres
labels:
app: postgres
vent: true
chart: stable/postgresql
version: 8.4.0
vĂŚrdier:
- envs/{{ .Environment.Name }}/values/postgres.yamlreleases/backend.yaml
releases:
- navn: backend
labels:
app: backend
vent: true
chart: private-helm-repo/backend
version: {{ .Values.charts.versions.backend }}
behov:
- postgres
vĂŚrdier:
- envs/{{ .Environment.Name }}/values/backend.yamlNote
Ved brug af baser: det er nødvendigt at bruge yaml-separator. ---, sü man kan anvende releases (og andre dele, süsom helmDefaults) med vÌrdier fra miljøerne.
I sĂĽ fald vil postgres-versionen ikke engang vĂŚre med i beskrivelsen for produktion. Meget praktisk!
Globale vĂŚrdier til overskrivning for versioner.
Det er selvfølgelig fantastisk, at man kan angive vÌrdier for helm charts for hvert miljø, men hvad hvis vi har beskrevet flere miljøer, og vi ønsker, for eksempel, at angive en vÌrdi, som skal vÌre den samme for alle. affinity, men ikke ønsker at indstille det som standard i selve charts, der er gemt i repoerne.
I sü fald kunne vi for hver version angive 2 filer med vÌrdier: en første med standardvÌrdierne, der vil bestemme chartets vÌrdier, og den anden med vÌrdierne for miljøet, som sü vil overskrive standarderne.
.
âââ 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"Definition of global values for helm charts of all releases at the environment level
Suppose we create several ingress in multiple releases â we could manually define this for each chart hosts:, but in our case the domain is the same, so why not pull it out into a global variable and just substitute its value into the charts? For this, the files with values that we want to parameterize should have the extension .gotmpl, so that helmfile knows to process them through the templater.
.
âââ 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
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 }}Note
Det er ĂĽbenlyst, at ingress i Postgres-chartet er noget ekstremt tvivlsomt, sĂĽ det nĂŚvnes i artiklen blot som et sfĂŚrisk eksempel i et vakuum og for at undgĂĽ at introducere en ny version kun for at beskrive ingress.
IndsÌttelse af hemmeligheder (secrets) fra miljøvariabler.
Pü samme müde som det ovenfor nÌvnte eksempel kan man indsÌtte vÌrdier, der er krypteret med . I stedet for at oprette en unik secrets-fil for hver version, hvor der bestemmes krypterede vÌrdier for chartet, kan vi blot definere vÌrdier i releases default.yaml.gotmpl, som vil blive hentet fra variabler angivet pü miljøniveau. Og vÌrdier, som vi ikke behøver at skjule fra nogen, kan vi trygt overskrive i release-vÌrdierne i det specifikke miljø.
.
âââ 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
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.domainenvs/production/values/backend.yaml
elasticsearch:
host: elastic-0.production.domainNote
Forresten, getOrNil â en speciel funktion til go-skabeloner i helmfile, som, selv hvis .Values.secrets ikke eksisterer, ikke kaster en fejl, men muliggør at bruge funktionen default til at indsĂŚtte en standardvĂŚrdi.
Konklusion
De beskrevne ting virker ret übenlyse, men informationen om praktisk beskrivelse af deployment i flere miljøer med helmfile er meget begrÌnset, og jeg elsker IaC (Infrastructure-as-Code) og ønsker en klar beskrivelse af deployment state.
Afslutningsvis vil jeg tilføje, at variablerne for standardmiljøet kan parametriseres med miljøvariablerne fra et givet runner, som deploymenten vil blive kørt fra, og dermed skabe dynamiske miljøer.
helmfile.yaml
environments:
default:
values:
- global:
clusterDomain: {{ env "CLUSTER_DOMAIN" | default "cluster.local" }}
ingressDomain: {{ env "INGRESS_DOMAIN" }}Kilde: habr.com
