O samom helmfileu i primjerima njegovog korištenja možete pročitati u
Upoznat ćemo se s neočitim načinima opisivanja izdanja u helmfileu
Recimo da imamo paket kormilarskih dijagrama (na primjer, recimo postgres i neku pozadinsku aplikaciju) i nekoliko okruženja (nekoliko kubernetes klastera, nekoliko prostora imena ili nekoliko oboje). Uzimamo helmfile, čitamo dokumentaciju i počinjemo opisivati naše okruženje i izdanja:
.
├── 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
Završili smo s 2 okruženja: razviti, proizvodnja — svaki sadrži vlastite vrijednosti za tablice otpuštanja kormila. Rasporedit ćemo ih ovako:
helmfile -n <namespace> -e <env> apply
Različite verzije kormilarskih karata u različitim okruženjima
Što ako trebamo uvesti različite verzije pozadine u različita okruženja? Kako parametrirati verziju izdanja? Ekološke vrijednosti dostupne putem {{ .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 }}
...
Različiti skupovi aplikacija u različitim okruženjima
Super, ali što ako nam ne treba production
uvesti postgres, jer znamo da ne trebamo gurati bazu podataka u k8s, a za prodaju imamo prekrasan odvojen postgres klaster? Za rješavanje ovog problema imamo oznake
helmfile -n <namespace> -e devel apply
helmfile -n <namespace> -e production -l app=backend apply
Ovo je sjajno, ali osobno radije opisujem koje aplikacije implementirati u okruženju ne koristeći argumente pokretanja, već u opisu samih okruženja. Što uraditi? Možete smjestiti opise izdanja u zasebnu mapu, izraditi popis potrebnih izdanja u opisu okruženja i “pokupiti” samo potrebna izdanja, zanemarujući ostala
.
├── 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
Bilješka
Kada koristite bases:
potrebno je koristiti yaml separator ---
, tako da možete izraditi predložak izdanja (i drugih dijelova, kao što je helmDefaults) s vrijednostima iz okruženja
U ovom slučaju, postgres izdanje neće biti ni uključeno u opis za proizvodnju. Vrlo udobno!
Globalne vrijednosti koje se mogu nadjačati za izdanja
Naravno, odlično je što možete postaviti vrijednosti za karte kormila za svako okruženje, ali što ako imamo nekoliko opisanih okruženja, a želimo, na primjer, postaviti isto za sve affinity
, ali ne želimo ga konfigurirati prema zadanim postavkama u samim grafikonima, koji su pohranjeni u repi.
U ovom slučaju, za svako izdanje mogli bismo navesti 2 datoteke s vrijednostima: prvu sa zadanim vrijednostima, koje će odrediti vrijednosti samog grafikona, a drugu s vrijednostima za okruženje, koje će zauzvrat nadjačati zadane.
.
├── 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"
Definiranje globalnih vrijednosti za upravljačke karte svih izdanja na razini okruženja
Recimo da kreiramo nekoliko ulaza u nekoliko izdanja - mogli bismo ručno definirati za svaki grafikon hosts:
, ali u našem slučaju domena je ista, pa zašto je ne staviti u neku globalnu varijablu i jednostavno zamijeniti njezinu vrijednost u grafikone? Da bismo to učinili, te datoteke s vrijednostima koje želimo parametrizirati morat će imati ekstenziju .gotmpl
, tako da helmfile zna da se mora pokrenuti kroz predložak.
.
├── 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 }}
Bilješka
Očito je ingress u postgres grafikonu nešto krajnje dvojbeno, pa je ovaj članak dat jednostavno kao sferni primjer u vakuumu i kako se ne bi uvodilo neko novo izdanje u članak samo radi opisa ingressa
Zamjena tajni iz vrijednosti okoline
Po analogiji s gornjim primjerom, šifrirane možete zamijeniti pomoću
.
├── 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
Bilješka
Usput, getOrNil
- posebna funkcija za go predloške u helmfileu, koja, čak i ako .Values.secrets
neće postojati, neće izbaciti pogrešku, ali će dopustiti rezultat pomoću funkcije default
zamjenska zadana vrijednost
Zaključak
Opisano se čini sasvim očiglednim, ali informacije o prikladnom opisu implementacije u nekoliko okruženja pomoću helmfilea su vrlo rijetke, a ja volim IaC (Infrastructure-as-Code) i želim imati jasan opis stanja implementacije.
Zaključno bih želio dodati da se varijable za zadano okruženje mogu pak parametrizirati s varijablama okruženja OS-a određenog runnera iz kojeg će se pokrenuti implementacija i tako dobiti dinamička okruženja
helmfile.yaml
environments:
default:
values:
- global:
clusterDomain: {{ env "CLUSTER_DOMAIN" | default "cluster.local" }}
ingressDomain: {{ env "INGRESS_DOMAIN" }}
Izvor: www.habr.com