Organizimi i shpërndarjes në shumë mjedise k8s me ndihmën e helmfile

Helmfile — njĂ« mbĂ«shtetje pĂ«r helm, e cila lejon pĂ«rshkrimin e shumĂ« lĂ«shimeve helm nĂ« njĂ« vend, parametrizimin e grafikĂ«ve tĂ« tyre pĂ«r disa mjedise, si dhe pĂ«rcaktimin e rendit tĂ« ndĂ«rhyrjeve tĂ« tyre.

Rreth helmfile dhe shembujve të përdorimit të tij mund të lexoni në readme dhe udhëzuesin për praktikat më të mira.

Ne do të njihemi me mënyrat jo të dukshme për të përshkruar lëshimet në helmfile

Le të supozojmë se kemi një grup helm-grafikësh (për shembull, postgres dhe një aplikacion backend) dhe disa mjedise (disa klasterë kubernetes, disa hapësira emri, 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

mjediset:
  devel:
  production:

lëshimet:
  - emri: postgres
    etiketat:
      app: postgres
    prite: true
    grafik: stable/postgresql
    version: 8.4.0
    vlerat:
      - envs/{{ .Environment.Name }}/values/postgres.yaml
  - emri: backend
    etiketat:
      app: backend
    prite: true
    grafik: private-helm-repo/backend
    version: 1.0.5
    nevojat:
      - postgres
    vlerat:
      - envs/{{ .Environment.Name }}/values/backend.yaml

Kemi marrĂ« 2 mjedise: devel, production — nĂ« secilin ndodhen vlerat e tij pĂ«r grafikĂ«t e lĂ«shimeve helm. Ne do tĂ« ndĂ«rhyjmĂ« nĂ« to kĂ«shtu:

helmfile -n  -e  apply

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

ÇfarĂ« tĂ« bĂ«jmĂ« nĂ«se na nevojitet tĂ« dalim me versione tĂ« ndryshme tĂ« backend nĂ« mjedise tĂ« ndryshme? Si tĂ« parametrizojmĂ« versionin e lĂ«shimit? Vlerat e mjedisit, tĂ« disponueshme nĂ«pĂ«rmjet {{ .Values }}

helmfile.yaml

mjediset:
  devel:
+   vlerat:
+   - grafikët:
+       versionet:
+         backend: 1.1.0
  production:
+   vlerat:
+   - grafikët:
+       versionet:
+         backend: 1.0.5
...
  - emri: backend
    etiketat:
      app: backend
    prite: true
    grafik: private-helm-repo/backend
-   version: 1.0.5
+   version: {{ .Values.grafikët.versionet.backend }}
...

Grup i ndryshëm aplikacionesh në mjedise të ndryshme

Shumë mirë, por çfarë nëse nuk duhet të production lançojmë postgres, sepse e dimë se nuk duhet të vendosim një bazë të dhënash në k8s dhe për prodhim kemi një klaster postgres të shkëlqyer të veçantë? 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Ă« shkĂ«lqyer, por personalisht preferoj tĂ« pĂ«rshkruaj se cilat aplikacione tĂ« vendosen nĂ« mjedis jo pĂ«rmes argumenteve tĂ« nisjes, por nĂ« pĂ«rshkrimin e vetĂ« mjediseve. ÇfarĂ« mund tĂ« bĂ«jmĂ«? 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 injoruar tĂ« tjerat.

    .
    ├── envs
    │   ├── devel
    │   │   └── values
    │   │       ├── backend.yaml
    │   │       └── postgres.yaml
    │   └── production
    │       └── values
    │           ├── backend.yaml
    │           └── postgres.yaml
+   ├── releases
+   │   ├── backend.yaml
+   │   └── postgres.yaml
    └── helmfile.yaml

helmfile.yaml


  mjediset:
    devel:
      values:
      - charts:
          versions:
            backend: 1.1.0
      - apps:
        - postgres
        - backend

    production:
      values:
      - charts:
          versions:
            backend: 1.0.5
      - apps:
        - backend

- lëshime:
-    - emri: postgres
-      etiketat:
-        app: postgres
-      prit: true
-      grafiku: stable/postgresql
-      version: 8.4.0
-      vlerat:
-        - envs/{{ .Environment.Name }}/values/postgres.yaml
-    - emri: backend
-      etiketat:
-        app: backend
-      prit: true
-      grafiku: private-helm-repo/backend
-     version: {{ .Values.charts.versions.backend }}
-     nevojat:
-       - postgres
-     vlerat:
-       - envs/{{ .Environment.Name }}/values/backend.yaml
+ ---
+ baza:
+ {{- range .Values.apps }}
+   - releases/{{ . }}.yaml
+ {{- end }}

releases/postgres.yaml

lëshime:
  - emri: postgres
    etiketat:
      app: postgres
    prit: true
    grafiku: stable/postgresql
    version: 8.4.0
    vlerat:
      - envs/{{ .Environment.Name }}/values/postgres.yaml

releases/backend.yaml

lëshime:
  - emri: backend
    etiketat:
      app: backend
    prit: true
    grafiku: private-helm-repo/backend
    version: {{ .Values.charts.versions.backend }}
    nevojat:
      - postgres
    vlerat:
      - envs/{{ .Environment.Name }}/values/backend.yaml

Shënim

Kur përdorni baza: është e nevojshme të përdoret patjetër ndarja yaml ---, për të mundësuar templating të lëshimeve (dhe pjesëve të tjera, si helmDefaults) me vlera nga mjediset

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

Vlerat globale të zëvendësueshme për lëshimet

Sigurisht, është shkëlqyer që mund të vendosen vlera për çdo mjedis për grafiket helm, por çfarë ndodh nëse kemi përshkruar disa mjedise dhe duam, për shembull, të vendosim një vlerë të njëjtë për të gjithë affinity, por nuk duam ta konfiguroni atë si të paracaktuar në grafiket vetë, të cilat ruhen në repot.

Në këtë rast, mund të caktuam për secilën lëshim 2 skedarë me vlera: i pari me vlerat e paracaktuara, të cilat do të përcaktojnë vlerat e grafikut, dhe i dyti me vlerat për mjedisin, i cili nga ana tjetër do të zëvendësojë vlerat e 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

lëshime:
  - emri: backend
    etiketat:
      app: backend
    presje: e vërtetë
    grafik: private-helm-repo/backend
    version: {{ .Values.charts.versions.backend }}
    nevojat:
      - postgres
    vlerat:
+     - envs/default/values/backend.yaml
      - envs/{{ .Environment.Name }}/values/backend.yaml

envs/default/values/backend.yaml

afiniteti:
  podAntiAffinity:
    preferuarGjatëPlanifikimitInjoruarGjatëEkzekutimit:
    - peshë: 1
      podAffinityTerm:
        labelSelector:
          matchExpressions:
          - çelës: app.kubernetes.io/name
            operator: NĂ«
            vlerat:
            - backend
        topologyKey: "kubernetes.io/hostname"

Përcaktimi i vlerave globale për helm chartet e të gjitha lëshimeve në nivelin e ambientit

Supozoni se nĂ« disa lĂ«shime krijohen disa ingress — do tĂ« mund tĂ« pĂ«rcaktonim manualisht pĂ«r secilin chart hostet:, 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Ă« dĂ«shirojmĂ« tĂ« parametrizojmĂ«, duhet tĂ« kenĂ« shtrirjen .gotmpl, nĂ« mĂ«nyrĂ« qĂ« helmfile tĂ« dijĂ« se duhet t'i kalojĂ« pĂ«rmes shabllonizuesit.

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

  ambientet:
    devel:
      vlerat:
      - chartet:
          versionet:
            backend: 1.1.0
      - aplikacionet:
        - postgres
        - backend
+     - globale:
+         ingressDomain: k8s.devel.domain

    production:
      vlerat:
      - chartet:
          versionet:
            backend: 1.0.5
      - aplikacionet:
        - backend
+     - globale:
+         ingressDomain: production.domain
  ---
  bazat:
  {{- range .Values.apps }}
    - releases/{{ . }}.yaml
  {{- end }}

envs/default/values/backend.yaml.gotmpl

ingress:
  e mundësuar: e vërtetë
  rrugët:
    - /api
  hostet:
    - {{ .Values.global.ingressDomain }}

envs/default/values/postgres.yaml.gotmpl

ingress:
  e mundësuar: e vërtetë
  rrugët:
    - /
  hostet:
    - postgres.{{ .Values.global.ingressDomain }}

Shënim

Mund të thuhet se ingress në chartin postgres është diçka jashtëzakonisht e dyshimtë, prandaj në këtë artikull është paraqitur thjesht si një shembull sferik në vakum dhe për të mos futur një lëshim të ri në artikull vetëm për të përshkruar ingress.

Vendosja e sekreteve (secrets) nga vlerat e ambientit

Në përputhje me shembullin e mësipërm, mund të vendosim gjithashtu të dhëna të koduara me helm secrets vlerat. Në vend që për secilin lëshim të krijojmë skedarin e tij të sekreteve, ku përcaktojmë vlerat e koduara për chartin, mund të përcaktojmë thjesht në default.yaml.gotmpl vlerat që do të merren nga variablat e përcaktuara në nivel ambientesh. Ndërsa vlerat që nuk na duhen të fshihen nga askush, mund të rivedosim qetësisht në vlerat e lëshimit në ambientin konkret.

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

  ambientet:
    devel:
      vlerat:
      - chartet:
          versionet:
            backend: 1.1.0
      - aplikacionet:
        - postgres
        - backend
      - globale:
          ingressDomain: k8s.devel.domain
+     sekrete:
+       - envs/devel/secrets.yaml

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

envs/devel/secrets.yaml

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

envs/production/secrets.yaml

sekretet:
    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

Me thĂ«nĂ« tĂ« vĂ«rtetĂ«n, getOrNil — funksion i veçantĂ« pĂ«r shabllonet go nĂ« helmfile, i cili, edhe nĂ«se .Values.secrets nuk ekziston, nuk do tĂ« hedhĂ« njĂ« gabim, por do tĂ« lejojĂ« nĂ« pĂ«rfundim qĂ« me anĂ« tĂ« funksionit default tĂ« vendosĂ« njĂ« vlerĂ« tĂ« paracaktuar

Përfundimi

Gjërat e përshkruara duken mjaft të qarta, por informacioni për një përshkrim të lehtë të deploy-it në disa ambiente me ndihmën e helmfile është shumë i pakët, dhe mua më pëlqen IaC (Infrastructure-as-Code) dhe dua të kem një përshkrim të qartë të gjendjes së deploy-it.

Si përfundim, dëshiroj të shtoj se variablat për ambientin default mund të parametrizohen gjithashtu me variablat e ambientit të SO-së së një runner-i, nga i cili do të kryhet deploy, dhe në këtë mënyrë të marrim ambiente dinamike

helmfile.yaml

ambientet:
  default:
    vlerat:
    - globale:
        clusterDomain: {{ env "CLUSTER_DOMAIN" | default "cluster.local" }}
        ingressDomain: {{ env "INGRESS_DOMAIN" }}

Burimi: habr.com

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