Organizimi i depilimit në shumë mjedise k8s përmes helmfile

Helmfile — njĂ« mbĂ«shtetje pĂ«r helm, e cila lejon qĂ« nĂ« njĂ« vend tĂ« pĂ«rshkruajmĂ« shumĂ« lĂ«shime helm, t'i parametrizojmĂ« chartet pĂ«r disa mjedise, si dhe tĂ« pĂ«rcaktojmĂ« radhĂ«n e shpĂ«rndarjes sĂ« tyre.

Për helmfile-n dhe shembujt e përdorimit të tij mund të lexoni në readme dhe udhëzuesin e praktikave më të mira.

Ne do të njohim me mënyrat jo të qarta për të përshkruar lëshimet në helmfile

Supozoni se kemi një grup helm-chartesh (për shembull, postgres dhe një aplikacion backend) dhe disa mjedise (disa klastera kubernetes, disa namespace ose të dyja). Marrim helmfile, lexojmë dokumentacionin dhe fillojmë të përshkruajmë mjediset dhe lëshimet 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

Na rezultoi 2 mjedise: devel, production — nĂ« secilin ndodhen vlerat e veta pĂ«r chartet helm tĂ« lĂ«shimeve. Ne do t'i shpĂ«rndajmĂ« nĂ« kĂ«tĂ« mĂ«nyrĂ«:

helmfile -n  -e  apply

Versionet e ndryshme të chartëve helm në mjedise të ndryshme

ÇfarĂ« tĂ« bĂ«jmĂ« nĂ«se na nevojitet tĂ« hedhim versionet e ndryshme tĂ« backend-it nĂ« mjedise tĂ« ndryshme? Si tĂ« parametrizojmĂ« versionin e lĂ«shimit? NĂ« ndihmĂ« vijnĂ« vlerat e mjedisit, 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 }}
...

Grupi i ndryshëm i aplikacioneve në mjedise të ndryshme

E shkëlqyer, por çfarë ndodh nëse nuk duam të production heqim postgres, sepse e dimë që nuk duhet të fusim bazën e të dhënave në k8s dhe për prodhim kemi një klaster postgres të shkëlqyer të ndarë? Për të zgjidhur këtë problem, kemi etiketat (labels)

helmfile -n  -e devel apply
helmfile -n  -e production -l app=backend apply

Kjo Ă«shtĂ« e shkĂ«lqyer, por unĂ« personalisht preferoj tĂ« pĂ«rshkruaj se cilat aplikacione tĂ« zbulojmĂ« nĂ« njĂ« mjedis jo me anĂ« tĂ« argumenteve tĂ« nisjes, por nĂ« pĂ«rshkrimin e vetĂ« mjediseve. ÇfarĂ« duhet bĂ«rĂ«? Mund tĂ« vendosim pĂ«rshkrimin e lĂ«shimeve nĂ« njĂ« dosje tĂ« veçantĂ«, nĂ« pĂ«rshkrimin e mjedisit tĂ« krijojmĂ« njĂ« listĂ« tĂ« lĂ«shimeve tĂ« nevojshme dhe "tĂ« lidhim" vetĂ«m lĂ«shimet e nevojshme, duke pĂ«rjashtuar tĂ« tjerat.

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

Kur përdoret bases: është e domosdoshme të përdoret ndarësi yaml ---, në mënyrë që të mund të modelojmë lëshimet (dhe pjesët e tjera, si helmDefaults) me vlerat nga mjediset

Në këtë rast lëshimi postgres as që do të përfshihet në përshkrimin për prodhimin. Shumë e përshtatshme!

Vlerat globale të rizgjedhura për lëshimet

Sigurisht, është e shkëlqyer që për çdo mjedis mund të caktojmë vlera për helm chartet, por çfarë ndodh nëse kemi përshkruar disa mjedise, dhe ne duam, për shembull, të caktojmë një vlerë të njëjtë për të gjithë affinity, por nuk duam ta konfigurojmë atë parazgjedhje në vetë chartet, që ruhen në repozita.

Në këtë rast mund të caktojmë për çdo lëshim 2 skedarë me vlera: njëri me vlera fillestare, të cilat do të përcaktojnë vlerat e vetë chartit, dhe tjetri me vlera për mjedisin, i cili nga ana e tij do të rizgjedhë vlerat fillestare.

    .
    ├── 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 helm chartet e të gjitha lëshimeve në nivelin e mjedisit

Supozoni se nĂ« disa lĂ«shime krijohen disa ingress — ne mund tĂ« pĂ«rkufizojmĂ« manualisht pĂ«r çdo chart hosts:, por nĂ« rastin tonĂ« domeni Ă«shtĂ« i njĂ«jtĂ«, kĂ«shtu qĂ« pse tĂ« mos e nxjerrim nĂ« njĂ« variabĂ«l globale dhe thjesht ta vendosim vlerĂ«n e saj nĂ« chartet? PĂ«r kĂ«tĂ«, ato skedarĂ« me vlera, qĂ« duam tĂ« parametrizojmĂ«, do tĂ« duhet tĂ« kenĂ« zgjedhjen .gotmpl, nĂ« mĂ«nyrĂ« qĂ« helmfile tĂ« dijĂ« se duhet tĂ« kalojĂ« pĂ«rmes 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ënim

ËshtĂ« e qartĂ« se ingress nĂ« chart postgres Ă«shtĂ« diçka jashtĂ«zakonisht e dyshimtĂ«, kĂ«shtu qĂ« nĂ« artikull ai Ă«shtĂ« dhĂ«nĂ« thjesht si njĂ« shembull sferik nĂ« vakuum dhe pĂ«r tĂ« mos futur njĂ« version tĂ« ri vetĂ«m pĂ«r tĂ« pĂ«rshkruar ingress.

Zëvendësimi i sekreteve (secrets) nga vlerat e mjedisit.

Në përputhje me shembullin e mësipërm, mund të zëvendësohen gjithashtu të dhënat e koduara me metodën. helm secrets në vend të kësaj. Në vend që të krijojmë një skedë sekretesh për çdo version, ku përcaktojmë vlerat e koduara për chart-in, mund të përcaktojmë thjesht vlerat në default.yaml.gotmpl të versionit, që do të merren nga variablat e caktuara në nivelin e mjedisit. Vlerat që nuk na nevojiten të fshihen nga askush mund të tejkalohen në vlerat e versionit në mjedisin përkatës.

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

  mjediset:
    devel:
      vlera:
      - charts:
          versionet:
            backend: 1.1.0
      - aplikacione:
        - postgres
        - backend
      - globale:
          ingressDomain: k8s.devel.domain
+     sekrete:
+       - envs/devel/secrets.yaml

    production:
      vlera:
      - charts:
          versionet:
            backend: 1.0.5
      - aplikacione:
        - backend
      - globale:
          ingressDomain: production.domain
+     sekrete:
+       - envs/production/secrets.yaml
  ---
  bazat:
  {{- range .Values.apps }}
    - releases/{{ . }}.yaml
  {{- end }}

envs/devel/secrets.yaml

sekrete:
    elastic:
        password: ENC[AES256_GCM,data:hjCB,iv:Z1P6/6xBJgJoKLJ0UUVfqZ80o4L84jvZfM+uH9gBelc=,tag:dGqQlCZnLdRAGoJSj63rBQ==,type:int]
...

envs/production/secrets.yaml

sekrete:
    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ënim

PĂ«r mĂ« tepĂ«r, getOrNil — njĂ« funksion special pĂ«r shabllonet go nĂ« helmfile, i cili, madje edhe nĂ«se .Values.secrets nuk do tĂ« ekzistojĂ«, nuk do tĂ« shkaktojĂ« njĂ« gabim, por do tĂ« lejojĂ« qĂ« me ndihmĂ«n e funksionit default tĂ« zĂ«vendĂ«sohet njĂ« vlerĂ« e paracaktuar.

Përfundim

Gjëra të përshkruara duket se janë mjaft të dukshme, por informacioni për një përshkrim të përshtatshëm të deploimit në disa mjedise duke përdorur helmfile është shumë i kufizuar, dhe unë e dua IaC (Infrastructure-as-Code) dhe dëshiroj të kem një përshkrim të qartë të shtetit të deploimit.

Në përfundim, dëshiroj të shtoj se variablat për mjedisin default mund të parametrizohen me variablat e ambientit të OS të një runner-i të caktuar, nga i cili do të niset deploimi, dhe kështu të kemi mjedise dinamike.

helmfile.yaml

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

Burimi: habr.com

Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS đŸ”„ Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS | ProHoster