يمكنك أن تقرأ عن helmfile نفسه وأمثلة على استخدامه في
سوف نتعرف على طرق غير واضحة لوصف الإصدارات في helmfile
لنفترض أن لدينا حزمة من مخططات الدفة (على سبيل المثال، postgres وبعض تطبيقات الواجهة الخلفية) والعديد من البيئات (العديد من مجموعات kubernetes، أو العديد من مساحات الأسماء، أو العديد من كليهما). نأخذ ملف القيادة ونقرأ الوثائق ونبدأ في وصف بيئاتنا وإصداراتنا:
.
├── 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
لقد انتهى بنا الأمر ببيئتين: تطوير, إنتاج - يحتوي كل منها على قيمه الخاصة لمخططات إصدار الدفة. سننشر لهم مثل هذا:
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
طرح postgres، لأننا نعلم أننا لسنا بحاجة إلى دفع قاعدة البيانات إلى k8s وللبيع لدينا مجموعة postgres منفصلة رائعة؟ لحل هذه المشكلة لدينا تسميات
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 ---
، بحيث يمكنك إصدار القوالب (وأجزاء أخرى، مثل helmDefaults) بقيم من البيئات
في هذه الحالة، لن يتم تضمين إصدار postgres في وصف الإنتاج. مريح جدا!
القيم العالمية القابلة للتجاوز للإصدارات
بالطبع، من الرائع أن تتمكن من تعيين قيم لمخططات الدفة لكل بيئة، ولكن ماذا لو كان لدينا عدة بيئات موصوفة، ونريد، على سبيل المثال، تعيين نفس الشيء للجميع affinity
، لكننا لا نريد تكوينه افتراضيًا في المخططات نفسها، والتي يتم تخزينها في اللفت.
في هذه الحالة، لكل إصدار يمكننا تحديد ملفين بقيم: الأول بالقيم الافتراضية، والتي ستحدد قيم المخطط نفسه، والثاني بقيم البيئة، والتي بدورها ستتجاوز تلك الافتراضية.
.
├── 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
، بحيث يعرف helmfile أنه يجب تشغيله من خلال محرك القالب.
.
├── 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 }}
المذكرة
من الواضح أن الدخول في مخطط postgres هو أمر مشكوك فيه للغاية، لذلك يتم تقديم هذه المقالة ببساطة كمثال كروي في الفراغ ومن أجل عدم إدخال بعض الإصدارات الجديدة في المقالة فقط من أجل وصف الدخول
استبدال الأسرار من القيم البيئية
قياسا على المثال أعلاه، يمكنك استبدال تلك المشفرة باستخدام
.
├── 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
- وظيفة خاصة لقوالب go في helmfile، والتي، حتى لو كانت .Values.secrets
لن يكون موجودًا، ولن يلقي خطأً، ولكنه سيسمح بالنتيجة باستخدام الوظيفة default
استبدال القيمة الافتراضية
اختتام
تبدو الأشياء الموصوفة واضحة تمامًا، لكن المعلومات حول الوصف المناسب للنشر في العديد من البيئات باستخدام helmfile نادرة جدًا، وأنا أحب IaC (البنية التحتية كرمز) وأريد الحصول على وصف واضح لحالة النشر.
في الختام، أود أن أضيف أن متغيرات البيئة الافتراضية يمكن، بدورها، تحديد معلماتها مع متغيرات البيئة الخاصة بنظام التشغيل لمشغل معين سيتم إطلاق النشر منه، وبالتالي الحصول على بيئات ديناميكية
helmfile.yaml
environments:
default:
values:
- global:
clusterDomain: {{ env "CLUSTER_DOMAIN" | default "cluster.local" }}
ingressDomain: {{ env "INGRESS_DOMAIN" }}
المصدر: www.habr.com