Podeu llegir sobre el mateix helmfile i exemples del seu ús a
Ens familiaritzarem amb maneres no òbvies de descriure els llançaments a helmfile
Suposem que tenim un paquet de gràfics de timó (per exemple, diguem postgres i alguna aplicació de fons) i diversos entorns (diversos clústers de Kubernetes, diversos espais de noms o diversos d'ambdós). Agafem el fitxer helm, llegim la documentació i comencem a descriure els nostres entorns i versions:
.
├── 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
Vam acabar amb 2 ambients: desenvolupar, producció — cadascun conté els seus propis valors per als gràfics de llançament del timó. Els distribuirem així:
helmfile -n <namespace> -e <env> apply
Diferents versions de gràfics de timó en diferents entorns
Què passa si hem de desplegar diferents versions del backend a diferents entorns? Com parametritzar la versió de llançament? Els valors ambientals disponibles a través {{ .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 }}
...
Diferent conjunt d'aplicacions en diferents entorns
Genial, però què passa si no ens cal production
llançar postgres, perquè sabem que no necessitem empènyer la base de dades a k8s i que tenim a la venda un meravellós clúster de postgres separat? Per resoldre aquest problema disposem d'etiquetes
helmfile -n <namespace> -e devel apply
helmfile -n <namespace> -e production -l app=backend apply
Això és genial, però personalment prefereixo descriure quines aplicacions implementar a l'entorn no utilitzant arguments de llançament, sinó en la descripció dels propis entorns. Què fer? Podeu col·locar les descripcions de les versions en una carpeta separada, crear una llista de les versions necessàries a la descripció de l'entorn i "recollir" només les versions necessàries, ignorant la resta
.
├── 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
La nota
Quan s'utilitza el bases:
cal utilitzar el separador yaml ---
, perquè pugueu modelar llançaments (i altres parts, com ara helmDefaults) amb valors dels entorns
En aquest cas, la versió de postgres ni tan sols s'inclourà a la descripció per a la producció. Molt còmodament!
Valors globals anul·lables per a versions
Per descomptat, és fantàstic que pugueu establir valors per als gràfics de timó per a cada entorn, però què passa si tenim diversos entorns descrits i volem, per exemple, establir el mateix per a tots? affinity
, però no volem configurar-lo per defecte als mateixos gràfics, que s'emmagatzemen en naps.
En aquest cas, per a cada llançament podríem especificar 2 fitxers amb valors: el primer amb valors per defecte, que determinarà els valors del propi gràfic, i el segon amb valors per a l'entorn, que al seu torn anul·larà el els predeterminats.
.
├── 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"
Definició de valors globals per als gràfics de timó de tots els llançaments a nivell ambiental
Suposem que creem diverses entrades en diverses versions; podríem definir manualment per a cada gràfic hosts:
, però en el nostre cas el domini és el mateix, per què no posar-lo en alguna variable global i simplement substituir el seu valor als gràfics? Per fer-ho, aquells fitxers amb valors que volem parametritzar hauran de tenir l'extensió .gotmpl
, de manera que helmfile sàpiga que s'ha d'executar a través del motor de plantilles.
.
├── 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 }}
La nota
Òbviament, l'entrada al gràfic de postgres és una cosa extremadament dubtosa, de manera que aquest article es dóna simplement com a exemple esfèric al buit i per no introduir cap nou llançament a l'article només per descriure l'entrada.
Substituint els secrets dels valors ambientals
Per analogia amb l'exemple anterior, podeu substituir els xifrats utilitzant
.
├── 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
La nota
Per cert, getOrNil
- una funció especial per a les plantilles de go a helmfile, que, encara que .Values.secrets
no existirà, no generarà un error, però permetrà el resultat utilitzant la funció default
substituir el valor predeterminat
Conclusió
Les coses descrites semblen força òbvies, però la informació sobre una descripció convenient del desplegament a diversos entorns que utilitzen helmfile és molt escassa, i m'encanta IaC (Infrastructure-as-Code) i vull tenir una descripció clara de l'estat de desplegament.
En conclusió, m'agradaria afegir que les variables de l'entorn predeterminat es poden, al seu torn, parametritzar amb les variables d'entorn del sistema operatiu d'un determinat corredor des del qual es llançarà el desplegament, i així obtenir entorns dinàmics.
helmfile.yaml
environments:
default:
values:
- global:
clusterDomain: {{ env "CLUSTER_DOMAIN" | default "cluster.local" }}
ingressDomain: {{ env "INGRESS_DOMAIN" }}
Font: www.habr.com