Helm-enhed og dens faldgruber

Helm-enhed og dens faldgruber
Typhon fragt transportkoncept, Anton Swanepoel

Mit mit navn er Dmitry Sugrobov, jeg er udvikler hos «Leroy Merlin». I denne artikel vil jeg fortælle, hvorfor Helm er vigtigt, hvordan det forenkler arbejdet med Kubernetes, hvad der er ændret i den tredje version, og hvordan man opdaterer applikationer i produktionen uden nedetid ved hjælp af det.

Dette er et resumé inspireret af et oplæg på konferencen @Kubernetes Konference by Mail.ru Cloud Solutions — hvis du ikke vil læse, så se videoen.

Afspil video

Hvorfor vi bruger Kubernetes i produktion

«Leroy Merlin» er en markedsleder inden for DIY-detailhandel i Rusland og Europa. I vores virksomhed er der mere end hundrede udviklere, 33.000 interne medarbejdere og et stort antal mennesker, der besøger hypermarkederne og hjemmesiden. For at gøre alle dem glade besluttede vi at følge de standardmetoder i branchen. Vi udvikler nye applikationer ved hjælp af mikroservicesarkitektur; for at isolere miljøer og sikre korrekt levering bruger vi containere; og til orkestrering bruger vi Kubernetes. Prisen for at bruge orkestratorer falder hastigt: på markedet stiger antallet af ingeniører, der behersker teknologien, og der kommer udbydere, der tilbyder Kubernetes som en tjeneste.

Alt, hvad Kubernetes gør, kan selvfølgelig gøres på andre måder, for eksempel ved at smide en masse scripts oveni Jenkins og docker-compose, men hvorfor gøre livet mere kompliceret, hvis der findes en klar og pålidelig løsning? Derfor valgte vi Kubernetes og har allerede brugt det i produktionen i et år. I øjeblikket har vi fireogtyve Kubernetes-klynger, den ældste af dem er over et år gammel og har omkring to hundrede pods.

Forbandelsen ved et stort antal YAML-filer i Kubernetes

For at starte en mikrotjeneste i Kubernetes skal vi oprette mindst fem YAML-filer: til Deployment, Service, Ingress, ConfigMap, Secrets — og sende dem til klyngen. Til den næste applikation skriver vi den samme pakke af YAML-filer, den tredje — endnu en, og så videre. Hvis vi multiplicerer antallet af dokumenter med antallet af miljøer, har vi allerede hundrede filer, og det er endnu ikke medregnet dynamiske miljøer.

Helm-enhed og dens faldgruber
Adam Reese, kernevedligeholder for Helm, introducerede begrebet «Udviklingscyklus i Kubernetes», som ser således ud:

  1. Copy YAML - kopier YAML-filen.
  2. Paste YAML - indsæt den.
  3. Fix Indents - ret indrykningen.
  4. Repeat - gentag.

Metoden fungerer, men det kræver, at man kopierer YAML-filer mange gange. For at ændre denne cyklus blev Helm opfundet.

Hvad er Helm

For det første er Helm — pakkehåndtering, der hjælper med at finde og installere de nødvendige programmer. For eksempel, for at installere MongoDB behøver man ikke at gå ind på den officielle hjemmeside og downloade binærfilerne, det er nok at udføre kommandoen helm install stable/mongodb.

For det andet, Helm — skabelonmotor, hjælper med at parametrisere filer. Lad os vende tilbage til situationen med YAML-filer i Kubernetes. Det er lettere at skrive den samme YAML-fil, tilføje nogle pladsholdere i den, som Helm vil indsætte værdier i. Det vil sige, at i stedet for et stort antal YAML-filer vil der være et sæt skabeloner, hvor de nødvendige værdier vil blive indsat på det rigtige tidspunkt.

For det tredje, Helm — mester i deployment. Med det kan man installere, rulle tilbage og opdatere applikationer. Lad os se, hvordan man gør det.

Helm-enhed og dens faldgruber

Sådan bruger du Helm til at deploye dine egne applikationer

Vi installerer Helm-klienten på computeren ved at følge den officielle vejledningen. Derefter vil vi oprette et sæt YAML-filer. I stedet for at angive specifikke værdier vil vi lade pladsholdere stå, som Helm i fremtiden vil udfylde med information. Sættet af disse filer kaldes en Helm Chart. I den konsolklient, der er Helm, kan det sendes på tre måder:

  • angive en mappe med skabeloner;
  • pakke det i en .tar-arkiv og henvise til det;
  • placere skabelonen i et fjernt lager og tilføje et link til lageret i Helm-klienten.

Vi har også brug for en fil med værdier — values.yaml. Data derfra vil blive indsat i skabelonen. Lad os oprette den.

Helm-enhed og dens faldgruber
I den anden version af Helm er der en ekstra serverapplikation — Tiller. Den kører uden for Kubernetes og venter på anmodninger fra Helm-klienten, og ved kaldet indsætter de nødvendige værdier i skabelonen og sender den til Kubernetes.

Helm-enhed og dens faldgruber
Helm 3 er enklere: i stedet for at behandle skabeloner på serveren, behandles informationen nu helt på siden af Helm-klienten og sendes direkte til Kubernetes API. Denne forenkling forbedrer sikkerheden for klyngen og letter udrulningsprocessen.

Hvordan fungerer det hele?

Vi kører kommandoen helm install. Lad os angive navnet på applikationsudgivelsen, give stien til values.yaml. I slutningen angiver vi lageret, hvor chartet ligger, og navnet på chartet. I eksemplet er det «lmru» og «bestchart» henholdsvis.

helm install --name bestapp --values values.yaml lmru/bestchart

Udførelse af kommandoen er kun mulig én gang, ved gentagen udførelse i stedet for installation skal der anvendes opgraderinger. For enkelhed kan man udføre kommandoen opgraderinger med en ekstra nøgle --installVed første udførelse vil Helm sende en kommando til at installere udgivelsen, og fremover vil den opdatere den.

helm upgrade --install bestapp --values values.yaml lmru/bestchart

Fallgruber ved deployment af nye versioner af applikationen med Helm

I denne del af fortællingen spiller jeg med salen i "Hvem vil være millionær?", og vi undersøger, hvordan man får Helm til at opdatere applikationens version. Se video.

Da jeg studerede Helm, blev jeg overrasket over den mærkelige opførsel, når jeg forsøgte at opdatere versionerne af de kørende applikationer. Jeg opdaterede applikationskoden, uploadede det nye billede til docker-registry, sendte en deployment-kommando – og der skete intet. Nedenfor er nogle mindre vellykkede metoder til at opdatere applikationer. Ved at undersøge hver af dem nærmere begynder man at forstå værktøjets indre mekanisme og årsagerne til denne ikke-indlysende opførsel.

Metode 1. Ikke ændre informationen siden sidste opstart

Som det siges den officielle hjemmeside Helm, "Kubernetes charts kan være store og komplekse, så Helm forsøger ikke at ændre noget unødigt". Så hvis man opdaterer latest-versionen af applikationens billede i docker registry og udfører kommandoen helm upgrade, vil der ikke ske noget. Helm vil tro, at der ikke er sket nogen ændringer, og der er ikke behov for at sende en opdateringskommando til Kubernetes.

Her og fremover er tagget latest kun vist som eksempel. Når man angiver dette tag, vil Kubernetes hver gang hente billedet fra docker registry, uanset parameteren imagePullPolicy. Brug af latest i produktion anbefales ikke og kan forårsage bivirkninger.

Metode 2. Opdatere LABEL i billedet

Som det står i samme dokumentationen, "Helm vil kun opdatere applikationen, hvis den er blevet ændret siden den sidste udgivelse". En logisk mulighed for dette ville være at opdatere LABEL-tagget i selve docker-billedet. Men Helm kigger ikke ind i applikationernes billeder og har ikke kendskab til eventuelle ændringer i dem. Derfor, når man opdaterer etiketterne i billedet, vil Helm ikke få kendskab til dem, og opdateringskommandoen til applikationen vil ikke blive sendt til Kubernetes.

Metode 3. Brug en nøgle --force

Helm-enhed og dens faldgruber
Lad os se i manualerne og finde den nødvendige nøgle. Den mest passende nøgle i betydning ser ud til at være nøglen --force. På trods af det sigende navn, adskiller adfærden sig fra det forventede. I stedet for at tvinge en opdatering af applikationen, er dens egentlige formål genopretning af en udgivelse, der er i status FAILED. Hvis denne nøgle ikke bruges, skal kommandoerne udføres sekventielt. helm delete && helm install --replace. I stedet foreslås det at bruge nøglen --force, som automatiserer sekventiel udførelse af disse kommandoer. Mere information findes i denne pull-request.. For at få Helm til endelig at opdatere versionen af applikationen, fungerer desværre denne nøgle ikke.

Måde 4. Ændring af labels direkte i Kubernetes.

Helm-enhed og dens faldgruber
Opdatering af label direkte i klyngen ved hjælp af kommandoen kubectl edit – det er en dårlig idé. Denne handling vil føre til inkonsistens mellem den kørende applikation og det, der oprindeligt blev sendt til deployment. Helm's adfærd ved deployment i dette tilfælde adskiller sig fra dets version: Helm 2 vil ikke gøre noget, mens Helm 3 vil deploye en ny version af applikationen. For at forstå årsagen, er det nødvendigt at forstå, hvordan Helm fungerer.

Hvordan fungerer Helm?

For at bestemme, om applikationen er ændret siden den sidste udgivelse, kan Helm benytte sig af:

  • den kørende applikation i Kubernetes;
  • en ny values.yaml og den aktuelle chart;
  • intern information fra Helm om udgivelserne.

For de mest nysgerrige: hvor gemmer Helm intern information om udgivelserne?Ved at køre kommandoen helm history, får vi al information om versioner installeret ved hjælp af Helm.

Helm-enhed og dens faldgruber
Der er også detaljeret information om de sendte skabeloner og værdier. Vi kan anmode om det:

Helm-enhed og dens faldgruber
I den anden version af Helm ligger disse oplysninger i den samme namespace, hvor Tiller kører (standard er kube-system), i en ConfigMap mærket med labelen «OWNER=TILLER»:

Helm-enhed og dens faldgruber
I takt med at den tredje version af Helm kom frem, blev informationen flyttet til hemmeligheder, og i samme namespace, hvor applikationen kører. Dette gjorde det muligt at køre flere applikationer samtidigt i forskellige namespaces med det samme navn på udgivelsen. I den anden version var dette en stor hovedpine, når namespaces er isolerede, men kan påvirke hinanden.

Helm-enhed og dens faldgruber

Den anden Helm, når den forsøger at forstå, om der er behov for en opdatering, bruger kun to kilder til information: det, der blev givet nu, og den interne information om udgivelserne, som ligger i ConfigMap.

Helm-enhed og dens faldgruber
Den tredje Helm bruger en three-way merge-strategi: ud over den information, der tages i betragtning, overvejer den også applikationen, der kører lige nu i Kubernetes.

Helm-enhed og dens faldgruber
Af denne grund vil den gamle version af Helm ikke gøre noget, da den ikke tager hensyn til informationen om applikationen i klyngen, mens Helm 3 vil modtage ændringerne og sende den nye applikation til deployment.

Metode 5. Brug nøgle —recreate-pods

Med nøglen --recreate-pods kan man opnå, hvad der oprindeligt var meningen med nøglen --force. Containerne vil blive genstartet, og ifølge politikken imagePullPolicy: Always for tagget latest (dette er nævnt tidligere), vil Kubernetes downloade og starte den nye version af billedet. Det vil ikke ske på den bedste måde: uden at tage hensyn til StrategyType for deployment, vil det skarpt slukke for alle gamle instanser af applikationen og begynde at starte nye. Under genstarten vil systemet ikke fungere, og brugerne vil lide.

I selve Kubernetes eksisterede der også et lignende problem i lang tid. Og nu, fire år efter åbningen Problem, er problemet blevet løst, og fra version 1.15 af Kubernetes er der mulighed for rolling-restart af pods.

Helm slukker simpelthen for alle applikationer og starter nye containere ved siden af. I produktionen kan man ikke gøre det, da det vil forårsage nedetid for applikationen. Dette skal kun gøres for udviklingsformål, og kan kun udføres i stage-miljøer.

Hvordan opdaterer man applikationsversionen ved hjælp af Helm?

Vi vil ændre værdierne, der sendes til Helm. Som regel er dette værdier, der indsættes i stedet for billede-tagget. I tilfælde af latest, som ofte bruges til ikke-produktive miljøer, fungerer annotationen, som er værdifuld for Helm, men ubrugelig for Kubernetes, som et signal til opdatering af applikationen. Muligheder for at udfylde annoteringsværdien:

  1. Tilfældig værdi ved hjælp af den standardfunktion — {{ randAlphaNum 6 }}.
    Der er et nuanceret punkt: efter hver deployment ved hjælp af chart med en sådan variabel vil annoteringsværdien være unik, og Helm vil tro, at der er ændringer. Dette betyder, at vi altid vil genstarte applikationen, selvom vi ikke har ændret dens version. Det er ikke kritisk, da der ikke vil være nedetid, men det er stadig ubehageligt.
  2. Indsætte den nuværende dato og tid — {{ .Release.Date }}.
    Varianten ligner en tilfældig værdi med en konstant unik variabel.
  3. En mere korrekt måde er at bruge kontrolsummer. Dette er SHA for billedet eller SHA for den seneste commit i git — {{ .Values.sha }}.
    De skal tælles og sendes til Helm-klienten på den kaldende side, for eksempel i Jenkins. Hvis applikationen ændres, ændres kontrolsummen også. Derfor vil Helm kun opdatere applikationen, når det er nødvendigt.

Lad os opsummere vores forsøg

  • Helm foretrækker at lave ændringer på den mindst invasive måde, så enhver ændring på niveauet for applikationsbilledet i Docker Registry fører ikke til en opdatering: efter udførelsen af kommandoen vil intet ske.
  • Nøgle --force bruger til at gendanne problematiske udgivelser og er ikke relateret til en tvungen opdatering.
  • Nøgle --recreate-pods tvinger applikationer til at opdatere, men gør det på en vildgående måde: den slukker brat for alle containere. Dette vil skade brugerne, og det bør ikke gøres i produktion.
  • At foretage ændringer direkte i Kubernetes-klusteret ved hjælp af kommandoen kubectl edit skal undgås: vi vil bryde konsistens, og adfærden vil variere afhængigt af Helm-versionen.
  • Med den nye version af Helm er der opstået mange nuancer. Issues i Helm-repositoriet er beskrevet i et letforståeligt sprog, og de vil hjælpe med at forstå detaljerne.
  • At tilføje en ændret annotation til chartet vil gøre det mere fleksibelt. Dette vil muliggøre korrekt udrulning af applikationen uden nedetid.

En tanke fra kategorien 'verdensfred', der fungerer i alle livets områder: læs brugsanvisningen inden brug, ikke efter. Kun ved at have fuld information vil det være muligt at bygge pålidelige systemer og gøre brugerne glade.

Andre links om emnet:

  1. Introduktion til Helm 3
  2. Den officielle Helm-hjemmeside
  3. Helm-repositoriet på GitHub
  4. 25 nyttige Kubernetes-værktøjer: udrulning og administration

Denne præsentation blev første gang præsenteret ved @Kubernetes Konference af Mail.ru Cloud Solutions. Se en video andre præsentationer og tilmeld dig nyhedsbreve om arrangementer på Telegram Omkring Kubernetes i Mail.ru Group.

Kilde: habr.com

Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere 🔥 Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere | ProHoster