Helmfile kullanarak birden fazla k8s ortamına dağıtımı organize etme

Dümen dosyası - için sarıcı dümenBu, birçok dümen sürümünü tek bir yerde tanımlamanıza, çeşitli ortamlar için grafiklerini parametreleştirmenize ve ayrıca bunların konuşlandırılma sırasını ayarlamanıza olanak tanır.

Helmfile'ın kendisini ve kullanım örneklerini şu adreste okuyabilirsiniz: beni oku и en iyi uygulamalar kılavuzu.

Dümen dosyasındaki sürümleri tanımlamanın açık olmayan yollarını öğreneceğiz

Diyelim ki bir paket dümen grafiğimiz (örneğin, postgres ve bazı arka uç uygulamaları diyelim) ve birkaç ortamımız (birkaç kubernetes kümesi, birkaç ad alanı veya her ikisinden birden) var. Dümen dosyasını alıyoruz, belgeleri okuyoruz ve ortamlarımızı ve sürümlerimizi açıklamaya başlıyoruz:

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

Sonunda 2 ortam elde ettik: devel, üretim — her biri dümen serbest bırakma çizelgeleri için kendi değerlerini içerir. Onlara şu şekilde konuşlandıracağız:

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

Farklı ortamlardaki dümen haritalarının farklı versiyonları

Peki ya arka ucun farklı sürümlerini farklı ortamlara yaymamız gerekirse? Yayın sürümü nasıl parametrelendirilir? Mevcut çevresel değerler {{ .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 }}
...

Farklı ortamlarda farklı uygulamalar

Harika ama ya ihtiyacımız yoksa production Postgres'i kullanıma sunuyoruz, çünkü veritabanını k8'lere aktarmamıza gerek olmadığını biliyoruz ve satılık harika bir ayrı postgres kümemiz var, öyle mi? Bu sorunu çözmek için etiketlerimiz var

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

Bu harika, ancak şahsen ben ortamda hangi uygulamaların dağıtılacağını başlatma argümanlarını kullanarak değil, ortamların kendilerinin açıklamasında açıklamayı tercih ediyorum. Ne yapalım? Sürüm açıklamalarını ayrı bir klasöre yerleştirebilir, ortam açıklamasında gerekli sürümlerin bir listesini oluşturabilir ve geri kalanını göz ardı ederek yalnızca gerekli sürümleri "alabilirsiniz"

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

Dikkat

Kullanırken bases: yaml ayırıcı kullanmak gereklidir ---böylece sürümleri (ve helmDefaults gibi diğer parçaları) ortamlardan alınan değerlerle şablon haline getirebilirsiniz.

Bu durumda postgres sürümü üretim açıklamasına bile dahil edilmeyecektir. Çok rahat!

Sürümler için geçersiz kılınabilir genel değerler

Elbette, her ortam için dümen grafikleri için değerler ayarlayabilmeniz harika, ancak tanımlanmış birden fazla ortamımız varsa ve örneğin tümü için aynısını ayarlamak istiyorsak ne olur? affinity, ancak bunu şalgamlarda saklanan grafiklerin kendisinde varsayılan olarak yapılandırmak istemiyoruz.

Bu durumda, her sürüm için değerleri olan 2 dosya belirtebiliriz: birincisi, grafiğin değerlerini belirleyecek olan varsayılan değerlere sahip ve ikincisi, sırasıyla ortamın değerlerini geçersiz kılacak olan ortam değerlerine sahip. varsayılan olanlar.

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

Çevre düzeyindeki tüm sürümlerin dümen çizelgeleri için küresel değerlerin tanımlanması

Diyelim ki birkaç sürümde birden fazla giriş oluşturduğumuzu varsayalım; her grafik için manuel olarak tanımlayabiliriz hosts:, ancak bizim durumumuzda etki alanı aynı, o halde neden onu bazı global değişkenlere koyup değerini grafiklere koymayalım? Bunu yapmak için parametreleştirmek istediğimiz değerlere sahip dosyaların uzantısına sahip olması gerekir. .gotmpl, böylece helmfile şablon motoru aracılığıyla çalıştırılması gerektiğini bilir.

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

Dikkat

Açıkçası, postgres grafiğindeki giriş son derece şüpheli bir şeydir, bu nedenle bu makale, yalnızca girişi tanımlamak adına makaleye yeni bir sürüm eklememek için boşlukta küresel bir örnek olarak verilmiştir.

Sırların çevre değerlerinden değiştirilmesi

Yukarıdaki örneğe benzer şekilde, şifrelenmiş olanları kullanarak değiştirebilirsiniz. dümen sırları anlamlar. Grafiğe yönelik şifrelenmiş değerleri tanımlayabileceğimiz her sürüm için kendi secret dosyamızı oluşturmak yerine, default.yaml.gotmpl sürümünde basitçe tanımladığımız değişkenlerden alınacak değerleri tanımlayabiliriz. çevre seviyesi. Ve kimseden saklamamıza gerek olmayan değerler, belirli bir ortamdaki sürüm değerlerinde kolaylıkla yeniden tanımlanabilir.

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

Dikkat

Bu arada, getOrNil - helm dosyasındaki go şablonları için özel bir işlev; .Values.secrets mevcut olmayacak, hata vermeyecek, ancak fonksiyonun kullanılmasıyla sonuca izin verilecek default varsayılan değeri değiştir

Sonuç

Açıklanan şeyler oldukça açık görünüyor, ancak helm dosyası kullanılarak çeşitli ortamlara dağıtımın uygun bir açıklamasına ilişkin bilgi çok azdır ve IaC'yi (Kod Olarak Altyapı) seviyorum ve dağıtım durumunun net bir açıklamasına sahip olmak istiyorum.

Sonuç olarak, varsayılan ortam değişkenlerinin, dağıtımın başlatılacağı belirli bir çalıştırıcının işletim sisteminin ortam değişkenleriyle parametrelendirilebileceğini ve böylece dinamik ortamlar elde edilebileceğini eklemek isterim.

helmfile.yaml

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

Kaynak: habr.com

Yorum ekle