O sami datoteki helmfile in primerih njene uporabe lahko preberete v
Seznanili se bomo z neočitnimi načini opisovanja izdaj v datoteki helmfile
Recimo, da imamo paket krmilnih grafikonov (na primer postgres in nekaj zaledne aplikacije) in več okolij (več gruč kubernetes, več imenskih prostorov ali več obojega). Vzamemo datoteko helm, preberemo dokumentacijo in začnemo opisovati naša okolja in izdaje:
.
├── 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
Na koncu smo imeli 2 okolji: razviti, proizvodnja — vsaka vsebuje svoje vrednosti za tabele sprostitve krmila. Namestili jih bomo takole:
helmfile -n <namespace> -e <env> apply
Različne različice krmilnih kart v različnih okoljih
Kaj pa, če moramo uvesti različne različice ozadja v različna okolja? Kako parametrirati različico izdaje? Okoljske vrednosti, ki so na voljo prek {{ .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čen nabor aplikacij v različnih okoljih
Super, a kaj, ko nam ni treba production
uvesti postgres, ker vemo, da nam baze podatkov ni treba potisniti v k8s in da imamo za prodajo čudovito ločeno gručo postgres? Za rešitev te težave imamo na voljo oznake
helmfile -n <namespace> -e devel apply
helmfile -n <namespace> -e production -l app=backend apply
To je super, vendar osebno raje opišem, katere aplikacije namestiti v okolju, ne z uporabo argumentov za zagon, ampak v opisu samih okolij. Kaj storiti? Opise izdaj lahko postavite v ločeno mapo, v opisu okolja ustvarite seznam potrebnih izdaj in »poberete« samo potrebne izpuste, ostale pa zanemarite.
.
├── 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
Opomba
Pri uporabi bases:
potrebno je uporabiti yaml separator ---
, tako da lahko oblikujete predloge za izdaje (in druge dele, kot je helmDefaults) z vrednostmi iz okolij
V tem primeru izdaja postgres sploh ne bo vključena v opis za proizvodnjo. Zelo udobno!
Preglasljive globalne vrednosti za izdaje
Seveda je super, da lahko nastavite vrednosti za krmilne karte za vsako okolje, a kaj ko imamo opisanih več okolij in želimo na primer za vsa nastaviti enako affinity
, vendar ga ne želimo privzeto konfigurirati v samih grafikonih, ki so shranjeni v repi.
V tem primeru bi lahko za vsako izdajo določili 2 datoteki z vrednostmi: prvo s privzetimi vrednostmi, ki bodo določile vrednosti samega grafikona, in drugo z vrednostmi za okolje, ki bodo preglasile privzete.
.
├── 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"
Določitev globalnih vrednosti za krmilne karte vseh izdaj na ravni okolja
Recimo, da ustvarimo več vhodov v več izdajah - lahko ročno določimo za vsak grafikon hosts:
, toda v našem primeru je domena enaka, zakaj je torej ne bi dali v neko globalno spremenljivko in njene vrednosti preprosto nadomestili v grafikone? Da bi to naredili, morajo imeti tiste datoteke z vrednostmi, ki jih želimo parametrizirati, končnico .gotmpl
, tako da datoteka helmfile ve, da jo je treba zagnati prek mehanizma predloge.
.
├── 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 }}
Opomba
Očitno je vstopanje v postgres grafikon nekaj zelo dvomljivega, zato je ta članek podan zgolj kot sferični primer v vakuumu in zato, da ne bi v članek vnesli kakšne nove izdaje samo zaradi opisa vstopanja
Nadomeščanje skrivnosti iz vrednot okolja
Po analogiji z zgornjim primerom lahko šifrirane nadomestite z uporabo
.
├── 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
Opomba
Mimogrede, getOrNil
- posebna funkcija za predloge go v helmfile, ki, tudi če .Values.secrets
ne bo obstajal, ne bo povzročil napake, vendar bo dovolil rezultat z uporabo funkcije default
nadomestna privzeta vrednost
Zaključek
Opisane stvari se zdijo povsem očitne, vendar so informacije o priročnem opisu uvajanja v več okoljih z uporabo datoteke helmfile zelo redke in obožujem IaC (Infrastructure-as-Code) in želim imeti jasen opis stanja uvajanja.
Na koncu bi rad dodal, da lahko spremenljivke za privzeto okolje parametriramo s spremenljivkami okolja OS določenega tekača, iz katerega se bo zagnala uvedba, in tako pridobimo dinamična okolja
helmfile.yaml
environments:
default:
values:
- global:
clusterDomain: {{ env "CLUSTER_DOMAIN" | default "cluster.local" }}
ingressDomain: {{ env "INGRESS_DOMAIN" }}
Vir: www.habr.com