شما می توانید در مورد خود helmfile و نمونه هایی از استفاده از آن بخوانید
ما با روش های غیر واضح برای توصیف نسخه ها در helmfile آشنا خواهیم شد
فرض کنید یک بسته از نمودارهای فرمان (به عنوان مثال، فرض کنید postgres و برخی از برنامه های کاربردی باطن) و چندین محیط (چند خوشه کوبرنت، چندین فضای نام، یا چند مورد از هر دو) داریم. ما فایل فرمان را می گیریم، اسناد را می خوانیم و شروع به توصیف محیط ها و نسخه های خود می کنیم:
.
├── 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
ما در نهایت به 2 محیط رسیدیم: توسعه, تولید - هر کدام حاوی مقادیر خاص خود برای نمودارهای انتشار فرمان است. ما به آنها به این صورت مستقر خواهیم کرد:
helmfile -n <namespace> -e <env> apply
نسخه های مختلف نمودارهای فرمان در محیط های مختلف
اگر بخواهیم نسخههای مختلف Backend را در محیطهای مختلف عرضه کنیم، چه؟ چگونه نسخه منتشر شده را پارامتر کنیم؟ ارزش های زیست محیطی در دسترس از طریق {{ .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 را منتشر کنید، زیرا میدانیم که نیازی به فشار دادن پایگاه داده به k8 نیست و برای فروش یک خوشه 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:
استفاده از جداکننده یامل ضروری است ---
، به طوری که می توانید نسخه های منتشر شده (و سایر بخش ها مانند helmDefaults) را با مقادیر از محیط ها الگوبرداری کنید.
در این مورد، انتشار postgres حتی در توضیحات برای تولید لحاظ نخواهد شد. خیلی راحت!
ارزش های جهانی قابل جبران برای نسخه ها
البته، خیلی خوب است که میتوانید برای هر محیط مقادیری را برای نمودارهای فرمان تنظیم کنید، اما اگر چندین محیط توصیف شده داشته باشیم، و مثلاً بخواهیم برای همه یکسان تنظیم کنیم، چه میشود. 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
، به طوری که 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 (زیرساخت به عنوان کد) هستم و می خواهم توضیح واضحی از وضعیت استقرار داشته باشم.
در پایان، میخواهم اضافه کنم که متغیرهای محیط پیشفرض، به نوبه خود، میتوانند با متغیرهای محیطی سیستمعامل یک runner خاص که استقرار از آن راهاندازی میشود، پارامتربندی شوند و در نتیجه محیطهای پویا به دست آید.
helmfile.yaml
environments:
default:
values:
- global:
clusterDomain: {{ env "CLUSTER_DOMAIN" | default "cluster.local" }}
ingressDomain: {{ env "INGRESS_DOMAIN" }}
منبع: www.habr.com