Helm-enheten och dess fallgropar

Helm-enheten och dess fallgropar
Typhon frakt dumper koncept, Anton Swanepoel

Jag heter Dmitry Sugrobov, jag är utvecklare på Leroy Merlin. I den här artikeln ska jag berätta varför Helm behövs, hur det förenklar arbetet med Kubernetes, vad som har ändrats i den tredje versionen och hur man använder det för att uppdatera applikationer i produktion utan stillestånd.

Detta är en sammanfattning baserad på ett tal på en konferens @Kubernetes konferens by Mail.ru molnlösningar – om du inte vill läsa, titta på videon.

Varför vi använder Kubernetes i produktionen

Leroy Merlin är ledande på DIY-marknaden i Ryssland och Europa. Vårt företag har mer än hundra utvecklare, 33 000 interna anställda och ett stort antal människor som besöker stormarknader och webbplatsen. För att göra dem alla nöjda bestämde vi oss för att följa branschstandardmetoder. Utveckla nya applikationer med hjälp av mikrotjänstarkitektur; använda behållare för att isolera miljöer och säkerställa korrekt leverans; och använd Kubernetes för orkestrering. Priset för att använda orkestratorer blir snabbt billigare: antalet ingenjörer som är skickliga i tekniken växer på marknaden, och leverantörer dyker upp som erbjuder Kubernetes som en tjänst.

Allt som Kubernetes gör går naturligtvis att göra på andra sätt, till exempel genom att täcka några Jenkins och docker-komponera med skript, men varför komplicera livet om det finns en färdig och pålitlig lösning? Det var därför vi kom till Kubernetes och har använt det i produktionen i ett år nu. Vi har för närvarande tjugofyra Kubernetes-kluster, varav den äldsta är mer än ett år gammal, med cirka tvåhundra baljor.

Förbannelsen av stora YAML-filer i Kubernetes

För att lansera en mikrotjänst i Kubernetes kommer vi att skapa minst fem YAML-filer: för Deployment, Service, Ingress, ConfigMap, Secrets - och skicka dem till klustret. För nästa ansökan kommer vi att skriva samma paket med ställningar, med den tredje kommer vi att skriva en annan, och så vidare. Om vi ​​multiplicerar antalet dokument med antalet miljöer kommer vi redan att få hundratals filer, och detta tar ännu inte hänsyn till dynamiska miljöer.

Helm-enheten och dess fallgropar
Adam Reese, kärnunderhållare av Helm, introducerade konceptet "Utvecklingscykel i Kubernetes", som ser ut så här:

  1. Kopiera YAML - kopiera en YAML-fil.
  2. Klistra in YAML - klistra in det.
  3. Fixa indrag - fixa indrag.
  4. Upprepa - upprepa igen.

Alternativet fungerar, men du måste kopiera YAML-filerna många gånger. För att ändra denna cykel uppfanns Helm.

Vad är Helm

För det första, Helm - pakethanterare, som hjälper dig att hitta och installera de program du behöver. För att installera till exempel MongoDB behöver du inte gå till den officiella webbplatsen och ladda ner binärer, kör bara kommandot helm install stable/mongodb.

För det andra, Helm - mallmotor, hjälper till att parametrisera filer. Låt oss återgå till situationen med YAML-filer i Kubernetes. Det är lättare att skriva samma YAML-fil, lägga till några platshållare i den, där Helm kommer att ersätta värdena. Det vill säga, istället för en stor uppsättning ställningar, kommer det att finnas en uppsättning mallar där de nödvändiga värdena kommer att ersättas vid rätt tidpunkt.

För det tredje, Helm - utplaceringsmästare. Med den kan du installera, återställa och uppdatera applikationer. Låt oss ta reda på hur man gör detta.

Helm-enheten och dess fallgropar

Hur du använder Helm för att distribuera dina egna applikationer

Låt oss installera Helm-klienten på din dator, efter den officiella Avstånd. Därefter skapar vi en uppsättning YAML-filer. Istället för att ange specifika värden kommer vi att lämna platshållare, som Helm kommer att fylla med information i framtiden. En uppsättning sådana filer kallas ett Helm-diagram. Det kan skickas till Helm-konsolklienten på tre sätt:

  • ange en mapp med mallar;
  • packa arkivet i en .tar och peka på det;
  • lägg mallen i ett fjärrlager och lägg till en länk till förvaret i Helm-klienten.

Du behöver också en fil med värden - values.yaml. Data därifrån kommer att infogas i mallen. Låt oss skapa det också.

Helm-enheten och dess fallgropar
Den andra versionen av Helm har en extra serverapplikation - Tiller. Den hänger utanför Kubernetes och väntar på förfrågningar från Helm-klienten, och när den anropas ersätter den de nödvändiga värdena i mallen och skickar den till Kubernetes.

Helm-enheten och dess fallgropar
Helm 3 är enklare: istället för att bearbeta mallar på servern, bearbetas information nu helt på Helm-klientsidan och skickas direkt till Kubernetes API. Denna förenkling förbättrar klustersäkerheten och underlättar utbyggnadsschemat.

Hur fungerar det hela

Kör kommandot helm install. Låt oss ange namnet på programversionen och ge sökvägen till values.yaml. I slutet kommer vi att ange arkivet där diagrammet finns och namnet på diagrammet. I exemplet är dessa "lmru" respektive "bestchart".

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

Kommandot kan endast utföras en gång, när det körs igen istället install behöver använda upgrade. För enkelhetens skull kan du köra kommandot istället för två kommandon upgrade med extra nyckel --install. När den körs för första gången kommer Helm att skicka ett kommando för att installera versionen och kommer att uppdatera den i framtiden.

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

Fallgropar med att distribuera nya versioner av en applikation med Helm

Vid det här laget i berättelsen spelar jag Vem vill bli miljonär med publiken, och vi håller på att ta reda på hur vi ska få Helm att uppdatera versionen av appen. Titta på videon.

När jag lärde mig hur Helm fungerar blev jag överraskad av konstigt beteende när jag försökte uppdatera versioner av program som körs. Jag uppdaterade applikationskoden, laddade upp en ny bild till Docker-registret, skickade distributionskommandot - och ingenting hände. Nedan finns några inte helt framgångsrika sätt att uppdatera applikationer. Genom att studera var och en av dem mer i detalj börjar du förstå instrumentets interna struktur och orsakerna till detta inte uppenbara beteende.

Metod 1. Ändra inte information sedan den senaste lanseringen

Som man brukar säga officiell hemsida Helm, "Kubernetes-diagram kan vara stora och komplexa, så Helm försöker att inte röra något för mycket." Därför, om du uppdaterar den senaste versionen av programbilden i docker-registret och kör kommandot helm upgrade, då händer ingenting. Helm kommer att tro att ingenting har förändrats och det finns inget behov av att skicka ett kommando till Kubernetes för att uppdatera applikationen.

Här och nedan visas den senaste taggen endast som ett exempel. När du anger den här taggen kommer Kubernetes att ladda ner bilden från docker-registret varje gång, oavsett parametern imagePullPolicy. Att använda det senaste inom produktionen är oönskat och orsakar biverkningar.

Metod 2. Uppdatera LABEL i bilden

Som skrivet i samma dokumentation, "Helm kommer bara att uppdatera ett program om det har ändrats sedan den senaste utgåvan." Ett logiskt alternativ för detta verkar vara att uppdatera ETIKETTEN i själva docker-bilden. Helm tittar dock inte på applikationsbilderna och har ingen aning om några ändringar av dem. Följaktligen, när du uppdaterar etiketter i bilden, kommer Helm inte att veta om dem, och kommandot för programuppdatering kommer inte att skickas till Kubernetes.

Metod 3: Använd en nyckel --force

Helm-enheten och dess fallgropar
Låt oss gå till manualerna och leta efter den nödvändiga nyckeln. Nyckeln är mest vettig --force. Trots det uppenbara namnet är beteendet annorlunda än förväntat. Istället för att tvinga fram en programuppdatering är dess verkliga syfte att återställa en version som har statusen MISLYCKAD. Om du inte använder den här nyckeln måste du utföra kommandona sekventiellt helm delete && helm install --replace. Det rekommenderas att använda nyckeln istället --force, som automatiserar sekventiell exekvering av dessa kommandon. Mer information i detta pull begäran. För att säga åt Helm att uppdatera applikationsversionen fungerar tyvärr inte denna nyckel.

Metod 4. Ändra etiketter direkt i Kubernetes

Helm-enheten och dess fallgropar
Uppdaterar etikett direkt i klustret med kommandot kubectl edit - dålig idé. Den här åtgärden kommer att leda till inkonsekvens av information mellan det körande programmet och det som ursprungligen skickades för distribution. Beteendet för Helm under distributionen i det här fallet skiljer sig från dess version: Helm 2 kommer inte att göra någonting, och Helm 3 kommer att distribuera den nya versionen av applikationen. För att förstå varför måste du förstå hur Helm fungerar.

Hur fungerar Helm?

För att avgöra om en applikation har ändrats sedan den senaste versionen kan Helm använda:

  • kör applikation i Kubernetes;
  • nya värden.yaml och aktuellt diagram;
  • Helms interna releaseinformation.

För de mer nyfikna: var lagrar Helm intern information om releaser?Genom att utföra kommandot helm history, kommer vi att få all information om de versioner som installerats med hjälp av Helm.

Helm-enheten och dess fallgropar
Det finns också detaljerad information om de skickade mallarna och värdena. Vi kan begära det:

Helm-enheten och dess fallgropar
I den andra versionen av Helm finns denna information i samma namnområde där Tiller körs (kube-system som standard), i ConfigMap, märkt med etiketten "OWNER=TILLER":

Helm-enheten och dess fallgropar
När den tredje versionen av Helm dök upp flyttade informationen till hemligheter och till samma namnområde där programmet kördes. Tack vare detta blev det möjligt att köra flera applikationer samtidigt i olika namnutrymmen med samma releasenamn. I den andra versionen var det en allvarlig huvudvärk när namnutrymmen är isolerade men kan påverka varandra.

Helm-enheten och dess fallgropar

Det andra rodret, när man försöker förstå om en uppdatering behövs, använder endast två informationskällor: vad som ges till det nu och intern information om utgåvor, som ligger i ConfigMap.

Helm-enheten och dess fallgropar
Den tredje Helm använder en trevägs sammanslagningsstrategi: förutom den informationen tar den även hänsyn till applikationen som körs just nu i Kubernetes.

Helm-enheten och dess fallgropar
Av denna anledning kommer den gamla versionen av Helm inte att göra någonting, eftersom den inte tar hänsyn till applikationsinformationen i klustret, men Helm 3 kommer att ta emot ändringarna och skicka den nya applikationen för distribution.

Metod 5. Använd omkopplaren --recreate-pods

Med en nyckel --recreate-pods du kan uppnå det du ursprungligen planerade att uppnå med nyckeln --force. Behållarna kommer att starta om och enligt imagePullPolicy: Always policy för den senaste taggen (mer om detta i fotnoten ovan), kommer Kubernetes att ladda ner och lansera en ny version av bilden. Detta kommer inte att göras på bästa sätt: utan att ta hänsyn till StrategyType för distribution, kommer det abrupt att stänga av alla gamla applikationsinstanser och börja lansera nya. Under omstarten kommer systemet inte att fungera, användarna kommer att drabbas.

I självaste Kubernetes fanns också ett liknande problem under lång tid. Och nu, 4 år efter öppningen Fråga, problemet har åtgärdats, och från och med version 1.15 av Kubernetes visas möjligheten att starta om pods.

Helm stänger helt enkelt av alla applikationer och lanserar nya containrar i närheten. Du kan inte göra detta i produktionen för att inte orsaka driftstopp i applikationen. Detta behövs endast för utvecklingsbehov och kan endast utföras i scenmiljöer.

Hur uppdaterar man applikationsversionen med Helm?

Vi kommer att ändra värdena som skickas till Helm. Vanligtvis är dessa värden som ersätts i stället för bildtaggen. När det gäller senaste, som ofta används för improduktiva miljöer, är den föränderliga informationen en anteckning, som är värdelös för Kubernetes själv, och för Helm kommer den att fungera som en signal för behovet av att uppdatera applikationen. Alternativ för att fylla i anteckningsvärdet:

  1. Slumpmässigt värde använder standardfunktionen - {{ randAlphaNum 6 }}.
    Det finns en varning: efter varje distribution med ett diagram med en sådan variabel kommer anteckningsvärdet att vara unikt, och Helm kommer att anta att det finns ändringar. Det visar sig att vi alltid kommer att starta om programmet, även om vi inte har ändrat dess version. Detta är inte kritiskt, eftersom det inte kommer att finnas några stillestånd, men det är fortfarande obehagligt.
  2. Klistra in ström datum och tid - {{ .Release.Date }}.
    En variant liknar ett slumpmässigt värde med en permanent unik variabel.
  3. Ett mer korrekt sätt är att använda kontrollsummor. Detta är SHA för bilden eller SHA för den sista commit i git - {{ .Values.sha }}.
    De kommer att behöva räknas och skickas till Helm-klienten på den anropande sidan, till exempel i Jenkins. Om applikationen har ändrats kommer kontrollsumman att ändras. Därför kommer Helm bara att uppdatera applikationen när det behövs.

Låt oss sammanfatta våra försök

  • Helm gör ändringar på det minst invasiva sättet, så alla ändringar på programbildsnivå i Docker Registry kommer inte att resultera i en uppdatering: ingenting kommer att hända efter att kommandot har körts.
  • nyckel --force används för att återställa problematiska versioner och är inte associerad med påtvingade uppdateringar.
  • nyckel --recreate-pods kommer att kraftfullt uppdatera applikationer, men kommer att göra det på ett vandaliskt sätt: det kommer plötsligt att stänga av alla behållare. Användare kommer att drabbas av detta; du bör inte göra detta i produktionen.
  • Gör ändringar direkt i Kubernetes-klustret med kommandot kubectl edit gör det inte: vi bryter konsistensen och beteendet kommer att variera beroende på versionen av Helm.
  • Med lanseringen av den nya versionen av Helm har många nyanser dykt upp. Problem i Helm-förvaret beskrivs i ett tydligt språk, de hjälper dig att förstå detaljerna.
  • Om du lägger till en redigerbar anteckning till ett diagram blir det mer flexibelt. Detta gör att du kan rulla ut applikationen korrekt, utan stillestånd.

En "världsfred"-tanke som fungerar på alla områden i livet: läs instruktionerna före användning, inte efter. Endast med fullständig information kommer det att vara möjligt att bygga tillförlitliga system och göra användarna nöjda.

Andra relaterade länkar:

  1. Bekantskap med Helm 3
  2. Helms officiella hemsida
  3. Helm repository på GitHub
  4. 25 Användbara Kubernetes-verktyg: Driftsättning och hantering

Denna rapport presenterades först kl @Kubernetes konferens av Mail.ru Cloud Solutions. Se video andra föreställningar och prenumerera på evenemangsmeddelanden på Telegram Runt Kubernetes på Mail.ru Group.

Källa: will.com

Lägg en kommentar