Mengatur penggunaan kepada berbilang persekitaran k8 menggunakan fail helm

Helmfile - pembalut untuk menerajui, yang membolehkan anda menerangkan banyak keluaran teraju di satu tempat, meparameterkan carta mereka untuk beberapa persekitaran, dan juga menetapkan susunan penggunaannya.

Anda boleh membaca tentang helmfile itu sendiri dan contoh penggunaannya dalam readme и panduan amalan terbaik.

Kami akan membiasakan diri dengan cara yang tidak jelas untuk menerangkan keluaran dalam fail helm

Katakan kita mempunyai pek carta pimpinan (contohnya, katakan postgres dan beberapa aplikasi bahagian belakang) dan beberapa persekitaran (beberapa gugusan kubernetes, beberapa ruang nama atau beberapa daripada kedua-duanya). Kami mengambil fail helm, membaca dokumentasi dan mula menerangkan persekitaran dan keluaran 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 persekitaran: memajukan, pengeluaran — setiap satu mengandungi nilainya sendiri untuk carta keluaran teraju. Kami akan menggunakan kepada mereka seperti ini:

helmfile -n <namespace> -e <env> apply

Versi berbeza carta helm dalam persekitaran yang berbeza

Bagaimana jika kita perlu melancarkan versi bahagian belakang yang berbeza kepada persekitaran yang berbeza? Bagaimana untuk membuat parameter versi keluaran? Nilai alam sekitar yang 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 }}
...

Set aplikasi yang berbeza dalam persekitaran yang berbeza

Hebat, tetapi bagaimana jika kita tidak perlu production melancarkan postgres, kerana kami tahu bahawa kami tidak perlu memasukkan pangkalan data ke dalam k8 dan untuk dijual kami mempunyai kluster postgres berasingan yang menarik? Untuk menyelesaikan masalah ini kami mempunyai label

helmfile -n <namespace> -e devel apply
helmfile -n <namespace> -e production -l app=backend apply

Ini bagus, tetapi secara peribadi saya lebih suka menerangkan aplikasi mana yang hendak digunakan dalam persekitaran tidak menggunakan hujah pelancaran, tetapi dalam perihalan persekitaran itu sendiri. Apa nak buat? Anda boleh meletakkan perihalan keluaran dalam folder berasingan, buat senarai keluaran yang diperlukan dalam perihalan persekitaran dan "ambil" hanya keluaran yang diperlukan, mengabaikan yang lain

    .
    ├── 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

Nota itu

Apabila menggunakan bases: perlu menggunakan pemisah yaml ---, supaya anda boleh keluaran templat (dan bahagian lain, seperti helmDefaults) dengan nilai daripada persekitaran

Dalam kes ini, keluaran postgres tidak akan disertakan dalam perihalan untuk pengeluaran. Sangat selesa!

Nilai global yang boleh ditolak untuk keluaran

Sudah tentu, anda boleh menetapkan nilai untuk carta teraju untuk setiap persekitaran, tetapi bagaimana jika kami mempunyai beberapa persekitaran yang diterangkan, dan kami mahu, sebagai contoh, menetapkan perkara yang sama untuk semua affinity, tetapi kami tidak mahu mengkonfigurasinya secara lalai dalam carta itu sendiri, yang disimpan dalam lobak.

Dalam kes ini, untuk setiap keluaran kami boleh menentukan 2 fail dengan nilai: yang pertama dengan nilai lalai, yang akan menentukan nilai carta itu sendiri, dan yang kedua dengan nilai untuk persekitaran, yang seterusnya akan mengatasi yang lalai.

    .
    ├── 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"

Mentakrifkan nilai global untuk carta teraju semua keluaran di peringkat persekitaran

Katakan kita mencipta beberapa kemasukan dalam beberapa keluaran - kita boleh menentukan secara manual untuk setiap carta hosts:, tetapi dalam kes kami domain adalah sama, jadi mengapa tidak meletakkannya dalam beberapa pembolehubah global dan hanya menggantikan nilainya ke dalam carta? Untuk melakukan ini, fail dengan nilai yang ingin kita parameterkan perlu mempunyai sambungan .gotmpl, supaya helmfile tahu bahawa ia perlu dijalankan melalui enjin 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 }}

Nota itu

Jelas sekali, kemasukan dalam carta postgres adalah sesuatu yang sangat meragukan, jadi artikel ini diberikan semata-mata sebagai contoh sfera dalam vakum dan untuk tidak memperkenalkan beberapa keluaran baharu ke dalam artikel hanya untuk menerangkan kemasukan

Menggantikan rahsia daripada nilai persekitaran

Dengan analogi dengan contoh di atas, anda boleh menggantikan yang disulitkan menggunakan rahsia helm makna. Daripada mencipta fail rahsia kami sendiri untuk setiap keluaran, di mana kami boleh menentukan nilai yang disulitkan untuk carta, kami hanya boleh mentakrifkan dalam default keluaran.yaml.gotmpl nilai yang akan diambil daripada pembolehubah yang ditakrifkan di peringkat persekitaran. Dan nilai yang kita tidak perlu sembunyikan daripada sesiapa pun boleh ditakrifkan semula dengan mudah dalam nilai keluaran dalam persekitaran tertentu.

    .
    ├── 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

Nota itu

By the way, getOrNil - fungsi khas untuk templat go dalam fail helm, yang, walaupun .Values.secrets tidak akan wujud, tidak akan membuang ralat, tetapi akan membenarkan hasil menggunakan fungsi tersebut default menggantikan nilai lalai

Kesimpulan

Perkara-perkara yang diterangkan kelihatan agak jelas, tetapi maklumat tentang penerangan yang mudah tentang penggunaan ke beberapa persekitaran menggunakan fail helm adalah sangat terhad, dan saya suka IaC (Infrastruktur-sebagai-Kod) dan ingin mempunyai penerangan yang jelas tentang keadaan penggunaan.

Sebagai kesimpulan, saya ingin menambah bahawa pembolehubah untuk persekitaran lalai boleh, seterusnya, diparameterkan dengan pembolehubah persekitaran OS bagi pelari tertentu dari mana penggunaan akan dilancarkan, dan dengan itu memperoleh persekitaran dinamik

helmfile.yaml

environments:
  default:
    values:
    - global:
        clusterDomain: {{ env "CLUSTER_DOMAIN" | default "cluster.local" }}
        ingressDomain: {{ env "INGRESS_DOMAIN" }}

Sumber: www.habr.com

Tambah komen