Anda dapat membaca tentang helmfile itu sendiri dan contoh penggunaannya di
Kita akan mengenal cara-cara yang tidak jelas untuk mendeskripsikan rilis di helmfile
Katakanlah kita memiliki sekumpulan diagram helm (misalnya, postgres dan beberapa aplikasi backend) dan beberapa lingkungan (beberapa cluster kubernetes, beberapa namespace, atau beberapa dari keduanya). Kami mengambil helmfile, membaca dokumentasi dan mulai menjelaskan lingkungan dan rilis kami:
.
├── 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
Kami berakhir dengan 2 lingkungan: devel, produksi — masing-masing berisi nilainya sendiri untuk bagan rilis helm. Kami akan menyebarkannya seperti ini:
helmfile -n <namespace> -e <env> apply
Versi bagan kemudi yang berbeda di lingkungan yang berbeda
Bagaimana jika kita perlu meluncurkan versi backend yang berbeda ke lingkungan yang berbeda? Bagaimana cara membuat parameter versi rilis? Nilai-nilai lingkungan tersedia melalui {{ .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 }}
...
Kumpulan aplikasi yang berbeda di lingkungan yang berbeda
Bagus, tapi bagaimana jika kita tidak perlu melakukannya production
meluncurkan postgres, karena kita tahu bahwa kita tidak perlu memasukkan database ke k8s dan untuk dijual kita memiliki cluster postgres terpisah yang bagus? Untuk mengatasi masalah ini kami memiliki label
helmfile -n <namespace> -e devel apply
helmfile -n <namespace> -e production -l app=backend apply
Ini bagus, tapi secara pribadi saya lebih suka menjelaskan aplikasi mana yang akan diterapkan di lingkungan bukan menggunakan argumen peluncuran, tetapi dalam deskripsi lingkungan itu sendiri. Apa yang harus dilakukan? Anda dapat menempatkan deskripsi rilis di folder terpisah, membuat daftar rilis yang diperlukan dalam deskripsi lingkungan dan "mengambil" hanya rilis yang diperlukan, mengabaikan sisanya
.
├── 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
Catatan
Bila menggunakan bases:
perlu menggunakan pemisah yaml ---
, sehingga Anda dapat membuat template rilis (dan bagian lain, seperti helmDefaults) dengan nilai dari lingkungan
Dalam hal ini, rilis postgres bahkan tidak akan disertakan dalam deskripsi produksi. Sangat nyaman!
Nilai global yang dapat dikesampingkan untuk rilis
Tentu saja, sangat bagus jika Anda dapat menetapkan nilai diagram kemudi untuk setiap lingkungan, tetapi bagaimana jika kita memiliki beberapa lingkungan yang dijelaskan, dan kami ingin, misalnya, menetapkan nilai yang sama untuk semua lingkungan? affinity
, tapi kami tidak ingin mengkonfigurasinya secara default di grafik itu sendiri, yang disimpan di lobak.
Dalam hal ini, untuk setiap rilis kita dapat menentukan 2 file dengan nilai: yang pertama dengan nilai default, yang akan menentukan nilai grafik itu sendiri, dan yang kedua dengan nilai lingkungan, yang pada gilirannya akan menimpa yang default.
.
├── 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"
Mendefinisikan nilai global untuk diagram kemudi dari semua rilis di tingkat lingkungan
Katakanlah kita membuat beberapa ingress dalam beberapa rilis - kita dapat menentukan secara manual untuk setiap grafik hosts:
, namun dalam kasus kita domainnya sama, jadi mengapa tidak memasukkannya ke dalam variabel global dan cukup mengganti nilainya ke dalam grafik? Untuk melakukan ini, file-file dengan nilai yang ingin kita parameterkan harus memiliki ekstensi .gotmpl
, agar helmfile mengetahui bahwa ia perlu dijalankan melalui mesin templat.
.
├── 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 }}
Catatan
Jelas sekali, ingress di grafik postgres adalah sesuatu yang sangat meragukan, jadi artikel ini diberikan hanya sebagai contoh bulat dalam ruang hampa dan agar tidak memasukkan beberapa rilis baru ke dalam artikel hanya demi menjelaskan ingress.
Menggantikan rahasia dari nilai-nilai lingkungan
Dengan analogi dengan contoh di atas, Anda dapat menggantinya dengan yang terenkripsi menggunakan
.
├── 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
Catatan
Kebetulan, getOrNil
- fungsi khusus untuk templat go di helmfile, yang meskipun .Values.secrets
tidak akan ada, tidak akan menimbulkan kesalahan, tetapi akan memungkinkan hasilnya menggunakan fungsi tersebut default
gantikan nilai default
Kesimpulan
Hal-hal yang dijelaskan tampak cukup jelas, tetapi informasi tentang deskripsi mudah penerapan ke beberapa lingkungan menggunakan helmfile sangat langka, dan saya menyukai IaC (Infrastruktur-as-Code) dan ingin memiliki gambaran yang jelas tentang status penerapan.
Sebagai kesimpulan, saya ingin menambahkan bahwa variabel untuk lingkungan default, pada gilirannya, dapat diparameterisasi dengan variabel lingkungan OS dari pelari tertentu tempat penerapan akan diluncurkan, dan dengan demikian memperoleh lingkungan yang dinamis.
helmfile.yaml
environments:
default:
values:
- global:
clusterDomain: {{ env "CLUSTER_DOMAIN" | default "cluster.local" }}
ingressDomain: {{ env "INGRESS_DOMAIN" }}
Sumber: www.habr.com