Možete pročitati o samom helmfileu i primjerima njegove upotrebe
Upoznat ćemo se s neočiglednim načinima opisivanja izdanja u helmfileu
Recimo da imamo paket helm grafikona (na primjer, recimo postgres i neku pozadinsku aplikaciju) i nekoliko okruženja (nekoliko kubernetes klastera, nekoliko imenskih prostora ili nekoliko od oboje). Uzimamo helmfile, čitamo dokumentaciju i počinjemo opisivati naša okruženja 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 sa 2 okruženja: razviti, proizvodnja — svaki sadrži svoje vrijednosti za karte izdanja kormila. Mi ćemo im rasporediti ovako:
helmfile -n <namespace> -e <env> apply
Različite verzije karata kormila u različitim okruženjima
Što ako trebamo uvesti različite verzije pozadine u različitim okruženjima? Kako parametrirati verziju izdanja? Ekološke vrijednosti dostupne kroz {{ .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 skup aplikacija u različitim okruženjima
Odlično, ali šta ako ne trebamo production
izbaciti postgres, jer znamo da ne trebamo gurati bazu podataka u k8s i za prodaju imamo divan odvojeni 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 lično više volim da opisujem koje aplikacije treba implementirati u okruženju ne koristeći argumente za pokretanje, već u opisu samih okruženja. sta da radim? Možete smjestiti opise izdanja u zasebnu mapu, kreirati listu potrebnih izdanja u opisu okruženja i "pokupiti" samo potrebna izdanja, ignorirajući ostalo
.
├── 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
Napomena
Kada koristite bases:
potrebno je koristiti yaml separator ---
, tako da možete šablonizirati izdanja (i druge dijelove, kao što je helmDefaults) s vrijednostima iz okruženja
U ovom slučaju, postgres izdanje neće biti ni uključeno u opis proizvodnje. Veoma udobno!
Zaobilazne globalne vrijednosti za izdanja
Naravno, sjajno je što možete postaviti vrijednosti za upravljačke karte za svako okruženje, ali šta ako imamo više opisanih okruženja, a želimo, na primjer, postaviti iste za sve affinity
, ali ne želimo da ga konfiguriramo prema zadanim postavkama u samim grafikonima, koji su pohranjeni u repi.
U ovom slučaju, za svako izdanje možemo navesti 2 datoteke sa vrijednostima: prvi sa zadanim vrijednostima, koji će odrediti vrijednosti samog grafikona, a drugi sa vrijednostima za okruženje, što ć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 nivou 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 domen je isti, pa zašto ga ne staviti u neku globalnu varijablu i jednostavno zamijeniti njegovu vrijednost u grafikone? Da biste to učinili, datoteke sa vrijednostima koje želimo parametrizirati morat će imati ekstenziju .gotmpl
, tako da taj helmfile zna da ga treba pokrenuti kroz mehanizam za predloške.
.
├── 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 }}
Napomena
Očigledno je da je ingress u postgres grafikonu nešto krajnje sumnjivo, 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 vrijednostima okruženja
Po analogiji s gornjim primjerom, možete zamijeniti šifrirane koristeći
.
├── 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
Napomena
Inače, getOrNil
- posebna funkcija za go predloške u helmfileu, koja, čak i ako .Values.secrets
neće postojati, neće izbaciti grešku, ali će dozvoliti rezultat pomoću funkcije default
zamjenska zadana vrijednost
zaključak
Opisane stvari izgledaju prilično očigledne, ali informacije o prikladnom opisu implementacije u nekoliko okruženja koristeći helmfile su vrlo oskudne, a ja volim IaC (Infrastructure-as-Code) i želim imati jasan opis stanja implementacije.
U zaključku, želio bih da dodam da se varijable za zadano okruženje mogu, zauzvrat, parametrizovati sa varijablama okruženja OS-a određenog trkača iz kojeg će se pokrenuti implementacija i na taj način 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