Diegimo organizavimas keliose k8s aplinkose naudojant helmfile

Helmfile - įvynioklis skirtas šturvalas, kuri leidžia aprašyti daugybę vairo leidimų vienoje vietoje, parametruoti jų diagramas kelioms aplinkoms ir taip pat nustatyti jų diegimo tvarką.

Galite perskaityti apie pačią helmfile ir jos naudojimo pavyzdžius Readme и geriausios praktikos vadovas.

Susipažinsime su neakivaizdžiais leidimų apibūdinimo būdais helmfile

Tarkime, kad turime vairo diagramų paketą (pvz., „postgres“ ir tam tikrą užpakalinę programą) ir kelias aplinkas (kelias „kubernetes“ grupes, kelias vardų sritis arba kelias iš abiejų). Paimame vairo failą, perskaitome dokumentaciją ir pradedame apibūdinti savo aplinką bei leidimus:

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

Mes gavome 2 aplinkas: išsivystyti, gamyba - kiekviename yra savo vairo atleidimo diagramų reikšmės. Mes juos pritaikysime taip:

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

Skirtingos vairo diagramų versijos skirtingose ​​aplinkose

Ką daryti, jei skirtingose ​​​​aplinkose turime įdiegti skirtingas užpakalinės programos versijas? Kaip parametruoti leidimo versiją? Aplinkos vertybės, prieinamos per {{ .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 }}
...

Skirtingas programų rinkinys skirtingose ​​aplinkose

Puiku, bet kas, jei mums to nereikia production įdiegti postgres, nes žinome, kad mums nereikia stumti duomenų bazės į k8s ir parduodame turime nuostabų atskirą postgres klasterį? Norėdami išspręsti šią problemą, turime etiketes

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

Tai puiku, bet man asmeniškai labiau patinka aprašyti kokias programas diegti aplinkoje ne naudojant paleidimo argumentus, o pačių aplinkų aprašyme. Ką daryti? Leidimų aprašymus galite patalpinti į atskirą aplanką, aplinkos aprašyme susikurti reikalingų leidimų sąrašą ir „pasiimti“ tik reikiamus leidimus, likusius ignoruoti.

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

Pastaba

kai naudojant bases: būtina naudoti yaml separatorių ---, kad galėtumėte šablonus išleisti (ir kitas dalis, pvz., helmDefaults) su reikšmėmis iš aplinkos

Tokiu atveju „postgres“ leidimas net nebus įtrauktas į gamybos aprašymą. Labai patogiai!

Nepakeičiamos pasaulinės leidimų vertės

Žinoma, puiku, kad galite nustatyti kiekvienos aplinkos vairo diagramų reikšmes, bet ką daryti, jei aprašome kelias aplinkas ir norime, pavyzdžiui, nustatyti vienodas visoms affinity, bet nenorime jo konfigūruoti pagal numatytuosius nustatymus pačiose diagramose, kurios saugomos ropėse.

Tokiu atveju kiekvienam leidimui galėtume nurodyti 2 failus su reikšmėmis: pirmasis su numatytosiomis reikšmėmis, kurios nustatys pačios diagramos reikšmes, o antrasis su aplinkos reikšmėmis, kurios savo ruožtu pakeis numatytieji.

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

Visų leidimų vairo diagramų pasaulinių verčių nustatymas aplinkos lygmeniu

Tarkime, kad sukuriame kelis įėjimus keliuose leidimuose – galėtume neautomatiškai nustatyti kiekvienai diagramai hosts:, bet mūsų atveju domenas yra tas pats, tai kodėl neįdėjus jo į kokį nors visuotinį kintamąjį ir tiesiog nepakeitus jo reikšmės diagramose? Norėdami tai padaryti, tie failai su reikšmėmis, kurias norime parametruoti, turės turėti plėtinį .gotmpl, kad helmfile žinotų, kad ją reikia paleisti per šablono variklį.

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

Pastaba

Akivaizdu, kad ingress postgres diagramoje yra labai abejotinas dalykas, todėl šis straipsnis pateikiamas tiesiog kaip sferinis pavyzdys vakuume ir tam, kad į straipsnį nebūtų įtraukta kokia nors nauja versija vien dėl ingress aprašymo.

Paslapčių pakeitimas aplinkos vertybėmis

Analogiškai su aukščiau pateiktu pavyzdžiu galite pakeisti šifruotus naudodami vairo paslaptys reikšmės. Užuot kurę savo paslapčių failą kiekvienam leidimui, kuriame galime apibrėžti užšifruotas diagramos reikšmes, galime tiesiog apibrėžti leidimo default.yaml.gotmpl reikšmes, kurios bus paimtos iš kintamųjų, apibrėžtų aplinkos lygiu. Ir vertybes, kurių mums nereikia nuo nieko slėpti, galima lengvai iš naujo apibrėžti išleidimo vertėse konkrečioje aplinkoje.

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

Pastaba

Beje, getOrNil - speciali funkcija go šablonams helmfile, kuri, net jei .Values.secrets nebus, neišmes klaidos, bet leis rezultatą naudojant funkciją default pakeisti numatytąją reikšmę

išvada

Aprašyti dalykai atrodo gana akivaizdūs, tačiau informacijos apie patogų diegimo keliose aplinkose naudojant helmfile aprašymą yra labai mažai, todėl man patinka IaC (Infrastructure-as-Code) ir noriu turėti aiškų diegimo būsenos aprašymą.

Baigdamas norėčiau pridurti, kad numatytosios aplinkos kintamieji savo ruožtu gali būti parametruojami su tam tikros programos, iš kurios bus paleistas diegimas, OS aplinkos kintamaisiais ir taip gauti dinamines aplinkas.

helmfile.yaml

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

Šaltinis: www.habr.com

Добавить комментарий