Բոլոր դասերը
DevOps և ամպԱռաջադեմ10 րոպե ընթերցումԱրժե իմանալ

Helm

Kubernetes-ի package manager-ը․ template-ավորված chart-եր, values ըստ միջավայրի, release-ներ, որոնք կարող ես rollback անել։

  • Charts
  • Values
  • Releases
  • Rollbacks
Քայլ 1/4
Kubernetes-ը նավապետն է։ Դու ասում ես, թե ինչ ես ուզում՝ «իմ հավելվածի 3 օրինակ», և նա դա իրականացնում է։

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-ը ժամանակին առողջ չդառնա։

bash
# 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 է անում, և լռելյայն տեղեկատվական է։

yaml
# 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-ի նման տառասխալները, մինչև դրանք հասնեն կլաստեր։

yaml
# 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-ում, տեղադրելու համար։

bash
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-ներից։

Լավագույն պրակտիկաներ

  1. Ամրացրու chart-երի տարբերակները և image-ների tag-երը․ երբեք production-ում մի՛ deploy արա լողացող latest տարբերակներ։
  2. Pipeline-ներում օգտագործիր helm upgrade --install --wait --rollback-on-failure-ով (կամ GitOps controller)։
  3. Միջավայրերի override-ները պահիր փոքր և Git-ում․ --set օգտագործիր միայն CI-ից եկող արժեքների համար, ինչպես image tag-ը։
  4. Secret-ները պահիր values ֆայլերից դուրս․ հղիր External Secrets-ով, Sealed Secrets-ով կամ SOPS-ով ստեղծված Secret-ներին։
  5. Chart-ի ամեն փոփոխության համար CI-ին ավելացրու values.schema.json, helm lint, kubeconform և helm diff։
  6. Ամեն փոփոխության ժամանակ մեծացրու chart-ի տարբերակը և հրապարակիր OCI registry-ում։
  7. Քո սեփական 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։

yaml
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-ին։

yaml
# 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

Իրական իրավիճակներ

01

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-ից առաջ։

02

Երրորդ կողմի 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-ի պլանով։

03

Տասը 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-ը։

Պրոդուկտի գաղափար ունե՞ք։Եկեք ստեղծենք այն։

Պատմեք ձեր գաղափարի, պրոդուկտի կամ թիմի մասին։ Սովորաբար պատասխանում եմ մեկ աշխատանքային օրվա ընթացքում։