Helm-apparaat en de valkuilen ervan

Helm-apparaat en de valkuilen ervan
Typhon vrachtvervoerder concept, Anton Swanepoel

Mijn naam is Dmitry Sugrobov, ik ben ontwikkelaar bij ‘Leroy Merlin’. In dit artikel zal ik uitleggen waarom Helm nodig is, hoe het het werk met Kubernetes vereenvoudigt, wat er is veranderd in de derde versie en hoe je met zijn hulp applicaties in productie kunt bijwerken zonder downtime.

Dit is een samenvatting op basis van een presentatie op de conferentie @Kubernetes Conferentie by Mail.ru Cloud Solutions — als je niet wilt lezen, bekijk dan de video.

Video afspelen

Waarom we Kubernetes in productie gebruiken

‘Leroy Merlin’ is de marktleider in de DIY-retailsector in Rusland en Europa. Ons bedrijf heeft meer dan honderd ontwikkelaars, 33.000 interne medewerkers en een enorm aantal mensen die onze hypermarkten en website bezoeken. Om iedereen gelukkig te maken, hebben we besloten standaardbenaderingen in de industrie te volgen. We ontwikkelen nieuwe applicaties met gebruik van microservicesarchitectuur; voor isolatie van omgevingen en correcte levering maken we gebruik van containers; en voor orkestratie gebruiken we Kubernetes. De kosten van het gebruik van orkestrators dalen snel: het aantal ingenieurs dat deze technologie beheerst, groeit, en er komen providers op de markt die Kubernetes als service aanbieden.

Alles wat Kubernetes doet, kan natuurlijk op andere manieren worden gedaan, bijvoorbeeld door een of andere Jenkins en docker-compose vol te stoppen met scripts, maar waarom het leven moeilijker maken als er een kant-en-klaar en betrouwbaar oplossing is? Daarom zijn we naar Kubernetes gegaan en gebruiken het nu al een jaar in productie. Op dit moment hebben we vierentwintig Kubernetes-clusters, waarvan de oudste meer dan een jaar oud is en waarin ongeveer tweehonderd pods draaien.

De vloek van het grote aantal YAML-bestanden in Kubernetes

Om een microservice in Kubernetes te starten, creëren we minstens vijf YAML-bestanden: voor Deployment, Service, Ingress, ConfigMap, Secrets — en we sturen deze naar het cluster. Voor de volgende applicatie schrijven we hetzelfde pakket aan YAML-bestanden, voor de derde weer een set en zo verder. Het aantal documenten vermenigvuldigd met het aantal omgevingen leidt al snel tot honderden bestanden, en dit zonder rekening te houden met dynamische omgevingen.

Helm-apparaat en de valkuilen ervan
Adam Reese, core maintainer van Helm, introduceerde het concept ‘De ontwikkelingscyclus in Kubernetes’, die er als volgt uitziet:

  1. Kopieer YAML — kopieer het YAML-bestand.
  2. Plak YAML — plak het.
  3. Herstel inspringingen — corrigeer de inspringingen.
  4. Herhaal — herhaal opnieuw.

De methode werkt, maar je moet vaak YAML-bestanden kopiëren. Om deze cyclus te veranderen, is Helm bedacht.

Wat is Helm

Ten eerste, Helm — pakketbeheerder, die helpt om de juiste programma's te vinden en te installeren. Voor de installatie van bijvoorbeeld MongoDB is het niet nodig om naar de officiële website te gaan en de binaries te downloaden, het volstaat om de opdracht uit te voeren helm install stable/mongodb.

Ten tweede, Helm — sjabloon motor, helpt om bestanden te parametriseren. Laten we teruggaan naar de situatie met YAML-bestanden in Kubernetes. Het is eenvoudiger om hetzelfde YAML-bestand te schrijven, enkele placeholders toe te voegen, waarin Helm waarden zal invullen. Dit betekent dat in plaats van een grote set YAML-bestanden er een set sjablonen is, waarin op het juiste moment de juiste waarden worden ingevuld.

Ten derde, Helm — de meester van implementatie. Hiermee kunnen applicaties worden geïnstalleerd, teruggedraaid en geüpdatet. Laten we eens kijken hoe dit werkt.

Helm-apparaat en de valkuilen ervan

Hoe Helm gebruiken voor het implementeren van eigen applicaties

We installeren de Helm-client op de computer, volgens de officiële handleiding,. Vervolgens maken we een set YAML-bestanden aan. In plaats van specifieke waarden op te geven, laten we placeholders achter die Helm in de toekomst met informatie zal vullen. Deze set bestanden wordt een Helm chart genoemd. Deze kunnen op drie manieren naar de Helm-consoleclient worden gestuurd:

  • geef de map met sjablonen op;
  • verpak het in een .tar-archief en wijs ernaar;
  • plaats het sjabloon in een externe repository en voeg een link naar de repository toe in de Helm-client.

Daarnaast is er een bestand met waarden nodig — values.yaml. Gegevens daaruit worden in de sjabloon ingevuld. Laten we dat ook maken.

Helm-apparaat en de valkuilen ervan
In de tweede versie van Helm is er een aanvullende serverapplicatie — Tiller. Het hangt buiten Kubernetes en wacht op verzoeken van de Helm-client, en bij een oproep vult het de benodigde waarden in de sjabloon en stuurt dit naar Kubernetes.

Helm-apparaat en de valkuilen ervan
Helm 3 is eenvoudiger: in plaats van sjablonen op de server te verwerken, wordt de informatie nu volledig aan de kant van de Helm-client verwerkt en direct naar de Kubernetes API gestuurd. Deze vereenvoudiging verhoogt de veiligheid van de cluster en vergemakkelijkt de uitrol.

Hoe dit alles werkt

We voeren de opdracht uit helm install. We geven de naam van de applicatierelease op, geven het pad naar values.yaml op. Tot slot geven we de repository op waar de chart zich bevindt en de naam van de chart. In dit voorbeeld zijn dat «lmru» en «bestchart» respectievelijk.

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

De opdracht kan slechts één keer worden uitgevoerd, bij herhaalde uitvoering in plaats van install moet upgrade. Voor de eenvoud kan in plaats van twee opdrachten de opdracht upgrade met een extra sleutel --installBij de eerste uitvoering zal Helm een commando verzenden om de release te installeren, en zal het in de toekomst updates uitvoeren.

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

Valstrikken bij het implementeren van nieuwe versies van applicaties met Helm

Op dit punt in het verhaal speel ik met de zaal in 'Wie wil een miljoenair worden', en we ontdekken hoe we Helm kunnen laten upgraden naar de nieuwe versie van de applicatie. Bekijk video.

Toen ik de werking van Helm bestudeerde, was ik verrast door het vreemde gedrag bij het proberen om versies van draaiende applicaties te upgraden. De code van de applicatie was bijgewerkt, het nieuwe beeld was naar de Docker Registry geüpload, ik verzond de implementatieopdracht – en er gebeurde niets. Hieronder staan een paar minder succesvolle manieren om applicaties te upgraden. Door elk van hen nader te bestuderen, begin je de interne werking van de tool en de redenen voor dit niet-evidente gedrag te begrijpen.

Methode 1. Geen informatie wijzigen sinds de laatste uitvoering

Zoals het zegt officiële website Helm, "Kubernetes charts kunnen groot en complex zijn, daarom probeert Helm niet onnodig iets te veranderen." Dus, als je de laatste versie van de applicatie image in de Docker Registry bijwerkt en het commando uitvoert helm upgrade, zal er niets gebeuren. Helm denkt dat er niets is veranderd en er hoeft geen commando naar Kubernetes gestuurd te worden om de applicatie bij te werken.

Hier en verder wordt de tag latest uitsluitend als voorbeeld weergegeven. Bij het opgeven van deze tag zal Kubernetes elke keer de image van de Docker Registry downloaden, ongeacht de imagePullPolicy. Het gebruik van latest in productie is ongewenst en kan bijwerkingen veroorzaken.

Methode 2. LABEL in de image bijwerken

Zoals vermeld in hetzelfde de documentatie, "Helm zal de applicatie alleen bijwerken als deze is veranderd sinds de laatste release." Een logische optie hiervoor zou zijn om het LABEL in de Docker image bij te werken. Echter, Helm kijkt niet naar de applicatie-images en heeft geen idee van eventuele veranderingen daarin. Daarom, bij het bijwerken van labels in de image, zal Helm daar niet van op de hoogte zijn, en zal er geen update-opdracht naar Kubernetes worden verzonden.

Methode 3. Een sleutel gebruiken --force

Helm-apparaat en de valkuilen ervan
Laten we de handleidingen raadplegen en naar de juiste sleutel zoeken. De sleutel die het beste past bij de context is --force. Ondanks de voor de hand liggende naam, wijkt het gedrag af van wat men verwacht. In plaats van een geforceerde update van de applicatie, is de werkelijke functie het herstel van een release die zich in de status FAILED bevindt. Als deze vlag niet wordt gebruikt, moeten de commando's opeenvolgend worden uitgevoerd. helm delete && helm install --replace. In plaats daarvan wordt aanbevolen deze vlag te gebruiken --force, die de opeenvolgende uitvoering van deze commando's automatiseert. Meer informatie hierover is te vinden in deze pull request.. Om Helm te instrueren de versie van de applicatie daadwerkelijk bij te werken, is deze vlag helaas niet geschikt.

Methode 4. Labels rechtstreeks in Kubernetes wijzigen

Helm-apparaat en de valkuilen ervan
Het direct updaten van een label in de cluster met behulp van het commando kubectl edit — is geen goed idee. Deze actie zal leiden tot inconsistentie in de informatie tussen de actieve applicatie en wat aanvankelijk is verzonden voor de deployment. Het gedrag van Helm tijdens de deployment verschilt in dit geval van zijn versie: Helm 2 zal niets doen, terwijl Helm 3 een nieuwe versie van de applicatie zal deployen. Om de reden hiervoor te begrijpen, moet men weten hoe Helm werkt.

Hoe Helm werkt

Om te bepalen of de applicatie sinds de laatste release is gewijzigd, kan Helm gebruikmaken van:

  • de actieve applicatie in Kubernetes;
  • een nieuwe values.yaml en de actuele chart;
  • interne informatie van Helm over de releases.

Voor de nieuwsgierigen: waar slaat Helm interne informatie over releases op?Door het commando helm history, krijgen we alle informatie over de versies die met Helm zijn geïnstalleerd.

Helm-apparaat en de valkuilen ervan
Er is ook gedetailleerde informatie over de verzonden sjablonen en waarden. We kunnen deze opvragen:

Helm-apparaat en de valkuilen ervan
In de tweede versie van Helm bevindt deze informatie zich in dezelfde namespace waar Tiller draait (standaard — kube-system), in een ConfigMap gemarkeerd met het label "OWNER=TILLER":

Helm-apparaat en de valkuilen ervan
Met de komst van de derde versie van Helm is de informatie verhuisd naar geheimen, en wel naar dezelfde namespace waar de applicatie draait. Dit maakt het mogelijk om meerdere applicaties met dezelfde naam voor een release tegelijk in verschillende namespaces uit te voeren. In de tweede versie was dit een grote hoofdpijn, omdat namespaces geïsoleerd zijn, maar invloed op elkaar kunnen hebben.

Helm-apparaat en de valkuilen ervan

In de tweede Helm, wanneer hij probeert te begrijpen of er een update nodig is, gebruikt hij alleen twee informatiebronnen: wat hem nu is verstrekt, en de interne informatie over de releases die in de ConfigMap is opgeslagen.

Helm-apparaat en de valkuilen ervan
De derde Helm gebruikt een driewegsamenvoegstrategie: naast de bestaande informatie houdt hij ook rekening met de applicatie die momenteel draait in Kubernetes.

Helm-apparaat en de valkuilen ervan
Om deze reden zal de oude versie van Helm niets doen, omdat deze geen informatie over de applicatie in de cluster meeneemt, terwijl Helm 3 de wijzigingen zal ontvangen en de nieuwe applicatie zal implementeren.

Methode 5. Gebruik de sleutel —recreate-pods

Met de sleutel --recreate-pods kan worden bereikt wat oorspronkelijk met de sleutel bedoeld was. --forceContainers worden opnieuw gestart en, volgens het beleid imagePullPolicy: Always voor de tag latest (zie de voetnoot hierboven), zal Kubernetes de nieuwe versie van de afbeelding downloaden en starten. Dit zal echter niet op de beste manier gebeuren: zonder rekening te houden met StrategyType van de uitrol, worden alle oude instanties van de applicatie abrupt uitgeschakeld en zullen nieuwe worden gestart. Tijdens de herstart zal het systeem niet functioneren en zullen gebruikers hinder ondervinden.

In Kubernetes bestond een vergelijkbaar probleem ook een lange tijd. En nu, vier jaar na de ontdekking Probleem, is het probleem opgelost en vanaf versie 1.15 van Kubernetes is het mogelijk om een rolling-restart van pods uit te voeren.

Helm schakelt gewoon alle applicaties uit en start nieuwe containers daarnaast. Dit mag niet in productie worden gedaan om downtime van de applicatie te vermijden. Dit moet alleen worden gedaan voor ontwikkelingsdoeleinden en mag alleen in stage-omgevingen worden uitgevoerd.

Hoe update je de versie van de applicatie met Helm?

We zullen waarden wijzigen die naar Helm worden verzonden. Dit zijn meestal waarden die vervangen worden voor de tag van de afbeelding. In het geval van latest, dat vaak wordt gebruikt voor onproductieve omgevingen, fungeert de annotatie als wijzigbare informatie, wat nutteloos is voor Kubernetes maar een signaal naar Helm zal zijn dat de applicatie moet worden bijgewerkt. Mogelijke waarden voor de annotatie zijn:

  1. Willekeurige waarde met behulp van de standaardfunctie — {{ randAlphaNum 6 }}.
    Er is een nuance: na elke implementatie met behulp van een chart met deze variabele, zal de waarde van de annotatie uniek zijn, en Helm zal aannemen dat er veranderingen zijn. Dit betekent dat we de applicatie altijd opnieuw zullen starten, zelfs als we de versie niet hebben veranderd. Dit is niet kritiek, omdat er geen downtime zal zijn, maar het is toch vervelend.
  2. De huidige datum en tijd invoegen — {{ .Release.Date }}.
    Deze optie is vergelijkbaar met een willekeurige waarde met een constant unieke variabele.
  3. Een juiste manier is om te gebruiken controleer eenheden. Dit is de SHA van het beeld of de SHA van de laatste commit in git — {{ .Values.sha }}.
    Deze moeten worden berekend en naar de Helm-client aan de oproepzijde worden verzonden, bijvoorbeeld in Jenkins. Als de applicatie verandert, verandert de controle-eenheid ook. Dit betekent dat Helm de applicatie alleen zal bijwerken wanneer dat nodig is.

Laten we onze pogingen samenvatten

  • Helm brengt veranderingen op de minst ingrijpende manier aan, zodat elke wijziging op het niveau van de applicatie-beeld in de Docker Registry niet leidt tot een update: na het uitvoeren van de opdracht gebeurt er niets.
  • Sleutel --force wordt gebruikt om probleemrelease te herstellen en is niet gerelateerd aan gedwongen updates.
  • Sleutel --recreate-pods dwingt de applicaties bij te werken, maar doet dit op een destructieve manier: het schakelt alle containers abrupt uit. Dit zal de gebruikers schaden; zo moet je niet in productie omgaan.
  • Wijzigingen rechtstreeks in de Kubernetes-cluster aanbrengen met de opdracht kubectl edit is niet nodig: we verstoren de consistentie en het gedrag varieert afhankelijk van de versie van Helm.
  • Met de uitgave van de nieuwe versie van Helm zijn er veel nuances ontstaan. Problemen in de Helm-repository zijn in begrijpelijke taal beschreven en zullen helpen de details te begrijpen.
  • Het toevoegen van een wijzigbare annotatie aan de chart maakt deze flexibeler. Hierdoor kan de applicatie correct worden uitgerold zonder downtime.

Een gedachte uit de categorie 'wereldwijde vrede', die in alle levenssferen werkt: lees de handleiding voor gebruik, niet erna. Alleen met volledige informatie kun je betrouwbare systemen bouwen en gebruikers gelukkig maken.

Andere links over het onderwerp:

  1. Introductie tot Helm 3
  2. Officiële site van Helm
  3. Helm-repository op GitHub
  4. 25 nuttige Kubernetes-tools: implementatie en beheer

Deze presentatie werd voor het eerst gegeven op @Kubernetes Conferentie door Mail.ru Cloud Solutions. Bekijk video's andere presentaties en abonneer je op evenementaankondigingen in Telegram Rondom Kubernetes bij Mail.ru Group.

Bron: habr.com

Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers 🔥 Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers | ProHoster