Můžete si přečíst o samotném helmfile a příkladech jeho použití v
Seznámíme se s nesrozumitelnými způsoby popisu vydání v helmfile
Řekněme, že máme balíček grafů kormidla (například řekněme postgres a nějakou backendovou aplikaci) a několik prostředí (několik klastrů kubernetes, několik jmenných prostorů nebo několik obojího). Vezmeme soubor helmfile, přečteme si dokumentaci a začneme popisovat naše prostředí a verze:
.
├── 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
Skončili jsme se 2 prostředími: devel, výroba — každý obsahuje své vlastní hodnoty pro tabulky uvolnění kormidla. Nasadíme je takto:
helmfile -n <namespace> -e <env> apply
Různé verze tabulek kormidla v různých prostředích
Co když potřebujeme zavést různé verze backendu do různých prostředí? Jak parametrizovat verzi vydání? Environmentální hodnoty dostupné prostřednictvím {{ .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 }}
...
Různé sady aplikací v různých prostředích
Skvělé, ale co když to nepotřebujeme production
zavést postgres, protože víme, že nepotřebujeme tlačit databázi do k8 a na prodej máme úžasný samostatný postgres cluster? K vyřešení tohoto problému máme štítky
helmfile -n <namespace> -e devel apply
helmfile -n <namespace> -e production -l app=backend apply
To je skvělé, ale osobně raději popisuji, které aplikace nasadit do prostředí ne pomocí argumentů launch, ale v popisu prostředí samotných. Co dělat? Popisy vydání můžete umístit do samostatné složky, vytvořit seznam nezbytných vydání v popisu prostředí a „vyzvednout“ pouze nezbytná vydání, ostatní ignorovat
.
├── 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
Poznámka
Při použití bases:
je nutné použít oddělovač yaml ---
, takže můžete šablonovat vydání (a další části, jako je helmDefaults) s hodnotami z prostředí
V tomto případě nebude postgres release ani zahrnut do popisu pro výrobu. Velmi pohodlně!
Přepsatelné globální hodnoty pro vydání
Samozřejmě je skvělé, že můžete nastavit hodnoty pro grafy kormidel pro každé prostředí, ale co když máme popsáno několik prostředí a chceme například nastavit stejné pro všechna affinity
, ale nechceme jej konfigurovat standardně v samotných grafech, které jsou uloženy v tuřínech.
V tomto případě bychom pro každé vydání mohli zadat 2 soubory s hodnotami: první s výchozími hodnotami, které budou určovat hodnoty samotného grafu, a druhý s hodnotami pro prostředí, které zase přepíší výchozí.
.
├── 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"
Definování globálních hodnot pro grafy kormidla všech verzí na úrovni prostředí
Řekněme, že vytvoříme několik vstupů v několika verzích - mohli bychom ručně definovat pro každý graf hosts:
, ale v našem případě je doména stejná, tak proč ji nevložit do nějaké globální proměnné a její hodnotu jednoduše nedosadit do grafů? Chcete-li to provést, soubory s hodnotami, které chceme parametrizovat, budou muset mít příponu .gotmpl
, takže helmfile ví, že je třeba jej spustit přes šablonový engine.
.
├── 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 }}
Poznámka
Je zřejmé, že ingress v grafu postgres je něco extrémně pochybného, takže tento článek je uveden jednoduše jako sférický příklad ve vzduchoprázdnu a abychom do článku nezavedli nějaké nové vydání jen kvůli popisu vniknutí.
Nahrazení tajemství z hodnot prostředí
Analogicky s výše uvedeným příkladem můžete nahradit šifrované pomocí
.
├── 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
Poznámka
Mimochodem, getOrNil
- speciální funkce pro go šablony v helmfile, která, i když .Values.secrets
nebude existovat, nevyhodí chybu, ale umožní výsledek pomocí funkce default
nahradit výchozí hodnotu
Závěr
Popsané věci se zdají být zcela zřejmé, ale informací o pohodlném popisu nasazení do několika prostředí pomocí helmfile je velmi vzácné a miluji IaC (Infrastructure-as-Code) a chci mít jasný popis stavu nasazení.
Na závěr bych rád dodal, že proměnné pro výchozí prostředí lze naopak parametrizovat s proměnnými prostředí OS určitého běžce, ze kterého bude nasazení spouštěno, a získat tak dynamická prostředí
helmfile.yaml
environments:
default:
values:
- global:
clusterDomain: {{ env "CLUSTER_DOMAIN" | default "cluster.local" }}
ingressDomain: {{ env "INGRESS_DOMAIN" }}
Zdroj: www.habr.com