Helm
Kubernetes-ի package manager-ը․ template-ավորված chart-եր, values ըստ միջավայրի, release-ներ, որոնք կարող ես rollback անել։
30 վայրկյանում
Helm-ը Kubernetes հավելվածները փաթեթավորում է որպես chart-եր՝ template-ավորված manifest-ների թղթապանակներ, գումարած values ֆայլ՝ խելամիտ լռելյայն արժեքներով։ Chart-ը կլաստերում տեղադրում ես որպես release, override ես անում values-ը ըստ միջավայրի, թարմացնում ես այն նոր values-ով կամ տարբերակներով և մեկ հրամանով rollback անում ցանկացած նախորդ revision։ Դա Kubernetes-ում երրորդ կողմի ծրագրեր տեղադրելու ստանդարտ ձևն է և սեփական ծառայությունները deploy անելու տարածված եղանակ։
Իմ ամենօրյա stack-ում չէ․ գիտեմ հիմնական գաղափարները և մանրամասները կսովորեմ, երբ նախագիծը դա պահանջի։
Ինչու է սա կարևոր
- Մեկ հավելվածի Kubernetes manifest-ները արագ հասնում են հարյուրավոր տողերի Deployment-ների, Service-ների, Ingress-ների և ConfigMap-ների միջով․ Helm-ը դրանք վերածում է մեկ պարամետրավորված փաթեթի։
- Նույն chart-ը deploy է անում dev, staging և production՝ տարբեր values ֆայլերով, պատճենված YAML-ի փոխարեն, որը ժամանակի հետ տարամիտվում է։
- Release-ները տարբերակավորված են կլաստերում, ուստի թարմացումները հետևվում են, և հայտնի լավ revision-ին rollback-ը մեկ հրաման է։
- Open-source ենթակառուցվածքի մեծ մասը (ingress controller-ներ, cert-manager, Prometheus, տվյալների բազաներ) տրամադրում է պաշտոնական Helm chart, ուստի Helm-ի իմացությունը սպասվում է յուրաքանչյուրից, ով աշխատեցնում է Kubernetes։
Ինչպես է աշխատում
01Chart-եր, values և release-ներ
Երեք բառ են կրում ամբողջ գաղափարը։ Chart-ը փաթեթ է՝ թղթապանակ Chart.yaml-ով (անուն, տարբերակ, dependency-ներ), values.yaml-ով (լռելյայն կարգավորումներ) և templates/ թղթապանակով, որտեղ Kubernetes manifest-ներն են՝ գրված Go template-ներով։ Values-ը input-ներն են՝ image-ի tag, replica-ների քանակ, ռեսուրսների limit-ներ, hostname-ներ։ Release-ը chart-ի մեկ տեղադրված instance է կլաստերում՝ անունով և namespace-ով․ նույն chart-ը կարող ես մի քանի անգամ տեղադրել որպես տարբեր release-ներ։ Պատկերացրու chart-ը որպես բաց թողնված տեղերով բաղադրատոմս, values-ը՝ որպես քո պատասխանները այդ տեղերին, իսկ release-ը՝ որպես իրականում մատուցված ուտեստ՝ ամեն անգամ փոխելու համարակալված պատմությամբ։ Helm-ը template-ները values-ով render է անում սովորական manifest-ների, ուղարկում Kubernetes API և release-ի revision-ը գրանցում որպես Secret release-ի namespace-ում։ Սերվերային կողմում տեղադրելու ոչ մի component չկա։
02Երրորդ կողմի chart-երի տեղադրում և կառավարում
Chart-երը տարածվում են OCI registry-ների (նույն registry-ները, որոնք պահում են container image-ները) կամ դասական HTTP chart ռեպոզիտորիաների միջոցով։ Հրամանները հետևում են պարզ կյանքի ցիկլի։ helm install-ը ստեղծում է release, helm upgrade --install-ը idempotent է և այն է, ինչ օգտագործում են pipeline-ները, helm list-ը ցույց է տալիս release-ները, helm history-ն՝ revision-ները, helm rollback-ը վերադառնում է նախորդ revision, helm uninstall-ը հեռացնում է այն ամենը, ինչ release-ը ստեղծել է։ Տեղադրելուց առաջ միշտ ուսումնասիրիր chart-ի լռելյայն values-ը և փոխանցիր միայն քո override-ները քո սեփական ֆայլում։ Ամրացրու chart-ի տարբերակը --version-ով, որպեսզի upstream-ի նոր release-ը քեզ չզարմացնի։ --wait-ը ստիպում է Helm-ին սպասել, մինչև ռեսուրսները պատրաստ լինեն, իսկ Helm 4-ում --rollback-on-failure-ը (վերանվանված --atomic) ավտոմատ rollback է անում, եթե upgrade-ը ժամանակին առողջ չդառնա։
# Look before you install
helm show values oci://registry.example.com/charts/my-app --version 1.4.2 > defaults.yaml
# Install or upgrade, pinned, waiting for readiness
helm upgrade --install my-app oci://registry.example.com/charts/my-app \
--version 1.4.2 \
--namespace my-app --create-namespace \
-f values-production.yaml \
--wait --timeout 5m --rollback-on-failure
helm list -n my-app
helm history my-app -n my-app
helm rollback my-app 3 -n my-app
03Քո սեփական chart-ի գրելը
helm create my-app-ը գեներացնում է աշխատող chart տիպիկ վեբ ծառայության համար, որը հետո կրճատում ես։ Template-ները կարդում են values-ը {{ .Values.image.tag }}-ով, ներկառուցված օբյեկտները՝ {{ .Release.Name }} և {{ .Chart.AppVersion }}, և ֆունկցիաներ, ինչպես default, quote և toYaml։ nindent-ը YAML բլոկները դնում է ճիշտ indentation-ով, և հենց այստեղ են թաքնված template-ների bug-երի մեծ մասը։ Ընդհանուր հատվածները, օրինակ՝ ստանդարտ label-ները, դրվում են _helpers.tpl-ի մեջ որպես անվանված template-ներ և ներառվում include-ով։ values.yaml-ը պահիր լավ մեկնաբանված, որովհետև այն chart-ի հանրային ինտերֆեյսն է։ Chart.yaml-ն ունի երկու տարբերակ․ version-ը chart-ի սեփական semantic version-ն է, որը մեծանում է chart-ի ամեն փոփոխության ժամանակ, իսկ appVersion-ը այն հավելվածի տարբերակն է, որը այն deploy է անում, և լռելյայն տեղեկատվական է։
# templates/deployment.yaml (excerpt)
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "my-app.fullname" . }}
labels:
{{- include "my-app.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "my-app.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "my-app.selectorLabels" . | nindent 8 }}
spec:
containers:
- name: app
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
resources: {{- toYaml .Values.resources | nindent 12 }}
04Values ըստ միջավայրի
Chart-ի values.yaml-ը պահում է ապահով լռելյայն արժեքներ։ Յուրաքանչյուր միջավայր ստանում է փոքր override ֆայլ՝ միայն այն, ինչը տարբերվում է․ production-ը կարող է մեծացնել replica-ները, սահմանել ռեսուրսների limit-ներ, միացնել autoscaling և օգտագործել իրական hostname։ Մի քանի ֆայլ փոխանցիր -f-ով․ հետագա ֆայլերը հաղթում են, իսկ --set-ը հաղթում է ֆայլերին, բայց --set-ը պահիր մեկանգամյա արժեքների համար, օրինակ՝ CI-ից եկող image tag-ի, որպեսզի կոնֆիգուրացիան մնա review անելի Git-ում։ Երբեք secret-ներ մի՛ դիր Git-ում commit արված values ֆայլերում։ Հղիր գոյություն ունեցող Kubernetes Secret-ներին անունով, կամ ստեղծիր դրանք External Secrets Operator-ի կամ Sealed Secrets-ի նման գործիքներով, կամ deploy-ի պահին վերծանիր helm-secrets plugin-ով և SOPS-ով։ Chart-ում values.schema.json ֆայլը տեղադրման պահին ստուգում է values-ը JSON Schema-ի դեմ՝ բռնելով replicaCont-ի նման տառասխալները, մինչև դրանք հասնեն կլաստեր։
# values-production.yaml - only overrides
replicaCount: 3
image:
repository: registry.example.com/my-app
tag: "" # set by CI: --set image.tag=$GIT_SHA
ingress:
enabled: true
hosts:
- host: app.example.com
paths: [{ path: /, pathType: Prefix }]
resources:
requests: { cpu: 250m, memory: 256Mi }
limits: { memory: 512Mi }
existingSecret: my-app-env # created by External Secrets, not Helm
05Թեստավորում, փաթեթավորում և հրապարակում
Chart-ին վերաբերվիր ինչպես կոդի՝ release-ի գործընթացով։ helm lint-ը ստուգում է կառուցվածքը և տարածված սխալները։ helm template-ը լոկալ render է անում manifest-ները առանց կլաստերի, ուստի կարող ես review անել ճիշտ այն, ինչ կկիրառվի, կամ ստուգել այն kubeconform-ով Kubernetes schema-ների դեմ։ helm upgrade --dry-run=server-ը render և ստուգում է իրական API սերվերի դեմ։ helm diff plugin-ը ցույց է տալիս, թե ինչ կփոխի upgrade-ը, ինչը անգնահատելի է pull request-ներում։ Chart-ի թեստերը pod-եր են templates/tests-ում՝ նշված որպես hook-եր, և աշխատում են helm test-ով տեղադրումից հետո։ Հրապարակելու համար helm package-ը ստեղծում է տարբերակավորված .tgz, իսկ helm push-ը upload է անում այն OCI registry։ Ստորագրիր chart-երը և ստուգիր դրանք տեղադրման ժամանակ supply-chain-ի ամբողջականության համար, և CI-ում աշխատեցրու chart-testing (ct)՝ փոխված chart-երը lint անելու և ժամանակավոր կլաստերում, օրինակ՝ kind-ում, տեղադրելու համար։
helm lint ./charts/my-app
helm template my-app ./charts/my-app -f values-production.yaml | kubeconform -strict -summary
helm diff upgrade my-app ./charts/my-app -n my-app -f values-production.yaml
helm package ./charts/my-app # -> my-app-1.4.2.tgz
helm registry login registry.example.com
helm push my-app-1.4.2.tgz oci://registry.example.com/charts
Օգտագործեք, երբ
- Kubernetes-ում երրորդ կողմի ծրագրերի տեղադրում, որոնք ունեն պաշտոնական chart։
- Քո սեփական ծառայությունների deploy մի քանի միջավայր կամ կլաստեր՝ մեկ պարամետրավորված փաթեթից։
- Հավելվածի տարածում հաճախորդներին կամ այլ թիմերին, որոնք այն աշխատեցնում են իրենց սեփական կլաստերներում։
- Ուզում ես release-ների պատմություն և պարզ rollback-ներ սովորական Kubernetes-ի վրա։
Մի՛ օգտագործեք, երբ
- Kubernetes-ում չես․ Docker Compose-ին կամ PaaS-ին Helm պետք չէ։
- Մի քանի պարզ manifest՝ միջավայրերի փոքր տարբերություններով, որտեղ Kustomize overlay-ները ավելի պարզ են։
- Բարդ day-two գործողություններ, օրինակ՝ տվյալների բազայի failover և backup-ներ, որտեղ operator-ը կյանքի ցիկլը կառավարում է ավելի լավ, քան template-ները։
Այլընտրանքներ
- Kustomize
Առանց template-ների overlay-ներ և patch-եր սովորական YAML-ի վրա, ներկառուցված kubectl-ում։
- Kubernetes operator-ներ
Controller-ներ, որոնք անընդհատ կառավարում են բարդ stateful հավելվածներ՝ տեղադրումից և թարմացումից այն կողմ։
- Argo CD / Flux
GitOps controller-ներ, որոնք հաճախ render են անում Helm chart-եր և կլաստերը համաժամեցված պահում Git-ի հետ։
- Timoni / CUE, jsonnet
Տիպավորված կամ ծրագրավորվող կոնֆիգուրացիոն լեզուներ այն թիմերի համար, որոնք դուրս են աճել տեքստային template-ներից։
Լավագույն պրակտիկաներ
- Ամրացրու chart-երի տարբերակները և image-ների tag-երը․ երբեք production-ում մի՛ deploy արա լողացող latest տարբերակներ։
- Pipeline-ներում օգտագործիր helm upgrade --install --wait --rollback-on-failure-ով (կամ GitOps controller)։
- Միջավայրերի override-ները պահիր փոքր և Git-ում․ --set օգտագործիր միայն CI-ից եկող արժեքների համար, ինչպես image tag-ը։
- Secret-ները պահիր values ֆայլերից դուրս․ հղիր External Secrets-ով, Sealed Secrets-ով կամ SOPS-ով ստեղծված Secret-ներին։
- Chart-ի ամեն փոփոխության համար CI-ին ավելացրու values.schema.json, helm lint, kubeconform և helm diff։
- Ամեն փոփոխության ժամանակ մեծացրու chart-ի տարբերակը և հրապարակիր OCI registry-ում։
- Քո սեփական chart-երում որպես լռելյայն սահմանիր ռեսուրսների request-ներ, probe-եր և security context-ներ։
Տարածված սխալներ
- Երրորդ կողմի values.yaml-ը ամբողջությամբ պատճենել քո ռեպոզիտորիա, հետո upgrade-ի ժամանակ բաց թողնել upstream-ի լռելյայն արժեքների փոփոխությունները։
- Template-ներում indentation-ի սխալներ՝ nindent-ը մոռանալու կամ {{- նշանով բացատները սխալ կտրելու պատճառով։
- Helm-ով տեղադրելուց հետո ռեսուրսները kubectl-ով խմբագրել՝ առաջացնելով drift, որը հաջորդ upgrade-ը վերագրում է։
- Գաղտնաբառերը պահել բաց values ֆայլերում Git-ում։
- Ծանր տրամաբանություն դնել template-ներում, մինչև chart-ը դառնա անընթեռնելի ծրագրավորման լեզու։
Խորը վերլուծություն
06Hook-եր, հերթականություն և դրանց ձախողման ձևերը
Hook-երը helm.sh/hook annotation-ով նշված ռեսուրսներ են, որպեսզի Helm-ը դրանք աշխատեցնի կյանքի ցիկլի կոնկրետ կետերում՝ pre-install, pre-upgrade, post-upgrade, pre-delete, test և այլն։ Դասական օգտագործումը տվյալների բազայի migration Job-ն է pre-upgrade-ում, որպեսզի migration-ները աշխատեն նոր pod-երի գործարկումից առաջ։ helm.sh/hook-weight-ը կարգավորում է hook-երի հերթականությունը, իսկ helm.sh/hook-delete-policy-ն՝ մաքրումը, օրինակ՝ before-hook-creation,hook-succeeded։ Թակարդներ․ hook ռեսուրսները չեն կառավարվում որպես release-ի մաս, ուստի uninstall-ը դրանք չի հեռացնում, եթե delete policy-ն այլ բան չի ասում, ձախողված pre-upgrade hook-ը արգելափակում է upgrade-ը, ինչը լավ է, բայց դանդաղը կարող է հասնել timeout-ի, և hook-երը կատարյալ չեն աշխատում GitOps գործիքների հետ, որոնք դրանք թարգմանում են իրենց sync phase-երի։ Migration-ները պահիր idempotent և հետադարձ համատեղելի, և hook Job-երին տուր backoffLimit և activeDeadlineSeconds։
apiVersion: batch/v1
kind: Job
metadata:
name: {{ include "my-app.fullname" . }}-migrate
annotations:
"helm.sh/hook": pre-upgrade,pre-install
"helm.sh/hook-weight": "0"
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
spec:
backoffLimit: 1
activeDeadlineSeconds: 600
template:
spec:
restartPolicy: Never
containers:
- name: migrate
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
command: ["./migrate", "up"]
07Server-side apply, դաշտերի սեփականություն և drift
Client-side apply-ի դեպքում Helm-ը հաշվում էր three-way merge նախորդ release-ի manifest-ի, նոր manifest-ի և կենդանի օբյեկտի միջև։ Այլ մասնակիցների կատարած փոփոխությունները, օրինակ՝ HorizontalPodAutoscaler-ի կողմից replica-ների փոփոխությունը կամ ինչ-որ մեկի kubectl edit-ը, կարող էին լուռ վերագրվել կամ, ավելի վատ, բաց թողնվել։ Server-side apply-ը, որը Helm 4-ում նոր release-ների լռելյայն տարբերակն է, ուղարկում է ցանկալի manifest-ը և թողնում API սերվերին merge անել՝ managedFields-ում հետևելով, թե որ manager-ն է տիրապետում յուրաքանչյուր դաշտին։ Եթե մեկ այլ manager տիրապետում է դաշտին, որը Helm-ը ուզում է սահմանել, API-ն կոնֆլիկտ է հաղորդում՝ լուռ պայքարելու փոխարեն․ --force-conflicts-ը գիտակցաբար վերցնում է սեփականությունը։ Գործնական հետևանքներ․ մի՛ սահմանիր replicas chart-ում, երբ autoscaler-ն է դրանց տիրապետում, սպասիր բացահայտ կոնֆլիկտի սխալներ այնտեղ, որտեղ նախկինում լուռ վերագրումներ էին լինում, և ստուգիր release-ի apply մեթոդը helm get metadata-ով, նախքան հին release-ները server-side apply-ի տեղափոխելը։
08Library chart-եր, dependency-ներ և umbrella pattern
Dependency-ները հայտարարվում են Chart.yaml-ում՝ անունով, տարբերակի միջակայքով, ռեպոզիտորիայով և ոչ պարտադիր condition-ով, օրինակ՝ postgresql.enabled․ helm dependency update-ը ներբեռնում է դրանք charts/-ի մեջ և ամրացնում Chart.lock-ում։ Umbrella chart-ը մի քանի subchart համադրում է մեկ release-ում, ինչը հարմար է պլատֆորմային փաթեթի համար, բայց ռիսկային է իրար հետ չկապված ծառայությունների համար, որովհետև դրանք այդ դեպքում կիսում են մեկ release-ի կյանքի ցիկլ և մեկ ձախողման տիրույթ։ Library chart-ը (type: library) պարունակում է միայն անվանված template-ներ, ոչ մի ռեսուրս, և թույլ է տալիս բազմաթիվ ծառայությունների chart-երին կիսել նույն Deployment-ի և Service-ի սահմանումները, մինչդեռ յուրաքանչյուրը պահում է իր values-ը։ Դա տալիս է կազմակերպության մակարդակով ստանդարտներ label-ների, probe-երի և security context-ների համար՝ առանց template-ներ պատճենելու։ Parent chart-երը կարող են override անել subchart-ի values-ը subchart-ի անվան տակ, իսկ global values-ը տեսանելի են յուրաքանչյուր subchart-ին։
# Chart.yaml
apiVersion: v2
name: my-app
version: 1.4.2
appVersion: "2.8.0"
dependencies:
- name: common-templates
version: ~0.6.0
repository: oci://registry.example.com/charts
- name: redis
version: ">=20.0.0 <21.0.0"
repository: oci://registry.example.com/charts
condition: redis.enabled
Իրական իրավիճակներ
Upgrade-ը production-ը թողեց կիսով չափ deploy արված
Խնդիր
Pipeline-ը աշխատեցրեց helm upgrade առանց սպասելու։ Նոր pod-երը crash եղան բացակայող միջավայրի փոփոխականի պատճառով, release-ը նշվեց deployed, և traffic-ը մասամբ հասավ ձախողվող pod-երին։
Ինչպես լուծել
Անմիջապես rollback արա․ helm history-ով գտիր վերջին լավ revision-ը և helm rollback my-app <rev> --wait։ Ուղղիր pipeline-ը․ օգտագործիր helm upgrade --install --wait --timeout 5m --rollback-on-failure, որպեսզի անառողջ upgrade-ը ավտոմատ հետ գլորվի, և job-ը տեսանելիորեն ձախողվի։ Համոզվիր, որ Deployment-ն ունի readiness probe-եր, այլապես Kubernetes-ը crash եղող, բայց գործարկվող pod-երը պատրաստ է համարում։ Ավելացրու values.schema.json՝ փոփոխականը որպես պարտադիր, helm lint և helm diff քայլ pull request-ում։ Դիտարկիր staging deploy նույն values կառուցվածքով production-ից առաջ։
Երրորդ կողմի chart-ի թարմացում major տարբերակի միջով
Խնդիր
Ingress controller-ի chart-ը երկու major տարբերակ հետ է մնացել։ Թիմը տարիներ առաջ պատճենել է նրա ամբողջական values.yaml-ը և վախենում է թարմացումից։
Ինչպես լուծել
Պատճենված ֆայլը կրճատիր միայն իրական override-ներով՝ այն համեմատելով ընթացիկ տարբերակի helm show values-ի հետ։ Կարդա chart-ի changelog-ը և upgrade note-երը երկու major տարբերակների համար՝ նշելով վերանվանված values-ը և CRD-ների փոփոխությունները։ Երկու տարբերակներն էլ render արա helm template-ով և համեմատիր, կամ օգտագործիր helm diff upgrade կենդանի կլաստերի դեմ։ Նախ թարմացրու staging-ը՝ մեկ major տարբերակ ամեն անգամ, ստուգելով CRD-ները, որոնք Helm-ը ավտոմատ չի թարմացնում crds/ թղթապանակից։ Հետևիր մետրիկաներին և սխալների մակարդակին, հետո կրկնիր production-ում հանգիստ ժամին՝ rollback-ի պլանով։
Տասը microservice՝ տասը պատճենված chart-ով
Խնդիր
Յուրաքանչյուր ծառայություն ունի իր chart-ը, որը տարիներ առաջ ստեղծվել է helm create-ով։ Label-ները, probe-երը և անվտանգության կարգավորումները տարբերվում են, և անվտանգության ուղղումը պետք է կրկնել տասն անգամ։
Ինչպես լուծել
Ստեղծիր library chart անվանված template-ներով Deployment-ի, Service-ի, Ingress-ի, HPA-ի և լռելյայն ապահով securityContext-ի համար, հրապարակված OCI registry-ում semantic version-ներով։ Մեկ ծառայության chart-ը փոխակերպիր այնպես, որ կախված լինի դրանից՝ պահելով միայն values-ը և ծառայությանը հատուկ փոքր template-ներ, և helm template-ով ստուգիր, որ output-ը համարժեք է։ Մնացած ծառայությունները migrate արա աստիճանաբար։ Ավելացրու values.schema.json՝ ինտերֆեյսը ստանդարտացնելու համար։ Հիմա ուղղումը library-ի release է գումարած տարբերակների թարմացում, որը Renovate-ը կարող է ավտոմատ առաջարկել բոլոր ծառայությունների ռեպոզիտորիաներում։
Արագ ուղեցույց
- Ապահով install կամ upgrade
helm upgrade --install my-app ./chart -n my-app --create-namespace --wait --rollback-on-failure- Ցույց տալ chart-ի լռելյայն արժեքները
helm show values oci://registry.example.com/charts/my-app --version 1.4.2- Render լոկալ
helm template my-app ./chart -f values-production.yaml- Ստուգել կլաստերի դեմ
helm upgrade --install my-app ./chart --dry-run=server- Կենդանի release-ի values-ը
helm get values my-app -n my-app --all- Release-ի պատմություն
helm history my-app -n my-app- Rollback
helm rollback my-app 3 -n my-app --wait- Ամրացնել dependency-ները
helm dependency update ./chart- Փաթեթավորել և push անել
helm package ./chart && helm push my-app-1.4.2.tgz oci://registry.example.com/charts
Հարցեր և պատասխաններ
Q1Ո՞րն է տարբերությունը chart-ի, release-ի և revision-ի միջև։
Chart-ը փաթեթն է՝ template-ներ, լռելյայն values և metadata, տարբերակավորված semantic version-ով։ Release-ը այդ chart-ի մեկ տեղադրված instance է կլաստերում՝ նույնականացված անունով և namespace-ով․ նույն chart-ը կարող ես երկու անգամ տեղադրել որպես երկու release։ Revision-ը release-ի համարակալված snapshot է․ ամեն install, upgrade կամ rollback ստեղծում է նոր revision, որը գրանցում է render արված manifest-ները և օգտագործված values-ը։ Helm-ը revision-ները պահում է որպես Secret-ներ release-ի namespace-ում, և այդպես են աշխատում helm history-ն և helm rollback-ը։ Revision 3-ին rollback անելը իրականում ստեղծում է նոր revision, որի բովանդակությունը հավասար է revision 3-ին, ուստի պատմությունը երբեք չի վերագրվում։
Q2Helm, թե՞ Kustomize։
Helm-ը template-ավորման և փաթեթավորման գործիք է․ պարամետրերով chart-եր, տարբերակավորված տարածում, dependency-ներ և release-ների պատմություն rollback-ով։ Այն փայլում է երրորդ կողմի ծրագրերի և բազմաթիվ տարբերակներով deploy արվող հավելվածների համար։ Kustomize-ը աշխատում է սովորական YAML-ի վրա overlay-ներով և patch-երով, առանց template լեզվի, ներկառուցված է kubectl-ում․ այն հիանալի է, երբ manifest-ները քոնն են, և միջավայրերը փոքր-ինչ են տարբերվում։ Դրանք իրար չեն բացառում։ Շատ թիմեր վաճառողի ծրագրերը տեղադրում են Helm-ով, իսկ սեփական ծառայությունները կառավարում Kustomize-ով, և Kustomize-ը կարող է նույնիսկ inflate անել Helm chart-եր։ Իմ հիմնական կանոնը․ եթե պետք է տարածել կամ խիստ պարամետրավորել՝ Helm, եթե ուզում ես կարդալ ճիշտ այն YAML-ը, որը կիրառվում է՝ Kustomize։
Q3Ինչպե՞ս է աշխատում helm rollback-ը, և ի՞նչը այն չի հետարկում։
helm rollback my-app 3-ը վերցնում է revision 3-ում պահված manifest-ները և նորից կիրառում դրանք որպես նոր revision, ուստի Deployment-ները, ConfigMap-ները և մյուս ռեսուրսները վերադառնում են այդ վիճակին։ Այն չի հետարկում Kubernetes օբյեկտներից դուրս եղած բաները՝ աշխատած տվյալների բազայի migration-ները, նոր տարբերակի գրած տվյալները կամ արտաքին ռեսուրսները, օրինակ՝ DNS-ը կամ ամպային bucket-ները։ Այն նաև չի կարող առանց խնդիրների վերականգնել Helm-ից դուրս ձեռքով ջնջված ռեսուրսները, իսկ PersistentVolumeClaim-ները սովորաբար պահպանում են իրենց տվյալները անկախ ամեն ինչից։ Ահա թե ինչու տվյալների բազայի փոփոխությունները պետք է լինեն հետադարձ համատեղելի, իսկ migration-ները աշխատեն որպես առանձին, գիտակցված քայլեր։ Rollback-ը հուսալի է stateless կոնֆիգուրացիայի և image-ների համար, ոչ թե state-ի։
Q4Ինչպե՞ս ես կառավարում secret-ները Helm-ով։
Կանոնն այն է, որ secret արժեքները չեն ապրում բաց values ֆայլերում Git-ում։ Տարբերակներ՝ ըստ իմ նախընտրության․ chart-ը թող հղի գոյություն ունեցող Secret-ին անունով, և այդ Secret-ը ստեղծիր External Secrets Operator-ով ամպային secret manager-ից կամ Vault-ից, օգտագործիր Sealed Secrets, որը secret-ները գաղտնագրում է կլաստերի բանալիով, ուստի գաղտնագրված ձևը կարող է ապրել Git-ում, կամ օգտագործիր SOPS helm-secrets plugin-ով՝ գաղտնագրված values ֆայլերը deploy-ի պահին վերծանելու համար։ Նաև հիշիր, որ Helm-ը render արված manifest-ները պահում է release Secret-ներում, ուստի յուրաքանչյուր ոք, ով կարող է կարդալ namespace-ի Secret-ները, կարող է կարդալ Helm-ին փոխանցված values-ը։ Հետևաբար namespace-ի RBAC-ը նույնքան կարևոր է, որքան values-ի փոխանցման եղանակը։
Q5Ի՞նչ փոխվեց Helm 4-ով։
Helm 4-ը, թողարկված 2025-ի վերջին, առաջին major տարբերակն է 2019-ի Helm 3-ից հետո։ Ամենամեծ փոփոխությունը server-side apply-ն է նոր տեղադրումների համար․ Kubernetes-ն ինքն է merge անում փոփոխությունները և հետևում դաշտերի սեփականությանը՝ փոխարինելով Helm 3-ի client-side three-way merge-ը․ գոյություն ունեցող release-ները պահպանում են իրենց նախկին մեթոդը, եթե բացահայտ չընտրես նորը։ Մի քանի flag վերանվանվել են, օրինակ՝ --atomic-ը դարձել է --rollback-on-failure, իսկ --force-ը՝ --force-replace։ Կա նոր plugin համակարգ WebAssembly-ի վրա հիմնված plugin-ներով, պատրաստվածության ավելի լավ ստուգում kstatus-ով և OCI-ի բարելավված աջակցություն, ներառյալ digest-ով տեղադրումը։ v2 API օգտագործող chart-երը շարունակում են աշխատել, և release-ների պահեստը համատեղելի է, ուստի գոյություն ունեցող Helm 3 release-ները կարող են կառավարվել Helm 4-ով առանց migration-ի։ Helm 3-ը սահմանափակ ժամանակով ստանում է միայն անվտանգության ուղղումներ։
Սենիոր մակարդակի հարցեր
S1Ինչպե՞ս են Helm-ը և Argo CD-ի նման GitOps գործիքները համատեղվում։
Argo CD-ն և Flux-ը կարող են render անել Helm chart-եր և կիրառել արդյունքը՝ անընդհատ համաժամեցնելով կլաստերը Git-ի հետ։ Այդ մոդելում Helm-ը հիմնականում template-ավորման և փաթեթավորման ձևաչափ է․ Argo CD-ն render է անում helm template-ով և կիրառում իր սեփական շարժիչով, ուստի helm list-ը ոչինչ ցույց չի տալիս, և Argo-ի պատմությունը փոխարինում է Helm-ի revision-ներին։ Flux-ի helm-controller-ը, ընդհակառակը, իրական Helm release-ներ է կատարում։ GitOps-ի առավելություններ․ drift-ի հայտնաբերում, CI-ում կլաստերի credentials-ի բացակայություն և Git-ը որպես աուդիտի լոգ։ Ծախսեր․ hook-երը անկատար են համապատասխանում sync phase-երին, և debug-ը տարածվում է երկու գործիքի վրա։ Ես chart-երը կպահեի ընդհանուր և տարբերակավորված registry-ում, միջավայրերի values-ը՝ GitOps ռեպոզիտորիայում, և CI-ին թույլ կտայի միայն թարմացնել image tag-երը կամ chart-երի տարբերակները այնտեղ՝ pull request-ների միջոցով։
S2Ե՞րբ են Helm template-ները դառնում սխալ աբստրակցիա։
YAML-ի տեքստային template-ավորումը աշխատում է, մինչև chart-երը կուտակեն խորը պայմաններ, ներդրված map-երի վրա ցիկլեր և տասնյակ անջատիչներ։ Այդ ժամանակ ոչ ոք չի կարող կանխատեսել output-ը, values.yaml-ը դառնում է չփաստաթղթավորված API հարյուրավոր key-երով, և փոքր փոփոխությունները կոտրում են indentation-ը անհասկանալի ճյուղերում։ Նշաններ, որ փոխելու ժամանակն է․ գրում ես տրամաբանություն, ոչ թե պարամետրեր, chart-երը թեստավորում ես հիմնականում render անելով և աչքով նայելով, կամ մեկ chart փորձում է սպասարկել սկզբունքորեն տարբեր deploy ձևեր։ Տարբերակներ․ բաժանել ավելի փոքր chart-երի ընդհանուր library chart-ով, տարբերությունները տեղափոխել Kustomize overlay-ների մեջ render արված output-ի վրա, օգտագործել տիպավորված կոնֆիգուրացիոն լեզու, օրինակ՝ CUE, կամ Timoni-ի նման գործիք, կամ բարդ կյանքի ցիկլի տրամաբանության համար գրել operator։ Փոխզիջումը էկոհամակարգի ծածկույթն է․ Helm-ը համընդհանուր հասկանալի է, մինչդեռ այլընտրանքները նոր հմտություններ են պահանջում։
S3Ինչպե՞ս ես նախագծում chart, որը կտեղադրեն այլ թիմեր կամ հաճախորդներ։
values.yaml-ին վերաբերվիր որպես հանրային API-ի՝ semantic versioning-ով․ key-ի վերանվանումը breaking change է և պահանջում է major տարբերակ։ Տրամադրիր ապահով, աշխատող լռելյայն արժեքներ՝ non-root securityContext, ռեսուրսների request-ներ, probe-եր և առանց hard-coded hostname-ների։ Ստուգիր values.schema.json-ով և փաստաթղթավորիր ամեն արժեք։ Աջակցիր existingSecret pattern-ներին՝ values-ում secret-ներ պահանջելու փոխարեն։ Ոչ պարտադիր component-ները դարձրու պայմանական և խուսափիր cluster-scoped ռեսուրսներից, եթե դրանք հստակ պետք չեն, քանի որ շատ տեղադրողներ cluster-admin չունեն։ CRD-ների հետ զգույշ եղիր, որովհետև Helm-ը տեղադրում է, բայց չի թարմացնում crds/-ում եղածները․ շատ նախագծեր դրանք տրամադրում են որպես առանձին chart։ Ստորագրիր և հրապարակիր OCI registry-ում, պահիր changelog upgrade note-երով և CI-ում թեստավորիր install-ի և upgrade-ի ճանապարհները chart-testing-ով kind-ի վրա։
Բառարան
- Chart
- Helm փաթեթ՝ template-ներ, լռելյայն values և metadata Kubernetes հավելվածի համար։
- Release
- Chart-ի մեկ տեղադրված instance կլաստերում՝ անունով և namespace-ով։
- Revision
- Release-ի համարակալված snapshot, որը ստեղծվում է ամեն install-ով, upgrade-ով կամ rollback-ով։
- Values
- Կոնֆիգուրացիոն input-ներ, որոնք լրացնում են chart-ի template-ները՝ ֆայլերից կամ --set-ից։
- Hook
- Ռեսուրս, որը Helm-ը աշխատեցնում է կյանքի ցիկլի կետում, օրինակ՝ migration Job upgrade-ից առաջ։
- Library chart
- Chart, որը պարունակում է միայն վերօգտագործվող անվանված template-ներ, որոնք կիսում են այլ chart-եր։
- OCI registry
- Container registry, որը նաև պահում է Helm chart-եր որպես տարբերակավորված artifact-ներ։
- Server-side apply
- Kubernetes-ը ցանկալի վիճակը merge է անում API սերվերում և հետևում, թե որ գործիքն է տիրապետում յուրաքանչյուր դաշտին։
- values.schema.json
- JSON Schema chart-ում, որը տեղադրման ժամանակ ստուգում է տրամադրված values-ը։
Շարունակեք սովորել
Պրոդուկտի գաղափար ունե՞ք։Եկեք ստեղծենք այն։
Պատմեք ձեր գաղափարի, պրոդուկտի կամ թիմի մասին։ Սովորաբար պատասխանում եմ մեկ աշխատանքային օրվա ընթացքում։