Helm-struktur och dess fallgropar

Helm-struktur och dess fallgropar
Typhon frakttransportkoncept, Anton Swanepoel

Jag heter Dmitrij Sugrobov, jag Àr utvecklare pÄ "Leroy Merlin". I artikeln kommer jag att berÀtta varför Helm behövs, hur det förenklar arbetet med Kubernetes, vad som har förÀndrats i den tredje versionen och hur man uppdaterar applikationer i produktion utan driftstopp.

Detta Ă€r en sammanfattning baserad pĂ„ en presentation pĂ„ konferensen @Kubernetes Conference by Mail.ru Cloud Solutions — om du inte vill lĂ€sa, titta pĂ„ videon.

Spela video

Varför vi anvÀnder Kubernetes i produktion

"Leroy Merlin" Àr en ledare pÄ DIY-retailmarknaden i Ryssland och Europa. I vÄrt företag arbetar över hundra utvecklare, 33 000 interna anstÀllda och ett stort antal mÀnniskor besöker vÄra varuhus och webbplats. För att göra alla glada beslutade vi att följa standardmetoder inom branschen. Vi utvecklar nya applikationer med mikrotjÀnstarkitektur; för att isolera miljöer och sÀkerstÀlla korrekt leverans anvÀnder vi containrar; och för orkestrering anvÀnder vi Kubernetes. Kostnaden för att anvÀnda orkestratorer blir snabbt billigare: antalet ingenjörer som behÀrskar tekniken ökar pÄ marknaden och leverantörer erbjuder Kubernetes som en tjÀnst.

Allt som Kubernetes gör kan sjÀlvklart göras pÄ andra sÀtt, till exempel genom att kladda med skript i nÄgon Jenkins och docker-compose, men varför komplicera livet nÀr det finns en fÀrdig och pÄlitlig lösning? DÀrför har vi valt Kubernetes och har anvÀnt det i produktion i ett Är nu. Nu har vi tjugofyra Kubernetes-kluster, det Àldsta av dem Àr över ett Är gammalt och har cirka tvÄhundra pods.

Förbannelsen med ett stort antal YAML-filer i Kubernetes

För att starta 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 applikation skriver vi samma uppsĂ€ttning YAML-filer, med den tredje — ytterligare en och sĂ„ vidare. Multiplicera antalet dokument med antalet miljöer, sĂ„ fĂ„r vi hundratals filer, och detta tar inte ens hĂ€nsyn till dynamiska miljöer.

Helm-struktur och dess fallgropar
Adam Reese, huvudansvarig för Helm, introducerade begreppet "Utvecklingscykeln i Kubernetes" som ser ut sÄ hÀr:

  1. Kopiera YAML — kopiera YAML-filen.
  2. Klistra in YAML — klistra in den.
  3. Fixera indrag — fixa indragen.
  4. Upprepa — upprepa igen.

Detta alternativ fungerar, men man mÄste ofta kopiera YAML-filer flera gÄnger. För att förÀndra denna cykel uppfanns Helm.

Vad Àr Helm

Först och frĂ€mst Ă€r Helm — paketchef, som hjĂ€lper till att hitta och installera nödvĂ€ndiga program. För att installera till exempel MongoDB mĂ„ste man inte gĂ„ till den officiella webbplatsen och ladda ner binĂ€rfiler, det rĂ€cker att köra kommandot helm install stable/mongodb.

För det andra, Helm — en mallmotor, hjĂ€lper till att parametrera filer. LĂ„t oss Ă„tergĂ„ till situationen med YAML-filer i Kubernetes. Det Ă€r enklare att skriva samma YAML-fil, lĂ€gga till nĂ„gra platshĂ„llare, dĂ€r Helm sĂ€tter in vĂ€rden. Det betyder att istĂ€llet för en stor uppsĂ€ttning YAML-filer kommer det att finnas en uppsĂ€ttning mallar, dĂ€r de nödvĂ€ndiga vĂ€rdena kommer att sĂ€ttas in vid rĂ€tt tidpunkt.

För det tredje, Helm — mĂ€stare vid distribution. Med hjĂ€lp av det kan man installera, Ă„terstĂ€lla och uppdatera applikationer. LĂ„t oss gĂ„ igenom hur man gör detta.

Helm-struktur och dess fallgropar

Hur man anvÀnder Helm för att distribuera sina egna applikationer

Vi installerar Helm-klienten pÄ datorn, enligt den officiella instruktionerna. Sedan skapar vi en uppsÀttning YAML-filer. IstÀllet för att ange specifika vÀrden lÀmnar vi platshÄllare som Helm senare kommer att fylla med information. En uppsÀttning sÄdana filer kallas för en Helm-diagram. Den kan skickas till Helm-konsolklienten pÄ tre sÀtt:

  • ange mappen med mallar;
  • paketera den i en .tar-arkiv och ange den;
  • placera mallen i ett fjĂ€rrrepo och lĂ€gga till en lĂ€nk till repositoriet i Helm-klienten.

Även en fil med vĂ€rden behövs — values.yaml. Data dĂ€rifrĂ„n kommer att sĂ€ttas in i mallen. LĂ„t oss skapa den ocksĂ„.

Helm-struktur och dess fallgropar
I den andra versionen av Helm finns det en tillĂ€ggstjĂ€nst — Tiller. Den finns utanför Kubernetes och vĂ€ntar pĂ„ förfrĂ„gningar frĂ„n Helm-klienten, och nĂ€r den anropas sĂ€tter den in nödvĂ€ndiga vĂ€rden i mallen och skickar dem till Kubernetes.

Helm-struktur och dess fallgropar
Helm 3 Àr enklare: istÀllet för att bearbeta mallarna pÄ servern, behandlas informationen nu helt och hÄllet pÄ sidan av Helm-klienten och skickas direkt till Kubernetes API. Denna förenkling förbÀttrar sÀkerheten för klustret och förenklar distributionsschemat.

Hur detta fungerar

Kör kommandot helm install. Ange namnet pÄ applikationens release, ge sökvÀgen till values.yaml. I slutet anger vi repo dÀr diagrammet ligger och namnet pÄ diagrammet. I exemplet Àr detta «lmru» och «bestchart» respektive.

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

Utförandet av kommandot Àr möjligt endast en gÄng, vid upprepning av kommandot istÀllet för install mÄste du anvÀnda upgrade. För enkelhetens skull kan man istÀllet för tvÄ kommandon köra kommandot upgrade med en extra nyckel --install. Vid första körningen skickar Helm en kommando för att installera releasen, och kommer att uppdatera den i framtiden.

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

Fallgropar vid deployment av nya versioner av applikationen med Helm

Vid den hÀr punkt i berÀttelsen spelar jag med publiken i "Vem vill bli miljonÀr?", och vi tar reda pÄ hur man fÄr Helm att uppdatera applikationens version. Se videon.

NĂ€r jag studerade hur Helm fungerar, blev jag förvĂ„nad över det mĂ€rkliga beteendet vid försök att uppdatera versioner av körda applikationer. Applikationens kod uppdaterades, en ny bild laddades upp i Docker-registret, jag skickade ett kommando för deployment – och ingenting hĂ€nde. HĂ€r Ă€r nĂ„gra inte helt lyckade sĂ€tt att uppdatera applikationer. Genom att studera varje metod mer ingĂ„ende börjar man förstĂ„ verktygets inre funktion och orsakerna till detta inte sĂ„ uppenbara beteende.

Metod 1. Ändra inte informationen sedan senaste körningen

Som det stÄr den officiella webbplatsen Helm, "Kubernetes charts kan vara stora och komplexa, sÄ Helm försöker helst att inte röra saker för mycket". DÀrför, om man uppdaterar latest-versionen av applikationens bild i Docker-registret och utför kommandot helm upgrade, sÄ kommer ingenting att hÀnda. Helm kommer att tro att ingenting har förÀndrats och behöver ingen kommando för att uppdatera applikationen i Kubernetes.

HÀr och framÄt visas taggen latest endast som ett exempel. Vid angivande av denna tagg kommer Kubernetes att ladda ner bilden frÄn Docker-registret varje gÄng, oavsett imagePullPolicy. AnvÀndning av latest i produktion Àr inte rekommenderat och ger biverkningar.

Metod 2. Uppdatera LABEL i bilden

Som det stÄr i samma dokumentationen, "Helm kommer att uppdatera applikationen endast om den har förÀndrats sedan senaste releasen". En logisk ÄtgÀrd för detta skulle vara att uppdatera LABEL-taggen i sjÀlva Docker-bilden. Men Helm kollar inte i applikationernas bilder och har ingen aning om nÄgra förÀndringar i dem. DÀrför, vid uppdatering av etiketter i bilden, fÄr Helm inte veta om dem och kommandot för att uppdatera applikationen i Kubernetes kommer inte att skickas.

Metod 3. AnvÀnd nyckeln --force

Helm-struktur och dess fallgropar
LÄt oss kolla manualerna och leta efter rÀtt nyckel. Den nyckel som passar bÀst i betydelse --force. Trots det talande namnet, skiljer sig beteendet frÄn förvÀntningarna. IstÀllet för att tvinga fram en uppdatering av appen, Àr dess verkliga syfte att ÄterstÀlla en release som Àr i status FAILED. Om denna flagga inte anvÀnds, mÄste kommandona utföras sekventiellt. helm delete && helm install --replace. IstÀllet föreslÄs det att anvÀnda flaggan --force, som automatiserar sekventiell körning av dessa kommandon. Mer information finns i denna pull request.. För att fÄ Helm att faktiskt uppdatera appversionen, kommer tyvÀrr denna flagga inte att fungera.

Metod 4. Ändra labels direkt i Kubernetes.

Helm-struktur och dess fallgropar
Uppdatering av label direkt i klustret med kommandot kubectl edit. — Ă€r en dĂ„lig idĂ©. Denna Ă„tgĂ€rd kommer att leda till inkonsekvens i informationen mellan den körande appen och vad som ursprungligen skickades för distribution. Helm's beteende vid distribution i detta fall skiljer sig frĂ„n dess version: Helm 2 kommer inte att göra nĂ„got, medan Helm 3 kommer att distribuera en ny version av appen. För att förstĂ„ orsaken, behöver man förstĂ„ hur Helm fungerar.

Hur Helm fungerar.

För att avgöra om appen har Àndrats sedan den senaste releasen, kan Helm anvÀnda sig av:

  • den körande appen i Kubernetes;
  • en ny values.yaml och aktuell chart;
  • intern information om releases frĂ„n Helm.

För de mest nyfikna: var lagrar Helm intern information om releases?Genom att köra kommandot helm history,fÄr vi all information om versioner installerade med hjÀlp av Helm.

Helm-struktur och dess fallgropar
Det finns ocksÄ detaljerad information om de skickade mallarna och vÀrdena. Vi kan begÀra det:

Helm-struktur och dess fallgropar
I den andra versionen av Helm ligger denna information i samma namespace dÀr Tiller kör, vilket som standard Àr kube-system, i en ConfigMap mÀrkt med labeln "OWNER=TILLER":

Helm-struktur och dess fallgropar
Vid övergÄngen till den tredje versionen av Helm flyttades informationen till hemligheter, i samma namespace dÀr appen körs. Detta gjorde det möjligt att köra flera appar samtidigt i olika namespaces med samma release-namn. I den andra versionen var detta en stor huvudvÀrk, eftersom namespaces var isolerade men kunde pÄverka varandra.

Helm-struktur och dess fallgropar

Andra Helm, nÀr den försöker förstÄ om en uppdatering behövs, anvÀnder endast tvÄ informationskÀllor: det som gavs nu och den interna informationen om releases, som ligger i ConfigMap.

Helm-struktur och dess fallgropar
Den tredje Helm anvÀnder en trevÀgsfusionsstrategi: utöver den information som beaktas, tar den ocksÄ hÀnsyn till applikationen som körs just nu i Kubernetes.

Helm-struktur och dess fallgropar
Av denna anledning kommer den gamla versionen av Helm inte att göra nÄgot, eftersom den inte beaktar informationen frÄn applikationen i klustret, medan Helm 3 kommer att ta emot Àndringar och skicka en ny applikation för distribution.

Metod 5. AnvĂ€nda nyckeln —recreate-pods

Med hjÀlp av nyckeln --recreate-pods kan man uppnÄ det som ursprungligen var tÀnkt att uppnÄs med nyckeln --force. Kontainrarna kommer att startas om och, enligt policyn imagePullPolicy: Always för taggen latest (angivet ovan), kommer Kubernetes att ladda ner och starta den nya versionen av bilden. Det kommer att göras pÄ ett mindre optimalt sÀtt: utan att ta hÀnsyn till StrategyType för distributionen, kommer alla gamla instanser av applikationen plötsligt att stÀngas av och nya sÀttas igÄng. Under omstarten kommer systemet att vara nere, vilket innebÀr att anvÀndarna kommer att drabbas.

I Kubernetes har ett liknande problem ocksÄ funnits under en lÄng tid. Och nu, fyra Är efter att det öppnades Issue, har problemet ÄtgÀrdats, och frÄn och med version 1.15 av Kubernetes finns det möjlighet till rolling-restart av pods.

Helm stÀnger helt enkelt av alla applikationer och startar nya containrar bredvid dem. SÄ hÀr fÄr man inte göra i produktion för att undvika driftstopp av applikationen. Detta behövs endast för utvecklingssyften och kan endast utföras i stage-miljöer.

Hur uppdaterar man en applikationsversion med hjÀlp av Helm?

Vi kommer att Àndra de vÀrden som skickas till Helm. Som regel Àr detta vÀrden som ersÀtter taggen för bilden. I fallet med latest, som ofta anvÀnds för icke-produktiva miljöer, fungerar en annotation som den förÀnderliga informationen, vilken Àr vÀrdelös för Kubernetes men signalerar till Helm att applikationen behöver uppdateras. Alternativ för att fylla i vÀrdet pÄ annoteringen:

  1. Slumptal med hjĂ€lp av standardfunktionen — {{ randAlphaNum 6 }}.
    Det finns en detalj: efter varje distribution med en chart med en sÄdan variabel, kommer vÀrdet av annoteringen att vara unikt, och Helm kommer att tro att det finns Àndringar. Det gör att vi alltid kommer att starta om applikationen, Àven om vi inte har Àndrat dess version. Det Àr inte kritiskt, eftersom det inte kommer att bli nÄgot driftstopp, men det Àr ÀndÄ obehagligt.
  2. Infoga nuvarande datum och tid — {{ .Release.Date }}.
    Alternativet liknar slumptalet med en stÀndigt unik variabel.
  3. Ett mer korrekt sĂ€tt Ă€r att anvĂ€nda kontrollsummor. Det Ă€r SHA av bilden eller SHA av den senaste commit i git — {{ .Values.sha }}.
    Dessa mÄste berÀknas och skickas till Helm-klienten pÄ anropande sida, till exempel i Jenkins. Om applikationen har Àndrats, sÄ Àndras Àven kontrollsumman. DÀrför kommer Helm att uppdatera applikationen endast nÀr det behövs.

Sammanfatta vÄra försök

  • Helm gör Ă€ndringar pĂ„ det minst invasiva sĂ€ttet, sĂ„ varje Ă€ndring pĂ„ nivĂ„ av applikationsbild i Docker Registry kommer inte att leda till en uppdatering: efter att kommandot har körts kommer ingenting att hĂ€nda.
  • Nyckeln --force anvĂ€nds för att Ă„terstĂ€lla problematiska releaser och har ingen koppling till tvingad uppdatering.
  • Nyckeln --recreate-pods tvingar uppdateringar av applikationer, men gör det pĂ„ ett grymt sĂ€tt: det stĂ€nger abrupt av alla containrar. AnvĂ€ndarna kommer att drabbas, sĂ„ detta bör undvikas i produktion.
  • Direkt göra förĂ€ndringar i Kubernetes-klustret med kommandot kubectl edit. bör inte göras: vi skulle störa konsistensen, och beteendet kommer att variera beroende pĂ„ versionen av Helm.
  • Med den nya versionen av Helm har det dykt upp mĂ„nga nyanser. Issues i Helm-förvaret Ă€r beskrivna pĂ„ ett begripligt sprĂ„k, de kommer att hjĂ€lpa till att förstĂ„ detaljerna.
  • Att lĂ€gga till en Ă€ndringsbar annotation i chartet gör det mer flexibelt. Detta gör att applikationen kan rullas ut korrekt utan driftstopp.

En tanke frÄn kategorin "fred i hela vÀrlden", som fungerar i alla livets sfÀrer: lÀs instruktionen före anvÀndning, inte efter. Endast med fullstÀndig information kan man bygga pÄlitliga system och göra anvÀndarna nöjda.

Andra lÀnkar i temat:

  1. Introduktion till Helm 3
  2. Den officiella webbplatsen för Helm
  3. Helm-förvaret pÄ GitHub
  4. 25 anvÀndbara Kubernetes-verktyg: utplacering och hantering

Denna presentation hördes först pÄ @Kubernetes Conference av Mail.ru Cloud Solutions. Se video andra förelÀsningar och följ anmÀlningarna till evenemang pÄ Telegram Runt Kubernetes i Mail.ru Group.

KĂ€lla: habr.com

Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar đŸ”„ Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster