Magáról a helmfile-ről és a felhasználási példákról olvashat
Megismerjük a kiadások leírásának nem nyilvánvaló módjait a helmfile-ban
Tegyük fel, hogy van egy csomag sisakdiagramunk (például postgres és néhány háttéralkalmazás) és több környezetünk (több kubernetes-fürt, több névtér vagy mindkettő). Fogjuk a helmfile-t, elolvassuk a dokumentációt, és elkezdjük leírni környezetünket és kiadásainkat:
.
├── 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
2 környezethez jutottunk: fejlõdni, Termelés — mindegyik saját értéket tartalmaz a kormánykioldási táblázatokhoz. Így fogjuk bevezetni őket:
helmfile -n <namespace> -e <env> apply
A kormánydiagramok különböző változatai különböző környezetekben
Mi a teendő, ha a háttérrendszer különböző verzióit kell kivezetnünk különböző környezetekben? Hogyan lehet paraméterezni a kiadási verziót? keresztül elérhető környezeti értékek {{ .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 }}
...
Különböző alkalmazások különböző környezetekben
Remek, de mi van, ha nem kell production
roll out postgres, mert tudjuk, hogy nem kell az adatbázist k8s-ba tolni, és eladó egy csodálatos külön postgres klaszterünk? A probléma megoldására címkéink vannak
helmfile -n <namespace> -e devel apply
helmfile -n <namespace> -e production -l app=backend apply
Ez nagyszerű, de én személy szerint jobban szeretem leírni, hogy mely alkalmazásokat kell telepíteni a környezetben, nem indítási argumentumokkal, hanem maguknak a környezeteknek a leírásában. Mit kell tenni? A kiadásleírásokat külön mappába helyezheti, a környezetleírásban listát készíthet a szükséges kiadásokról, és csak a szükséges kiadásokat „veheti fel”, a többit figyelmen kívül hagyva.
.
├── 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
A jegyzet
Ha a bases:
yaml elválasztó használata szükséges ---
, így a kiadásokat (és más részeket, például a helmDefaults-ot) környezeti értékekkel sablonozhatja
Ebben az esetben a postgres kiadás nem is fog szerepelni a gyártás leírásában. Nagyon kényelmesen!
Felülírható globális értékek a kiadásokhoz
Természetesen nagyszerű, hogy minden környezethez beállíthat értékeket a sisakdiagramokhoz, de mi van akkor, ha több környezetet is leírtunk, és például ugyanazt szeretnénk beállítani affinity
, de nem akarjuk alapértelmezés szerint beállítani magukban a grafikonokban, amelyek a fehérrépában vannak tárolva.
Ebben az esetben minden kiadáshoz 2 fájlt adhatunk meg értékekkel: az első alapértelmezett értékekkel, amely magának a diagramnak az értékeit határozza meg, a második pedig a környezet értékeit, ami viszont felülírja a alapértelmezettek.
.
├── 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"
Globális értékek meghatározása az összes kiadás vezérlődiagramjaihoz környezeti szinten
Tegyük fel, hogy több bemenetet hozunk létre több kiadásban – manuálisan definiálhatnánk minden diagramhoz hosts:
, de a mi esetünkben a tartomány ugyanaz, akkor miért nem helyezzük be valamilyen globális változóba, és egyszerűen behelyettesítjük az értékét a diagramokba? Ehhez a paraméterezni kívánt értékekkel rendelkező fájloknak rendelkezniük kell a kiterjesztéssel .gotmpl
, hogy a helmfile tudja, hogy a sablonmotoron keresztül kell futtatni.
.
├── 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 }}
A jegyzet
Nyilvánvaló, hogy a postgres diagramban az ingress egy rendkívül kétes dolog, ezért ezt a cikket egyszerűen gömbölyű példaként adjuk egy légüres térben, és azért, hogy ne csak az ingress leírása miatt kerüljön be a cikkbe valami új kiadás.
A titkok helyettesítése környezeti értékekkel
A fenti példával analóg módon a titkosítottakat helyettesítheti a következővel
.
├── 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
A jegyzet
By the way, getOrNil
- egy speciális funkció a go sablonokhoz a helmfile-ban, amely még akkor is, ha .Values.secrets
nem létezik, nem dob hibát, de engedélyezi az eredményt a függvény segítségével default
helyettesítő alapértelmezett érték
Következtetés
A leírt dolgok elég nyilvánvalónak tűnnek, de a helmfile-t használó több környezetben történő telepítés kényelmes leírásáról nagyon kevés információ áll rendelkezésre, és szeretem az IaC-t (Infrastructure-as-Code), és szeretnék világos leírást kapni a telepítési állapotról.
Végezetül szeretném hozzátenni, hogy az alapértelmezett környezet változói viszont paraméterezhetők egy adott futtató operációs rendszerének környezeti változóival, amelyről a telepítés elindul, és így dinamikus környezeteket kaphatunk.
helmfile.yaml
environments:
default:
values:
- global:
clusterDomain: {{ env "CLUSTER_DOMAIN" | default "cluster.local" }}
ingressDomain: {{ env "INGRESS_DOMAIN" }}
Forrás: will.com