Organizimi i vendosjes në mjedise të shumta k8s duke përdorur helmfile

Helmfile - mbështjellës për kaskë, i cili ju lejon të përshkruani shumë lëshime të timonit në një vend, të parametrizoni grafikët e tyre për disa mjedise dhe gjithashtu të vendosni rendin e vendosjes së tyre.

Ju mund të lexoni për vetë skedarin helmues dhe shembuj të përdorimit të tij në README О udhëzues për praktikat më të mira.

Ne do të njihemi me mënyra jo të dukshme për të përshkruar lëshimet në helmet

Le të themi se kemi një paketë me diagrame të drejtimit (për shembull, le të themi postgres dhe disa aplikacione mbështetëse) dhe disa mjedise (disa grupe kubernetes, disa hapësira emrash, ose disa nga të dyja). Ne marrim dosjen e helmetit, lexojmë dokumentacionin dhe fillojmë të përshkruajmë mjediset dhe versionet tona:

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

Ne pĂ«rfunduam me 2 mjedise: zhvillohem, prodhim — secila pĂ«rmban vlerat e veta pĂ«r tabelat e lĂ«shimit tĂ« timonit. Ne do t'u vendosim atyre si kjo:

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

Versione të ndryshme të tabelave të timonit në mjedise të ndryshme

Po sikur të na duhet të nxjerrim versione të ndryshme të backend-it në mjedise të ndryshme? Si të parametrizoni versionin e lëshimit? Vlerat mjedisore të disponueshme përmes {{ .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 }}
...

Komplet të ndryshëm aplikacionesh në mjedise të ndryshme

E shkëlqyeshme, por çfarë nëse nuk kemi nevojë production nxjerr postgres, sepse ne e dimë se nuk kemi nevojë të shtyjmë bazën e të dhënave në k8 dhe për shitje kemi një grup të mrekullueshëm postgres? Për të zgjidhur këtë problem ne kemi etiketa

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

Kjo Ă«shtĂ« e mrekullueshme, por personalisht unĂ« preferoj tĂ« pĂ«rshkruaj se cilat aplikacione tĂ« vendosen nĂ« mjedis jo duke pĂ«rdorur argumentet e nisjes, por nĂ« pĂ«rshkrimin e vetĂ« mjediseve. ÇfarĂ« duhet bĂ«rĂ«? Ju mund t'i vendosni pĂ«rshkrimet e lĂ«shimeve nĂ« njĂ« dosje tĂ« veçantĂ«, tĂ« krijoni njĂ« listĂ« tĂ« lĂ«shimeve tĂ« nevojshme nĂ« pĂ«rshkrimin e mjedisit dhe "tĂ« merrni" vetĂ«m lĂ«shimet e nevojshme, duke injoruar pjesĂ«n tjetĂ«r.

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

Shënimi

Kur duke përdorur bases: është e nevojshme të përdorni ndarësin yaml ---, në mënyrë që të mund të shabllon lëshimet (dhe pjesë të tjera, të tilla si helmDefaults) me vlera nga mjediset

Në këtë rast, publikimi i postgres nuk do të përfshihet as në përshkrimin për prodhim. Shumë komode!

Vlerat globale të kapërcyeshme për publikimet

Sigurisht, është mirë që mund të vendosni vlera për diagramet e drejtimit për çdo mjedis, por çka nëse kemi disa mjedise të përshkruara dhe duam, për shembull, të vendosim të njëjtën gjë për të gjithë affinity, por ne nuk duam ta konfigurojmë atë si parazgjedhje në vetë grafikët, të cilat ruhen në rrepë.

Në këtë rast, për çdo lëshim mund të specifikojmë 2 skedarë me vlera: i pari me vlerat e paracaktuara, i cili do të përcaktojë vlerat e vetë grafikut dhe i dyti me vlerat për mjedisin, i cili nga ana tjetër do të anashkalojë ato të paracaktuara.

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

Përcaktimi i vlerave globale për tabelat kryesore të të gjitha lëshimeve në nivel mjedisor

Le të themi se krijojmë disa hyrje në disa versione - ne mund të përcaktojmë manualisht për secilën tabelë hosts:, por në rastin tonë domeni është i njëjtë, kështu që pse të mos e vendosni në një variabël global dhe thjesht të zëvendësoni vlerën e tij në grafikët? Për ta bërë këtë, ata skedarë me vlera që duam të parametrizojmë do të duhet të kenë shtesën .gotmpl, në mënyrë që helmfili të dijë se duhet të ekzekutohet përmes motorit të shabllonit.

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

Shënimi

Natyrisht, hyrja në grafikun postgres është diçka jashtëzakonisht e dyshimtë, kështu që ky artikull është dhënë thjesht si një shembull sferik në një vakum dhe për të mos futur ndonjë version të ri në artikull vetëm për hir të përshkrimit të hyrjes.

Zëvendësimi i sekreteve nga vlerat e mjedisit

Për analogji me shembullin e mësipërm, ju mund të zëvendësoni ato të koduara duke përdorur sekretet e timonit kuptimet. Në vend që të krijojmë skedarin tonë sekret për çdo version, në të cilin mund të përcaktojmë vlera të koduara për grafikun, ne thjesht mund të përcaktojmë në versionin default.yaml.gotmpl vlerat që do të merren nga variablat e përcaktuara në niveli i mjedisit. Dhe vlerat që nuk kemi nevojë t'i fshehim nga askush mund të ripërcaktohen lehtësisht në vlerat e lëshimit në një mjedis specifik.

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

Shënimi

Rastësisht, getOrNil - një funksion i veçantë për go shabllonet në helmfile, të cilat, edhe nëse .Values.secrets nuk do të ekzistojë, nuk do të hedhë një gabim, por do të lejojë rezultatin duke përdorur funksionin default zëvendësojnë vlerën e paracaktuar

PĂ«rfundim

Gjërat e përshkruara duken mjaft të dukshme, por informacioni për një përshkrim të përshtatshëm të vendosjes në disa mjedise duke përdorur skedarin helmues është shumë i pakët, dhe unë e dua IaC (Infrastruktura-as-Code) dhe dua të kem një përshkrim të qartë të gjendjes së vendosjes.

Si përfundim, do të doja të shtoja se variablat për mjedisin e paracaktuar, nga ana tjetër, mund të parametrizohen me variablat e mjedisit të sistemit operativ të një kontrabandisti të caktuar nga i cili do të nisë vendosja, dhe kështu të fitohen mjedise dinamike

helmfile.yaml

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

Burimi: www.habr.com

Shto një koment