Kas tas Helm ir kodėl jis tapo tokiu populiariu
Kubernetes ekosistema yra galinga, bet kartu ir sudėtinga. Bet kas, bandęs rankiniu būdu valdyti dešimtis YAML failų, žino, kaip greitai tai tampa košmaru. Čia ir ateina į pagalbą Helm – paketų valdytojas, kuris Kubernetes pasaulyje atlieka panašų vaidmenį kaip apt Ubuntu sistemoje ar npm JavaScript projekte.
Helm buvo sukurtas 2015 metais ir greitai tapo de facto standartu Kubernetes aplikacijų valdymui. Pagrindinė jo idėja paprasta: vietoj to, kad kiekvieną kartą rašytumėte dešimtis konfigūracijos failų, galite naudoti paruoštus šablonus (vadinamus „charts”), kuriuos lengva pritaikyti savo poreikiams. Tai tarsi receptų knyga jūsų infrastruktūrai.
Pati įdomiausia dalis yra ta, kad Helm leidžia ne tik įdiegti aplikacijas, bet ir valdyti jų gyvavimo ciklą – atnaujinti, grąžinti į ankstesnę versiją, ištrinti. Viskas daroma keliais komandomis, o ne redaguojant šimtus eilučių YAML kodo.
Kaip Helm iš tikrųjų veikia po gaubtu
Helm architektūra yra gana elegantiškai suprojektuota. Anksčiau (Helm 2 versijoje) buvo naudojama kliento-serverio architektūra su Tiller komponentu, kuris veikė Kubernetes klasteryje. Bet tai sukėlė nemažai saugumo problemų, todėl Helm 3 versijoje Tiller buvo visiškai pašalintas. Dabar Helm veikia kaip gryna kliento pusės įrankis, kuris tiesiogiai bendrauja su Kubernetes API.
Kai vykdote helm install komandą, įvyksta keletas dalykų. Pirma, Helm paima jūsų chart failą (kuris iš esmės yra suarchyvuota katalogų struktūra su šablonais). Tada jis įvertina visus šablonus, įstatydamas jūsų nurodytas reikšmes. Galiausiai sugeneruoti Kubernetes manifestai siunčiami į API serverį.
Vienas iš genialiausių Helm sprendimų yra tai, kaip jis saugo išdiegimų istoriją. Kiekvienas išdiegimas (vadinamas „release”) saugomas kaip Kubernetes Secret arba ConfigMap objektas. Tai reiškia, kad galite bet kada pamatyti, kas buvo įdiegta, kada ir su kokiomis reikšmėmis. Rollback funkcionalumas veikia būtent dėl šios istorijos.
Charts struktūra ir kaip ją suprasti
Helm chart yra ne kažkas mistiškai sudėtingo. Tai tiesiog katalogų struktūra su apibrėžta organizacija. Tipinis chart atrodo maždaug taip:
mychart/
Chart.yaml # Metaduomenys apie chart
values.yaml # Numatytosios reikšmės
charts/ # Priklausomi charts
templates/ # Kubernetes šablonai
deployment.yaml
service.yaml
ingress.yaml
.helmignore # Failai, kurių ignoruoti
Chart.yaml failas yra jūsų chart vizitinė kortelė. Jame nurodomas pavadinimas, versija, aprašymas ir kita svarbi informacija. Versijų valdymas čia yra kritiškai svarbus – Helm naudoja semantinį versijų numeravimą (SemVer), ir tai padeda valdyti suderinamumą.
values.yaml failas yra tikroji magija. Čia apibrėžiate visas konfigūruojamas reikšmes, kurias vartotojai gali perrašyti. Pavyzdžiui, galite nustatyti numatytąjį konteinerio atvaizdą, replicas skaičių, resursų limitus ir t.t. Kai kas nors naudoja jūsų chart, jie gali pateikti savo values failą arba perrašyti atskiras reikšmes per komandinę eilutę.
Templates kataloge yra jūsų Kubernetes manifestų šablonai. Čia naudojama Go šablonų sintaksė, kuri iš pradžių gali atrodyti keistoka, bet yra labai galinga. Galite naudoti sąlyginius sakinius, ciklus, funkcijas – visa tai leidžia sukurti labai lankščius ir pakartotinai naudojamus šablonus.
Praktinis darbas su Helm: nuo įdiegimo iki deployment
Pradėkime nuo pradžių. Helm įdiegimas yra paprastas – daugumoje Linux distribucijų galite naudoti paketų valdytojus, o macOS vartotojai gali pasikliauti Homebrew. Windows vartotojams yra Chocolatey arba tiesiog galite atsisiųsti binarinį failą.
Pirmasis dalykas po įdiegimo – pridėti chart repozitoriją. Helm Hub (dabar perkeltas į Artifact Hub) turi tūkstančius paruoštų charts. Populiariausias yra Bitnami repozitorija:
helm repo add bitnami https://charts.bitnami.com/bitnami
Dabar galite ieškoti prieinamų charts:
helm search repo wordpress
Įdiegti aplikaciją yra paprasta:
helm install my-wordpress bitnami/wordpress
Bet tikrasis Helm pranašumas atsiskleidžia, kai pradedate pritaikyti diegimą. Sukurkite savo custom-values.yaml failą:
wordpressUsername: admin
wordpressPassword: superslaptazodis
service:
type: LoadBalancer
persistence:
size: 20Gi
Ir įdiekite su šiomis reikšmėmis:
helm install my-wordpress bitnami/wordpress -f custom-values.yaml
Kai reikia atnaujinti diegimą, naudokite helm upgrade. Jei kas nors nepavyko, helm rollback my-wordpress 1 grąžins jus į pirmąją versiją. Tai neįtikėtinai patogu production aplinkose, kur klaidos gali kainuoti brangiai.
Savo chart kūrimas: nuo nulio iki hero
Nors naudoti esamų charts yra puiku, tikroji galia atsiranda, kai kuriate savo. Pradėkite su:
helm create myapp
Ši komanda sukurs visą reikiamą struktūrą su pavyzdiniais failais. Dabar pažiūrėkime į tipinį deployment šabloną:
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "myapp.fullname" . }}
labels:
{{- include "myapp.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "myapp.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "myapp.selectorLabels" . | nindent 8 }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
ports:
- containerPort: {{ .Values.service.port }}
Raktiniai dalykai, į kuriuos reikia atkreipti dėmesį: {{ }} sintaksė leidžia įterpti reikšmes, include funkcija leidžia pakartotinai naudoti šablonus, o nindent užtikrina teisingą YAML formatavimą.
Vienas iš dažniausių klausimų – kaip valdyti sąlyginius diegimus. Pavyzdžiui, jei norite, kad Ingress būtų sukurtas tik kai ingress.enabled yra true:
{{- if .Values.ingress.enabled -}}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "myapp.fullname" . }}
# ... likusios specifikacijos
{{- end }}
Testuoti savo chart galite be jokio diegimo:
helm template myapp ./myapp
Ši komanda tiesiog sugeneruos YAML išvestį, kurią galite peržiūrėti. Dar geriau – naudokite helm lint, kad patikrintumėte dažniausias klaidas.
Sudėtingesni scenarijai ir best practices
Kai jau įvaldėte pagrindus, laikas pereiti prie sudėtingesnių dalykų. Vienas iš jų – priklausomybių valdymas. Jūsų aplikacija gali priklausyti nuo duomenų bazės, cache sistemos ar kitų servisų. Helm leidžia apibrėžti šias priklausomybes Chart.yaml faile:
dependencies:
- name: postgresql
version: 11.x.x
repository: https://charts.bitnami.com/bitnami
condition: postgresql.enabled
- name: redis
version: 16.x.x
repository: https://charts.bitnami.com/bitnami
condition: redis.enabled
Tada vykdote helm dependency update, ir visos priklausomybės bus atsisiųstos į charts/ katalogą.
Saugumo požiūriu, niekada nesaugokite slaptažodžių tiesiogiai values failuose. Naudokite Kubernetes Secrets arba dar geriau – integruokite su išoriniais slaptažodžių valdymo įrankiais kaip HashiCorp Vault ar AWS Secrets Manager. Galite naudoti Helm hooks, kad automatiškai sukurtumėte secrets prieš diegimą.
Hooks apskritai yra labai galingas funkcionalumas. Galite vykdyti darbus (Jobs) prieš diegimą, po diegimo, prieš ištrynimą ir t.t. Pavyzdžiui, duomenų bazės migracijos:
apiVersion: batch/v1
kind: Job
metadata:
name: {{ include "myapp.fullname" . }}-migration
annotations:
"helm.sh/hook": pre-upgrade
"helm.sh/hook-weight": "0"
"helm.sh/hook-delete-policy": hook-succeeded
Dar viena svarbi praktika – naudokite chart versijų numeravimą protingai. Kiekvieną kartą, kai keičiate chart logiką (ne tik aplikacijos versiją), didinkite chart versiją. Tai padeda sekti pokyčius ir užtikrina, kad vartotojai žino, ką gauna.
Helm ekosistema ir įrankiai, kurie palengvina gyvenimą
Helm nėra vienas – aplink jį išaugo visa ekosistema papildomų įrankių. Helmfile yra vienas iš populiariausių – jis leidžia deklaratyviai apibrėžti visus jūsų Helm releases vienoje vietoje. Tai ypač naudinga, kai turite kelias aplinkas (dev, staging, production) ir norite valdyti jas vienodai.
Helm Secrets pluginas integruoja Mozilla SOPS arba Hashicorp Vault, leidžiant saugiai saugoti slaptažodžius versijų kontrolėje. Tai sprendžia vieną iš didžiausių Helm skausmų – kaip dalintis konfigūracijomis su komanda, neatskleidžiant jautrių duomenų.
Chart Testing (ct) įrankis yra būtinas, jei kuriate viešus charts. Jis automatizuoja linting, version checking ir net gali paleisti diegimus test Kubernetes klasteriuose. Daugelis open source projektų naudoja jį CI/CD pipeline’uose.
Artifact Hub (anksčiau Helm Hub) yra centralizuota vieta rasti charts. Bet įdomu tai, kad dabar jis palaiko ne tik Helm charts, bet ir kitus Kubernetes paketus. Tai rodo, kaip Helm įtakojo platesnę ekosistemą.
GitOps praktikose Helm puikiai dera su ArgoCD ar Flux. Šie įrankiai stebi jūsų Git repozitoriją ir automatiškai sinchronizuoja Helm releases su tuo, kas apibrėžta kode. Tai užtikrina, kad jūsų klasteris visada atitinka deklaruotą būseną.
Kur Helm pasiekia savo ribas ir kas ateina toliau
Nors Helm yra fantastiškas įrankis, jis nėra tobulas. Viena didžiausių problemų – šablonų sudėtingumas. Kai charts auga, Go šablonai gali tapti sunkiai skaitomi ir prižiūrimi. Kartais jaučiasi, kad rašai programavimo kalbą YAML viduje, kas nėra idealu.
Kita problema – būsenos valdymas. Nors Helm 3 pagerino situaciją, vis dar gali kilti problemų, kai keli žmonės ar procesai bando valdyti tą patį release. Konfliktų sprendimas nėra toks elegantiškas kaip norėtųsi.
Dėl šių priežasčių atsiranda alternatyvų. Kustomize, kuris dabar integruotas į kubectl, siūlo paprastesnį požiūrį be šablonų. Jsonnet ir Cue siūlo galingesnes konfigūracijos kalbas. Pulumi ir CDK8s leidžia naudoti tikras programavimo kalbas infrastruktūros apibrėžimui.
Bet Helm išlieka populiarus ne be priežasties. Jo ekosistema yra didžiulė, dokumentacija gera, o bendruomenė aktyvi. Daugelis įmonių investavo į Helm, ir greitu metu jis niekur nedings.
Ateitis greičiausiai bus hibridinė. Matome, kaip įrankiai pradeda derinti skirtingus požiūrius – pavyzdžiui, naudoti Kustomize su Helm arba generuoti Helm charts iš aukštesnio lygio abstrakcijų. Kubernetes ekosistema bręsta, ir tai gerai.
Praktiniai patarimai iš realių projektų
Baigiant, noriu pasidalinti keliais patarimais, kurie išmokti per skaudžią patirtį. Pirma, visada naudokite chart versijų fiksavimą production aplinkose. Vietoj helm install myapp stable/myapp, naudokite helm install myapp stable/myapp --version 1.2.3. Tai apsaugo nuo netikėtų pokyčių.
Antra, dokumentuokite savo values.yaml. Komentarai šiame faile yra vienintelis būdas vartotojams suprasti, ką kiekviena reikšmė daro. Naudokite aiškius pavyzdžius ir nurodykite tipus bei galimas reikšmes.
Trečia, testuokite upgrades, ne tik šviežius diegimus. Daugelis problemų atsiranda būtent atnaujinant, ypač kai keičiasi duomenų schemos ar ConfigMaps. Naudokite helm diff pluginą, kad pamatytumėte, kas pasikeis prieš vykdydami upgrade.
Ketvirta, struktūrizuokite savo values hierarchiškai. Vietoj databaseHost, databasePort, databaseName, naudokite:
database:
host: localhost
port: 5432
name: myapp
Tai daro konfigūraciją aiškesnę ir leidžia lengviau perrašyti visą sekciją.
Penkta, naudokite named templates funkcijoms. Jei pastebite, kad kopijuojate tą patį kodą keliuose šablonuose, iškelkite jį į _helpers.tpl failą. Tai ne tik sumažina dubliavimą, bet ir palengvina priežiūrą.
Helm yra įrankis, kuris transformavo tai, kaip diegiame aplikacijas Kubernetes. Taip, jis turi savo keblumų ir mokymosi kreivė nėra visiškai lygni, bet nauda yra akivaizdi. Nesvarbu, ar diegiate paprastą web aplikaciją, ar sudėtingą mikroservisų architektūrą, Helm suteikia struktūrą ir pakartojamumą, kurio taip reikia šiuolaikinėje cloud-native aplinkoje. Pradėkite nuo paprastų dalykų, eksperimentuokite su esamais charts, ir pamažu judėkite link savo sprendimų kūrimo. Kubernetes pasaulis yra sudėtingas, bet su Helm jis tampa šiek tiek labiau valdomas.
