Organisearje ynset nei meardere k8s-omjouwings mei help fan helmfile

Helmfile - wrapper foar roer, wêrtroch jo in protte helmútjeften op ien plak kinne beskriuwe, har charts foar ferskate omjouwings parameterisearje, en ek de folchoarder fan har ynset ynstelle.

Jo kinne lêze oer helmfile sels en foarbylden fan it gebrûk yn README и best practices gids.

Wy sille yn 'e kunde komme mei net-foar de hân lizzende manieren om releases yn helmfile te beskriuwen

Litte wy sizze dat wy in pakket mei helmkaarten hawwe (lit ús sizze bygelyks postgres en wat backend-applikaasje) en ferskate omjouwings (ferskate kubernetes-klusters, ferskate nammeromten, of ferskate fan beide). Wy nimme de helmfile, lêze de dokumintaasje en begjinne ús omjouwings en releases te beskriuwen:

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

Wy einige mei 2 omjouwings: ûntwikkelje, produksje - elk befettet syn eigen wearden foar de roer release charts. Wy sille har sa ynsette:

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

Ferskillende ferzjes fan roer charts yn ferskillende omjouwings

Wat as wy ferskate ferzjes fan 'e backend moatte útrolje nei ferskate omjouwings? Hoe kinne jo de releaseferzje parameterisearje? De miljeuwearden beskikber fia {{ .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 }}
...

Ferskillende set applikaasjes yn ferskate omjouwings

Geweldich, mar wat as wy it net hoege production roll out postgres, om't wy witte dat wy net hoege te triuwe de databank yn k8s en te keap hawwe wy in prachtich apart postgres kluster? Om dit probleem op te lossen hawwe wy labels

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

Dit is geweldich, mar persoanlik leaver ik te beskriuwen hokker applikaasjes yn 'e omjouwing ynset wurde, net mei lansearringsarguminten, mar yn' e beskriuwing fan 'e omjouwings sels. Wat te dwaan? Jo kinne de frijlittingsbeskriuwings yn in aparte map pleatse, in list meitsje mei de nedige releases yn 'e omjouwingsbeskriuwing en allinich de nedige releases "ophelje", negearje de rest

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

De notysje

By it brûken bases: it is nedich om yaml separator te brûken ---, sadat jo sjabloanreleases (en oare dielen, lykas helmDefaults) kinne mei wearden út omjouwings

Yn dit gefal sil de postgres release net iens wurde opnommen yn 'e beskriuwing foar produksje. Hiel noflik!

Overridable globale wearden foar releases

Fansels is it geweldich dat jo wearden kinne ynstelle foar roerdiagrammen foar elke omjouwing, mar wat as wy ferskate omjouwings hawwe beskreaun, en wy wolle, bygelyks, itselde ynstelle foar alle affinity, mar wy wolle it net standert ynstelle yn 'e charts sels, dy't opslein wurde yn raap.

Yn dit gefal koene wy ​​foar elke release 2 bestannen mei wearden oantsjutte: de earste mei standertwearden, dy't de wearden fan 'e kaart sels bepale, en de twadde mei wearden foar de omjouwing, dy't op syn beurt de wearden sil oerskriuwe. standert ones.

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

It definiearjen fan globale wearden foar roerdiagrammen fan alle releases op miljeunivo

Litte wy sizze dat wy ferskate yngongen meitsje yn ferskate releases - wy koenen foar elke grafyk manuell definiearje hosts:, mar yn ús gefal is it domein itselde, dus wêrom net yn guon globale fariabele pleatse en syn wearde gewoan yn 'e charts ferfange? Om dit te dwaan moatte dy bestannen mei wearden dy't wy wolle parameterisearje de tafoeging hawwe .gotmpl, sadat helmfile wit dat it troch de sjabloanmotor rinne moat.

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

De notysje

Fansels is yngong yn 'e postgres-diagram wat ekstreem dubieuze, dus dit artikel wurdt gewoan jûn as in sfearysk foarbyld yn in fakuüm en om net wat nije release yn it artikel yn te fieren gewoan om' e beskriuwing fan yngong

It ferfangen fan geheimen fan miljeuwearden

Troch analogy mei it boppesteande foarbyld kinne jo fersifere fersifere ferfange mei helm geheimen betsjuttings. Ynstee fan it meitsjen fan ús eigen geheimenbestân foar elke release, wêryn wy fersifere wearden kinne definiearje foar it diagram, kinne wy ​​gewoan yn 'e release default.yaml.gotmpl de wearden definiearje dy't sille wurde nommen út' e fariabelen definieare by de miljeu nivo. En de wearden dy't wy net hoege te ferbergjen foar elkenien, kinne maklik opnij definieare wurde yn 'e frijlittingswearden yn in spesifike omjouwing.

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

De notysje

By de manier, getOrNil - in spesjale funksje foar gean sjabloanen yn helmfile, dy't, sels as .Values.secrets sil net bestean, sil net smyt in flater, mar sil tastean it resultaat mei help fan de funksje default ferfange standert wearde

konklúzje

De dingen beskreaun lykje frij fanselssprekkend, mar ynformaasje oer in handige beskriuwing fan ynset nei ferskate omjouwings mei help fan helmfile is hiel knappe, en ik hâld fan IaC (Infrastructure-as-Code) en wol in dúdlike beskriuwing fan de ynset steat.

As konklúzje soe ik taheakje wolle dat de fariabelen foar de standertomjouwing op har beurt kinne wurde parameterisearre mei de omjouwingsfariabelen fan it OS fan in bepaalde runner wêrfan de ynset sil wurde lansearre, en sa dynamyske omjouwings krije

helmfile.yaml

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

Boarne: www.habr.com

Add a comment