Du kan lÀsa om sjÀlva helmfile och exempel pÄ dess anvÀndning i
Vi kommer att bekanta oss med icke-uppenbara sÀtt att beskriva releaser i helmfile
LÄt oss sÀga att vi har ett paket med styrdiagram (till exempel, lÄt oss sÀga postgres och nÄgon backend-applikation) och flera miljöer (flera kubernetes-kluster, flera namnomrÄden eller flera av bÄda). Vi tar rodret, lÀser dokumentationen och börjar beskriva vÄra miljöer och releaser:
.
âââ 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
Vi slutade med 2 miljöer: devel, produktion â var och en innehĂ„ller sina egna vĂ€rden för rodrets utlösningsdiagram. Vi kommer att distribuera till dem sĂ„ hĂ€r:
helmfile -n <namespace> -e <env> apply
Olika versioner av styrdiagram i olika miljöer
Vad hÀnder om vi behöver rulla ut olika versioner av backend till olika miljöer? Hur parametriserar man releaseversionen? De miljövÀrden som finns tillgÀngliga genom {{ .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 }}
...
Olika applikationer i olika miljöer
Bra, men tÀnk om vi inte behöver production
rulla ut postgres, eftersom vi vet att vi inte behöver skjuta in databasen i k8s och att vi har ett underbart separat postgres-kluster till salu? För att lösa detta problem har vi etiketter
helmfile -n <namespace> -e devel apply
helmfile -n <namespace> -e production -l app=backend apply
Detta Àr bra, men personligen föredrar jag att beskriva vilka applikationer som ska distribueras i miljön, inte med hjÀlp av startargument, utan i beskrivningen av sjÀlva miljöerna. Vad ska man göra? Du kan placera utgivningsbeskrivningarna i en separat mapp, skapa en lista över nödvÀndiga utgÄvor i miljöbeskrivningen och "plocka upp" endast de nödvÀndiga utgÄvorna, ignorera resten
.
âââ 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
Anteckningen
NÀr du anvÀnder bases:
det Àr nödvÀndigt att anvÀnda yaml separator ---
, sÄ att du kan mallslÀpp (och andra delar, sÄsom helmDefaults) med vÀrden frÄn miljöer
I det hÀr fallet kommer postgres-releasen inte ens att ingÄ i beskrivningen för produktion. Mycket bekvÀmt!
à sidosÀttbara globala vÀrden för releaser
Naturligtvis Àr det bra att du kan stÀlla in vÀrden för styrdiagram för varje miljö, men tÀnk om vi har flera miljöer beskrivna, och vi vill till exempel stÀlla samma för alla affinity
, men vi vill inte konfigurera det som standard i sjÀlva diagrammen, som lagras i rovor.
I det hÀr fallet kan vi för varje utgÄva specificera 2 filer med vÀrden: den första med standardvÀrden, som kommer att bestÀmma vÀrdena för sjÀlva diagrammet, och den andra med vÀrden för miljön, som i sin tur kommer att ÄsidosÀtta standard.
.
âââ 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"
Definierar globala vÀrden för styrdiagram över alla utgÄvor pÄ miljönivÄ
LÄt oss sÀga att vi skapar flera ingÄngar i flera utgÄvor - vi skulle kunna definiera manuellt för varje diagram hosts:
, men i vÄrt fall Àr domÀnen densamma, sÄ varför inte lÀgga den i nÄgon global variabel och helt enkelt ersÀtta dess vÀrde i diagrammen? För att göra detta mÄste de filer med vÀrden som vi vill parametrisera ha tillÀgget .gotmpl
, sÄ att helmfile vet att den mÄste köras genom mallmotorn.
.
âââ 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 }}
Anteckningen
Uppenbarligen Àr ingress i postgres-diagrammet nÄgot extremt tveksamt, sÄ den hÀr artikeln ges helt enkelt som ett sfÀriskt exempel i ett vakuum och för att inte introducera nÄgon ny version i artikeln bara för att beskriva ingressen
ErsÀtter hemligheter frÄn miljövÀrden
I analogi med exemplet ovan kan du ersÀtta krypterade med hjÀlp av
.
âââ 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
Anteckningen
Förresten, getOrNil
- en speciell funktion för go-mallar i helmfile, som Àven om .Values.secrets
kommer inte att existera, kommer inte att ge ett fel, men kommer att tillÄta resultatet med funktionen default
ersÀtt standardvÀrde
Slutsats
De saker som beskrivs verkar ganska sjÀlvklara, men information om en bekvÀm beskrivning av utplacering till flera miljöer med hjÀlp av helmfile Àr mycket knapphÀndig, och jag Àlskar IaC (Infrastructure-as-Code) och vill ha en tydlig beskrivning av driftsÀttningstillstÄndet.
Avslutningsvis skulle jag vilja tillÀgga att variablerna för standardmiljön i sin tur kan parametriseras med miljövariablerna för operativsystemet för en viss löpare frÄn vilken distributionen kommer att startas, och pÄ sÄ sÀtt erhÄlla dynamiska miljöer
helmfile.yaml
environments:
default:
values:
- global:
clusterDomain: {{ env "CLUSTER_DOMAIN" | default "cluster.local" }}
ingressDomain: {{ env "INGRESS_DOMAIN" }}
KĂ€lla: will.com