â un wrapper pour , qui permet de dĂ©crire plusieurs releases helm Ă un seul endroit, de paramĂ©trer leurs charts pour diffĂ©rents environnements, et de spĂ©cifier l'ordre de leur dĂ©ploiement.
Pour en savoir plus sur helmfile et des exemples d'utilisation, vous pouvez consulter le et .
Nous allons explorer des méthodes peu évidentes pour décrire les releases dans helmfile.
Supposons que nous avons un ensemble de charts helm (pour l'exemple, prenons postgres et une application backend) et plusieurs environnements (plusieurs clusters kubernetes, plusieurs namespaces ou un mélange des deux). Nous prenons helmfile, lisons la documentation et commençons à décrire nos environnements et releases :
.
âââ envs
â âââ devel
â â âââ values
â â âââ backend.yaml
â â âââ postgres.yaml
â âââ production
â âââ values
â âââ backend.yaml
â âââ postgres.yaml
âââ helmfile.yamlhelmfile.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.yamlNous avons créé 2 environnements : devel, production â chacun possĂšde ses propres valeurs pour les charts helm des releases. Nous allons les dĂ©ployer ainsi :
helmfile -n -e applyDifférentes versions des charts helm dans différents environnements
Que faire si nous devons déployer différentes versions du backend dans différents environnements ? Comment paramétrer la version de la release ? Les valeurs d'environnement accessibles via {{ .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 }}
...Un ensemble d'applications différent dans différents environnements
Excellent, mais que se passe-t-il si nous ne voulons pas production déployer postgres, parce que nous savons qu'il n'est pas nécessaire d'inclure une base de données dans k8s et que pour la production, nous avons un superbe cluster postgres séparé ? Pour résoudre ce problÚme, nous avons des labels
helmfile -n -e devel apply
helmfile -n -e production -l app=backend applyC'est super, mais personnellement, je prĂ©fĂšre dĂ©crire quelles applications dĂ©ployer dans un environnement non pas avec des arguments de ligne de commande, mais dans la description des environnements eux-mĂȘmes. Que faire ? On peut placer la description des releases dans un dossier sĂ©parĂ©, dans la description de l'environnement crĂ©er une liste des releases nĂ©cessaires et "accrocher" uniquement les releases requises, en ignorant les autres.
.
âââ 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.yamlreleases/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.yamlNote
Lorsque vous utilisez bases: il est impératif d'utiliser le séparateur yaml ---, afin de pouvoir modéliser les releases (et d'autres parties, comme helmDefaults) avec des valeurs provenant des environments
Dans ce cas, la release postgres ne sera mĂȘme pas incluse dans la description pour production. TrĂšs pratique !
Valeurs globales redéfinissables pour les releases
Bien sĂ»r, c'est super que l'on puisse dĂ©finir des valeurs pour les charts helm pour chaque environnement, mais que faire si plusieurs environnements sont dĂ©crits et que l'on souhaite, par exemple, dĂ©finir une valeur commune Ă tous affinity, mais que l'on ne souhaite pas la configurer par dĂ©faut dans les charts eux-mĂȘmes, qui sont stockĂ©s dans les dĂ©pĂŽts.
Dans ce cas, nous pourrions pour chaque release dĂ©finir 2 fichiers avec des valeurs : le premier avec les valeurs par dĂ©faut, qui dĂ©termineront les valeurs du chart lui-mĂȘme, et le second avec les valeurs pour l'environnement, qui Ă son tour remplace dĂ©jĂ les valeurs par dĂ©faut.
.
âââ envs
+ â  âââ dĂ©faut
+ â  â  âââ valeurs
+ â  â  âââ backend.yaml
+ â  â  âââ postgres.yaml
â  âââ dĂ©veloppement
â  â  âââ valeurs
â  â  âââ backend.yaml
â  â  âââ postgres.yaml
â  âââ production
â  âââ valeurs
â  âââ backend.yaml
â  âââ postgres.yaml
âââ releases
â  âââ backend.yaml
â  âââ postgres.yaml
âââ helmfile.yamlreleases/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/valeurs/backend.yaml
- envs/{{ .Environment.Name }}/valeurs/backend.yamlenvs/default/valeurs/backend.yaml
affinité:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- backend
topologyKey: "kubernetes.io/hostname"Définition des valeurs globales pour les charts helm de tous les releases au niveau de l'environnement
Supposons que plusieurs releases crĂ©ent plusieurs ingress â nous pourrions dĂ©finir manuellement pour chaque chart hosts:, mais dans notre cas, le domaine est le mĂȘme, alors pourquoi ne pas le dĂ©placer dans une variable globale et simplement substituer sa valeur dans les charts ? Pour cela, les fichiers avec les valeurs que nous souhaitons paramĂ©trer devront avoir l'extension .gotmpl, afin que helmfile sache qu'il doit passer par le moteur de templates.
.
âââ envs
â  âââ dĂ©faut
â  â  âââ valeurs
- â  â  âââ backend.yaml
- â  â  âââ postgres.yaml
+ â  â  âââ backend.yaml.gotmpl
+ â  â  âââ postgres.yaml.gotmpl
â  âââ dĂ©veloppement
â  â  âââ valeurs
â  â  âââ backend.yaml
â  â  âââ postgres.yaml
â  âââ production
â  âââ valeurs
â  âââ backend.yaml
â  âââ postgres.yaml
âââ releases
â  âââ backend.yaml
â  âââ postgres.yaml
âââ helmfile.yamlhelmfile.yaml
environnements:
développement:
valeurs:
- charts:
versions:
backend: 1.1.0
- apps:
- postgres
- backend
+ - global:
+ ingressDomain: k8s.devel.domain
production:
valeurs:
- charts:
versions:
backend: 1.0.5
- apps:
- backend
+ - global:
+ ingressDomain: production.domain
---
bases:
{{- range .Values.apps }}
- releases/{{ . }}.yaml
{{- end }}envs/default/valeurs/backend.yaml.gotmpl
ingress:
enabled: true
paths:
- /api
hosts:
- {{ .Values.global.ingressDomain }}envs/default/valeurs/postgres.yaml.gotmpl
ingress:
enabled: true
paths:
- /
hosts:
- postgres.{{ .Values.global.ingressDomain }}Note
Il est évident que l'ingress dans le chart postgres est quelque chose de trÚs douteux, c'est pourquoi il est simplement cité dans l'article comme un exemple sphérique dans le vide et pour ne pas introduire une nouvelle version juste pour décrire l'ingress.
Substitution des secrets (secrets) Ă partir des valeurs d'environnement.
De la mĂȘme maniĂšre que dans l'exemple ci-dessus, il est possible de substituer les valeurs chiffrĂ©es Ă l'aide de Au lieu de crĂ©er un fichier secrets distinct pour chaque version, oĂč dĂ©finir les valeurs chiffrĂ©es pour le chart, nous pouvons simplement dĂ©finir dans le default.yaml.gotmpl de la version, les valeurs qui seront prises Ă partir des variables dĂ©finies au niveau des environnements. Et les valeurs que nous ne devons pas cacher Ă qui que ce soit peuvent ĂȘtre redĂ©finies dans les valeurs de la version dans un environnement spĂ©cifique.
.
âââ 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.yamlhelmfile.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/valeurs/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.domainenvs/production/values/backend.yaml
elasticsearch:
host: elastic-0.production.domainNote
Au fait, getOrNil â une fonction spĂ©ciale pour les templates go dans helmfile, qui, mĂȘme si .Values.secrets n'existe pas, ne renverra pas d'erreur, mais permettra de substituer une valeur par dĂ©faut Ă l'aide de la fonction default remplacer par la valeur par dĂ©faut
Conclusion
Les éléments décrits semblent assez évidents, mais les informations sur la maniÚre de décrire de maniÚre conviviale le déploiement dans plusieurs environnements à l'aide de helmfile sont trÚs limitées. J'aime l'IaC (Infrastructure-as-Code) et je veux avoir une description claire de l'état du déploiement.
En conclusion, je tiens Ă ajouter que les variables pour l'environnement par dĂ©faut peuvent Ă©galement ĂȘtre paramĂ©trĂ©es par les variables d'environnement du systĂšme d'exploitation d'un certain runner Ă partir duquel le dĂ©ploiement sera lancĂ©, et ainsi obtenir des environnements dynamiques.
helmfile.yaml
environments:
default:
values:
- global:
clusterDomain: {{ env "CLUSTER_DOMAIN" | default "cluster.local" }}
ingressDomain: {{ env "INGRESS_DOMAIN" }}Source : habr.com
