Pag-aayos ng deployment sa maraming k8 na kapaligiran gamit ang helmfile

Helmfile - wrapper para sa timon, na nagbibigay-daan sa iyong ilarawan ang maraming mga release ng timon sa isang lugar, i-parameter ang kanilang mga chart para sa ilang mga kapaligiran, at itakda din ang pagkakasunud-sunod ng kanilang deployment.

Maaari mong basahin ang tungkol sa helmfile mismo at mga halimbawa ng paggamit nito sa readme и gabay sa pinakamahusay na kasanayan.

Makikilala natin ang mga hindi halatang paraan upang ilarawan ang mga release sa helmfile

Sabihin nating mayroon kaming isang pakete ng mga chart ng timon (halimbawa, sabihin nating mga postgres at ilang backend application) at ilang mga kapaligiran (ilang kubernetes cluster, ilang namespace, o ilan sa pareho). Kinukuha namin ang helmfile, binabasa ang dokumentasyon at sinimulang ilarawan ang aming mga kapaligiran at mga release:

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

Nagtapos kami sa 2 kapaligiran: devel, produksyon — bawat isa ay naglalaman ng sarili nitong mga halaga para sa mga chart ng paglabas ng timon. Magde-deploy kami sa kanila tulad nito:

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

Iba't ibang bersyon ng mga chart ng timon sa iba't ibang kapaligiran

Paano kung kailangan nating ilunsad ang iba't ibang bersyon ng backend sa iba't ibang kapaligiran? Paano i-parameter ang bersyon ng paglabas? Ang mga halaga ng kapaligiran na magagamit sa pamamagitan ng {{ .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 }}
...

Iba't ibang hanay ng mga application sa iba't ibang kapaligiran

Mahusay, ngunit paano kung hindi natin kailangan production ilunsad ang mga postgres, dahil alam namin na hindi namin kailangang itulak ang database sa mga k8 at para sa pagbebenta mayroon kaming isang kahanga-hangang hiwalay na postgres cluster? Upang malutas ang problemang ito mayroon kaming mga label

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

Ito ay mahusay, ngunit personal na mas gusto kong ilarawan kung aling mga application ang i-deploy sa kapaligiran na hindi gumagamit ng mga argumento sa paglulunsad, ngunit sa paglalarawan ng mga kapaligiran mismo. Anong gagawin? Maaari mong ilagay ang mga paglalarawan ng release sa isang hiwalay na folder, lumikha ng isang listahan ng mga kinakailangang release sa paglalarawan ng kapaligiran at "kunin" lamang ang mga kinakailangang release, hindi papansinin ang iba.

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

Ang tala

Kapag ginagamit ang bases: kinakailangang gumamit ng yaml separator ---, para makapag-release ka ng template (at iba pang bahagi, gaya ng helmDefaults) na may mga value mula sa mga environment

Sa kasong ito, ang postgres release ay hindi man lang isasama sa paglalarawan para sa produksyon. Napakakomportable!

Mga overridable na pandaigdigang halaga para sa mga release

Siyempre, napakahusay na maaari kang magtakda ng mga halaga para sa mga chart ng timon para sa bawat kapaligiran, ngunit paano kung mayroon kaming ilang mga kapaligiran na inilarawan, at gusto naming, halimbawa, na itakda ang pareho para sa lahat affinity, ngunit hindi namin gustong i-configure ito bilang default sa mga chart mismo, na nakaimbak sa mga singkamas.

Sa kasong ito, para sa bawat paglabas maaari naming tukuyin ang 2 mga file na may mga halaga: ang una ay may mga default na halaga, na tutukuyin ang mga halaga ng chart mismo, at ang pangalawa ay may mga halaga para sa kapaligiran, na kung saan ay i-override ang mga default.

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

Pagtukoy sa mga pandaigdigang halaga para sa mga chart ng timon ng lahat ng mga release sa antas ng kapaligiran

Sabihin nating gumawa kami ng ilang pagpasok sa ilang release - maaari naming manual na tukuyin para sa bawat chart hosts:, ngunit sa aming kaso ang domain ay pareho, kaya bakit hindi ilagay ito sa ilang pandaigdigang variable at palitan lang ang halaga nito sa mga chart? Upang gawin ito, ang mga file na iyon na may mga halaga na gusto naming i-parameter ay kailangang magkaroon ng extension .gotmpl, para malaman ng helmfile na kailangan itong patakbuhin sa template engine.

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

Ang tala

Malinaw, ang pagpasok sa postgres chart ay isang bagay na lubhang kahina-hinala, kaya ang artikulong ito ay ibinigay lamang bilang isang spherical na halimbawa sa isang vacuum at upang hindi magpakilala ng ilang bagong release sa artikulo para lamang sa paglalarawan ng pagpasok

Pagpapalit ng mga lihim mula sa mga halaga ng kapaligiran

Sa pamamagitan ng pagkakatulad sa halimbawa sa itaas, maaari mong palitan ang mga naka-encrypt na gamit mga lihim ng timon mga kahulugan. Sa halip na gumawa ng sarili naming secrets file para sa bawat release, kung saan matutukoy namin ang mga naka-encrypt na value para sa chart, maaari naming tukuyin sa release default.yaml.gotmpl ang mga value na kukunin mula sa mga variable na tinukoy sa antas ng kapaligiran. At ang mga halaga na hindi namin kailangang itago mula sa sinuman ay madaling muling tukuyin sa mga halaga ng paglabas sa isang partikular na kapaligiran.

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

Ang tala

Sa pamamagitan ng paraan, getOrNil - isang espesyal na function para sa mga template ng go sa helmfile, na, kahit na .Values.secrets ay hindi iiral, hindi magtapon ng error, ngunit papayagan ang resulta gamit ang function default palitan ang default na halaga

Konklusyon

Ang mga bagay na inilarawan ay tila medyo halata, ngunit ang impormasyon sa isang maginhawang paglalarawan ng pag-deploy sa ilang mga kapaligiran gamit ang helmfile ay napakahirap, at mahal ko ang IaC (Infrastructure-as-Code) at nais kong magkaroon ng isang malinaw na paglalarawan ng estado ng pag-deploy.

Sa konklusyon, nais kong idagdag na ang mga variable para sa default na kapaligiran ay maaaring, sa turn, ay ma-parameter sa mga variable ng kapaligiran ng OS ng isang partikular na runner kung saan ilulunsad ang deployment, at sa gayon ay makakuha ng mga dynamic na kapaligiran

helmfile.yaml

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

Pinagmulan: www.habr.com

Magdagdag ng komento