हेल्मफ़ाइल का उपयोग करके एकाधिक k8s परिवेशों में परिनियोजन व्यवस्थित करना

हेल्मफ़ाइल - के लिए रैपर संचालन, पतवार, जो आपको एक ही स्थान पर कई हेल्म रिलीज़ का वर्णन करने, कई वातावरणों के लिए उनके चार्ट को पैरामीटराइज़ करने और उनकी तैनाती का क्रम भी निर्धारित करने की अनुमति देता है।

आप हेल्मफाइल के बारे में और इसके उपयोग के उदाहरणों के बारे में पढ़ सकते हैं रीडमी и सर्वोत्तम प्रथाओं गाइड.

हम हेल्मफाइल में रिलीज़ का वर्णन करने के गैर-स्पष्ट तरीकों से परिचित होंगे

मान लें कि हमारे पास हेल्म चार्ट का एक पैक है (उदाहरण के लिए, मान लें कि पोस्टग्रेज़ और कुछ बैकएंड एप्लिकेशन) और कई वातावरण (कई कुबेरनेट्स क्लस्टर, कई नेमस्पेस, या दोनों में से कई)। हम हेल्मफ़ाइल लेते हैं, दस्तावेज़ पढ़ते हैं और अपने परिवेश और रिलीज़ का वर्णन करना शुरू करते हैं:

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

हमें दो वातावरण मिले: devel, उत्पादन - प्रत्येक में हेल्म रिलीज चार्ट के लिए अपने स्वयं के मूल्य शामिल हैं। हम उन्हें इस प्रकार तैनात करेंगे:

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

विभिन्न वातावरणों में हेल्म चार्ट के विभिन्न संस्करण

यदि हमें बैकएंड के विभिन्न संस्करणों को विभिन्न परिवेशों में रोल आउट करने की आवश्यकता हो तो क्या होगा? रिलीज़ संस्करण को पैरामीटराइज़ कैसे करें? के माध्यम से उपलब्ध पर्यावरणीय मूल्य {{ .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 }}
...

विभिन्न वातावरणों में अनुप्रयोगों का अलग-अलग सेट

बढ़िया, लेकिन क्या होगा अगर हमें इसकी ज़रूरत नहीं है production पोस्टग्रेज को रोल आउट करें, क्योंकि हम जानते हैं कि हमें डेटाबेस को k8s में धकेलने की आवश्यकता नहीं है और बिक्री के लिए हमारे पास एक अद्भुत अलग पोस्टग्रेज क्लस्टर है? इस समस्या को हल करने के लिए हमारे पास लेबल हैं

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

यह बहुत अच्छा है, लेकिन व्यक्तिगत रूप से मैं यह वर्णन करना पसंद करता हूं कि पर्यावरण में कौन से एप्लिकेशन को लॉन्च तर्कों का उपयोग करके तैनात नहीं किया जाना चाहिए, बल्कि स्वयं वातावरण के विवरण में। क्या करें? आप रिलीज़ विवरण को एक अलग फ़ोल्डर में रख सकते हैं, पर्यावरण विवरण में आवश्यक रिलीज़ की एक सूची बना सकते हैं और बाकी को अनदेखा करते हुए केवल आवश्यक रिलीज़ को "उठा" सकते हैं।

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

Заметка

जब प्रयोग bases: yaml विभाजक का उपयोग करना आवश्यक है ---, ताकि आप परिवेश के मानों के साथ टेम्प्लेट रिलीज़ (और अन्य भाग, जैसे हेल्मडिफॉल्ट्स) कर सकें

इस मामले में, पोस्टग्रेज़ रिलीज़ को उत्पादन के विवरण में भी शामिल नहीं किया जाएगा। बहुत आराम से!

रिलीज़ के लिए अत्यधिक वैश्विक मूल्य

बेशक, यह बहुत अच्छा है कि आप प्रत्येक वातावरण के लिए हेल्म चार्ट के लिए मान निर्धारित कर सकते हैं, लेकिन क्या होगा यदि हमारे पास कई वातावरण वर्णित हैं, और हम चाहते हैं, उदाहरण के लिए, सभी के लिए समान सेट करें affinity, लेकिन हम इसे स्वयं चार्ट में डिफ़ॉल्ट रूप से कॉन्फ़िगर नहीं करना चाहते हैं, जो शलजम में संग्रहीत हैं।

इस मामले में, प्रत्येक रिलीज़ के लिए हम मानों के साथ 2 फ़ाइलें निर्दिष्ट कर सकते हैं: पहला डिफ़ॉल्ट मानों के साथ, जो चार्ट के मानों को स्वयं निर्धारित करेगा, और दूसरा पर्यावरण के मानों के साथ, जो बदले में ओवरराइड करेगा डिफ़ॉल्ट वाले.

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

पर्यावरण स्तर पर सभी रिलीज़ के हेल्म चार्ट के लिए वैश्विक मूल्यों को परिभाषित करना

मान लीजिए कि हम कई रिलीज में कई इंग्रेस बनाते हैं - हम प्रत्येक चार्ट के लिए मैन्युअल रूप से परिभाषित कर सकते हैं hosts:, लेकिन हमारे मामले में डोमेन वही है, तो क्यों न इसे किसी वैश्विक चर में रखा जाए और इसके मान को चार्ट में प्रतिस्थापित कर दिया जाए? ऐसा करने के लिए, उन मानों वाली फ़ाइलों को जिन्हें हम पैरामीटराइज़ करना चाहते हैं, उन्हें एक्सटेंशन देना होगा .gotmpl, ताकि हेल्मफ़ाइल को पता चले कि इसे टेम्पलेट इंजन के माध्यम से चलाने की आवश्यकता है।

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

Заметка

जाहिर है, पोस्टग्रेज चार्ट में प्रवेश कुछ बेहद संदिग्ध है, इसलिए यह लेख केवल शून्य में एक गोलाकार उदाहरण के रूप में दिया गया है और केवल प्रवेश का वर्णन करने के लिए लेख में कुछ नई रिलीज पेश नहीं करने के लिए दिया गया है।

पर्यावरण मूल्यों से रहस्यों को प्रतिस्थापित करना

उपरोक्त उदाहरण के अनुरूप, आप एन्क्रिप्टेड का उपयोग करके स्थानापन्न कर सकते हैं पतवार रहस्य अर्थ. प्रत्येक रिलीज़ के लिए अपनी स्वयं की रहस्य फ़ाइल बनाने के बजाय, जिसमें हम चार्ट के लिए एन्क्रिप्टेड मानों को परिभाषित कर सकते हैं, हम केवल रिलीज़ default.yaml.gotmpl में उन मानों को परिभाषित कर सकते हैं जो परिभाषित चर से लिए जाएंगे। पर्यावरण स्तर. और जिन मूल्यों को हमें किसी से छिपाने की आवश्यकता नहीं है, उन्हें एक विशिष्ट वातावरण में रिलीज़ मूल्यों में आसानी से फिर से परिभाषित किया जा सकता है।

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

Заметка

संयोग से, getOrNil - हेल्मफाइल में गो टेम्प्लेट के लिए एक विशेष फ़ंक्शन, जो, भले ही .Values.secrets मौजूद नहीं होगा, कोई त्रुटि नहीं देगा, लेकिन फ़ंक्शन का उपयोग करके परिणाम की अनुमति देगा default स्थानापन्न डिफ़ॉल्ट मान

निष्कर्ष

वर्णित चीजें काफी स्पष्ट लगती हैं, लेकिन हेल्मफाइल का उपयोग करके कई वातावरणों में तैनाती के सुविधाजनक विवरण पर जानकारी बहुत दुर्लभ है, और मुझे IaC (इन्फ्रास्ट्रक्चर-एज़-कोड) पसंद है और मैं तैनाती स्थिति का स्पष्ट विवरण चाहता हूं।

अंत में, मैं यह जोड़ना चाहूंगा कि डिफ़ॉल्ट वातावरण के लिए चर, बदले में, एक निश्चित धावक के ओएस के पर्यावरण चर के साथ पैरामीटर किए जा सकते हैं, जहां से तैनाती शुरू की जाएगी, और इस प्रकार गतिशील वातावरण प्राप्त किया जा सकता है

helmfile.yaml

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

स्रोत: www.habr.com

एक टिप्पणी जोड़ें