Dispositivo Helm e le sue insidie

Dispositivo Helm e le sue insidie
Concetto di trasporto Typhon, Anton Swanepoel

Mi chiamo Dmitrij Sugrobov, sono uno sviluppatore presso «Leroy Merlin». In questo articolo spiegherò a cosa serve Helm, come semplifica il lavoro con Kubernetes, cosa è cambiato nella terza versione e come utilizzarlo per aggiornare le applicazioni in produzione senza interruzioni.

Questa è una sintesi ispirata a un intervento in conferenza @Kubernetes Conference eliminando file non necessari dai tuoi set di backup Mail.ru Cloud Solutions — se non vuoi leggere, guarda il video.

Guarda il video

Perché utilizziamo Kubernetes in produzione

«Leroy Merlin» è leader nel mercato del fai-da-te in Russia e in Europa. Nella nostra azienda ci sono più di cento sviluppatori, 33.000 dipendenti interni e un enorme numero di persone che visitano i negozi e il sito web. Per rendere tutti loro felici, abbiamo deciso di aderire a approcci standard del settore. Sviluppiamo nuove applicazioni utilizzando un'architettura a microservizi; per isolare gli ambienti e garantire una consegna corretta utilizziamo container; e per l'orchestrazione utilizziamo Kubernetes. Il costo di utilizzo degli orchestratori sta rapidamente diminuendo: aumenta il numero di ingegneri che conoscono questa tecnologia e stanno emergendo provider che offrono Kubernetes come servizio.

Tutto ciò che fa Kubernetes, ovviamente, può essere fatto in altri modi, ad esempio, usando un Jenkins con script e docker-compose, ma perché complicarsi la vita, se c'è una soluzione pronta e affidabile? Ecco perché ci siamo orientati verso Kubernetes e lo utilizziamo già da un anno in produzione. Attualmente abbiamo ventiquattro cluster Kubernetes, il più vecchio dei quali ha più di un anno e contiene circa duecento pod.

La maledizione del gran numero di file YAML in Kubernetes

Per avviare un microservizio in Kubernetes, creeremo almeno cinque file YAML: per Deployment, Service, Ingress, ConfigMap, Secrets — e li invieremo al cluster. Per la successiva applicazione scriveremo lo stesso pacchetto di file YAML, per la terza — un altro e così via. Moltiplichiamo il numero di documenti per il numero di ambienti e già otteniamo centinaia di file, senza contare gli ambienti dinamici.

Dispositivo Helm e le sue insidie
Adam Reese, core maintainer di Helm, ha introdotto il concetto di "Ciclo di sviluppo in Kubernetesche appare così:

  1. Copy YAML — copiare il file YAML.
  2. Paste YAML — incollarlo.
  3. Fix Indents — sistemare gli spazi.
  4. Repeat — ripetere di nuovo.

La variante è funzionante, ma comporta molte copie di file YAML. Per modificare questo ciclo, è stato ideato Helm.

Cos'è Helm

Innanzitutto, Helm è gestore di pacchetti, che aiuta a trovare e installare i programmi necessari. Ad esempio, per installare MongoDB non è necessario andare sul sito ufficiale e scaricare i binari, basta eseguire il comando helm install stable/mongodb.

In secondo luogo, Helm è un templater, che aiuta a parametrizzare i file. Torniamo alla situazione con i file YAML in Kubernetes. È più facile scrivere lo stesso file YAML, aggiungere alcuni segnaposto nei quali Helm inserirà i valori. Quindi, invece di un grande insieme di file YAML, avremo un insieme di template, nei quali verranno inseriti i valori necessari al momento giusto.

In terzo luogo, Helm è un maestro del deployment. Con esso è possibile installare, ripristinare e aggiornare le applicazioni. Cerchiamo di capire come fare.

Dispositivo Helm e le sue insidie

Come usare Helm per il deployment delle proprie applicazioni

Installiamo il client Helm sul computer, seguendo il guida. Poi creeremo un insieme di file YAML. Invece di specificare valori concreti, lasceremo dei segnaposto, che in futuro Helm riempirà con le informazioni. Questo insieme di file è chiamato Helm chart. Può essere inviato al client della console Helm in tre modi:

  • specificare una cartella con i template;
  • impacchettarlo in un archivio .tar e fare riferimento a esso;
  • mettere il template in un repository remoto e aggiungere un link al repository nel client Helm.

Serve inoltre un file con i valori — values.yaml. I dati da lì verranno inseriti nel template. Creiamolo anche.

Dispositivo Helm e le sue insidie
Nella seconda versione di Helm c'è un'applicazione server aggiuntiva — Tiller. Essa risiede all'esterno di Kubernetes e attende richieste dal client Helm, e quando viene chiamata, inserisce i valori necessari nel template e lo invia a Kubernetes.

Dispositivo Helm e le sue insidie
Helm 3 è più semplice: invece di elaborare i template sul server, le informazioni vengono ora elaborate interamente lato client di Helm e inviate direttamente all'API di Kubernetes. Questa semplificazione aumenta la sicurezza del cluster e facilita il processo di deployment.

Come funziona tutto questo

Eseguiamo il comando helm install. Indicheremo il nome del rilascio dell'applicazione, daremo il percorso fino a values.yaml. Alla fine indicheremo il repository in cui si trova il chart e il nome del chart. Nell'esempio, questi sono 'lmru' e 'bestchart' rispettivamente.

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

L'esecuzione del comando è possibile solo una volta; per eseguire di nuovo bisogna usare install devi usare . Per ulteriori informazioni su come utilizzare il flagcon un'opzione aggiuntiva . Per ulteriori informazioni su come utilizzare il flag --install --install. Al primo avvio, Helm invierà un comando per installare il rilascio e successivamente lo aggiornerà.

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

Insidie del deploy di nuove versioni dell'applicazione con Helm

In questo punto della storia, gioco con il pubblico in "Chi vuol essere milionario?", e stiamo scoprendo come costringere Helm ad aggiornare la versione dell'applicazione. Guarda il video.

Quando studiavo il funzionamento di Helm, mi ha sorpreso un comportamento strano quando tentavo di aggiornare le versioni delle applicazioni in esecuzione. Ho aggiornato il codice dell'applicazione, caricato una nuova immagine nel registro Docker, inviato il comando di deploy – e non è successo nulla. Di seguito alcuni modi non molto efficaci per aggiornare le applicazioni. Esaminando ciascuno di essi più in dettaglio, cominci a comprendere il funzionamento interno dello strumento e le ragioni di tale comportamento non intuitivo.

Modo 1. Non cambiare le informazioni dall'ultimo avvio

Come dice sito ufficiale Helm, "I chart di Kubernetes possono essere grandi e complessi, quindi Helm cerca di non toccare nulla senza motivo". Pertanto, se aggiorni l'immagine dell'applicazione all'ultima versione nel registro Docker e esegui il comando helm upgrade, non succederà nulla. Helm penserà che non sia cambiato nulla e non sarà necessario inviare a Kubernetes il comando per aggiornare l'applicazione.

Qui e oltre, il tag latest è mostrato esclusivamente a scopo esemplificativo. Specificando questo tag, Kubernetes scaricherà ogni volta l'immagine dal registro Docker, indipendentemente dal parametro imagePullPolicy. L'uso di latest in produzione è sconsigliato e causa effetti collaterali.

Modo 2. Aggiornare LABEL nell'immagine

Come scritto nello stesso documentazione, "Helm aggiornerà l'applicazione solo se è cambiata dall'ultimo rilascio". Un'opzione logica per questo sembrerebbe aggiornare il tag LABEL nell'immagine Docker stessa. Tuttavia, Helm non guarda nelle immagini delle applicazioni e non è a conoscenza di eventuali modifiche in esse. Pertanto, aggiornando i tag nell'immagine, Helm non ne verrà a conoscenza e il comando di aggiornamento dell'applicazione in Kubernetes non verrà emesso.

Modo 3. Utilizzare una chiave --force

Dispositivo Helm e le sue insidie
Rimandiamo ai manuali e cerchiamo la chiave giusta. La chiave che sembra avere più senso è --force. Nonostante il nome eloquente, il comportamento è diverso da quello previsto. Invece di forzare l'aggiornamento dell'applicazione, il suo reale scopo è il ripristino di una release in stato FAILED. Se non si utilizza questa chiave, è necessario eseguire i comandi in sequenza. helm delete && helm install --replace. Invece, si propone di utilizzare la chiave --force, che automatizza l'esecuzione sequenziale di questi comandi. Maggiori informazioni in questo pull request.. Per dire a Helm di aggiornare comunque la versione dell'applicazione, sfortunatamente, questa chiave non funzionerà.

Metodo 4. Modificare direttamente le etichette in Kubernetes.

Dispositivo Helm e le sue insidie
Aggiornare direttamente l'etichetta nel cluster utilizzando il comando kubectl edit è una cattiva idea. Questa azione porterà a una incongruenza delle informazioni tra l'applicazione in esecuzione e ciò che è stato inizialmente inviato per il deployment. Il comportamento di Helm durante il deployment in questo caso differisce dalla sua versione: Helm 2 non farà nulla, mentre Helm 3 deployerà una nuova versione dell'applicazione. Per comprendere la ragione, è necessario capire come funziona Helm.

Come è strutturato Helm.

Per determinare se l'applicazione è cambiata dall'ultima release, Helm può avvalersi di:

  • un'applicazione in esecuzione in Kubernetes;
  • nuovo values.yaml e chart attuale;
  • informazioni interne di Helm sulle release.

Per i più curiosi: dove Helm archivia le informazioni interne sulle release?Eseguendo il comando helm history, otteniamo tutte le informazioni sulle versioni installate tramite Helm.

Dispositivo Helm e le sue insidie
Ci sono inoltre dettagli sulle template e i valori inviati. Possiamo richiederli:

Dispositivo Helm e le sue insidie
Nella seconda versione di Helm, queste informazioni si trovano nello stesso namespace in cui è in esecuzione Tiller (di default — kube-system), in un ConfigMap contrassegnato dall’etichetta «OWNER=TILLER»:

Dispositivo Helm e le sue insidie
Con l'arrivo della terza versione di Helm, le informazioni sono state trasferite nei segreti, nel medesimo namespace in cui è in esecuzione l'applicazione. Questo ha reso possibile eseguire contemporaneamente più applicazioni in diversi namespace con lo stesso nome di release. Nella seconda versione, ciò era un forte mal di testa, poiché i namespace erano isolati, ma potevano influenzarsi reciprocamente.

Dispositivo Helm e le sue insidie

Il secondo Helm, quando cerca di capire se è necessario un aggiornamento, utilizza solo due fonti di informazione: ciò che gli è stato fornito ora e le informazioni interne sulle release, che si trovano nel ConfigMap.

Dispositivo Helm e le sue insidie
Il terzo Helm utilizza una strategia di merge a tre vie: oltre alle informazioni già disponibili, tiene conto anche dell'applicazione che è attualmente in esecuzione su Kubernetes.

Dispositivo Helm e le sue insidie
Per questo motivo, la vecchia versione di Helm non farà nulla, poiché non considera le informazioni sull'applicazione nel cluster, mentre Helm 3 riceverà le modifiche e invierà una nuova applicazione per il deployment.

Metodo 5. Utilizzare la chiave —recreate-pods

Con la chiave --recreate-pods è possibile ottenere ciò che si voleva inizialmente raggiungere con la chiave --force. I contenitori verranno riavviati e, secondo la politica imagePullPolicy: Always per il tag latest (come indicato nella nota sopra), Kubernetes scaricherà e avvierà una nuova versione dell'immagine. Questo avverrà in modo non ottimale: ignorando il StrategyType del deployment, spegnerà brutalmente tutte le vecchie istanze dell'applicazione e procederà ad avviare quelle nuove. Durante il riavvio, il sistema non sarà operativo e gli utenti subiranno disagi.

Nel Kubernetes stesso, un problema simile è esistito a lungo. E così, dopo 4 anni dall'apertura Problema, il problema è stato risolto e a partire dalla versione 1.15 di Kubernetes è disponibile la possibilità di riavvio rolling dei pod.

Helm invece spegne semplicemente tutte le applicazioni e avvia nuovi contenitori accanto a quelle esistenti. In produzione non è possibile farlo, per non provocare inattività dell'applicazione. Questo è qualcosa che va fatto solo per esigenze di sviluppo, e può essere eseguito solo in ambienti di staging.

Come aggiornare la versione dell'applicazione con Helm?

Modificheremo i valori inviati a Helm. Di solito, questi valori sono quelli che sostituiscono il tag dell'immagine. Nel caso di latest, frequentemente utilizzato per ambienti non produttivi, l'informazione modificabile consiste in un'annotazione, che per Kubernetes è inutile, ma per Helm sarà un segnale della necessità di aggiornare l'applicazione. Ecco alcune varianti per compilare il valore dell'annotazione:

  1. Valore casuale utilizzando la funzione standard — {{ randAlphaNum 6 }}.
    C'è un dettaglio: dopo ogni deployment utilizzando un chart con tale variabile, il valore dell'annotazione sarà unico, e Helm penserà che ci siano modifiche. Così facendo, riavvieremo sempre l'applicazione, anche se non abbiamo cambiato la sua versione. Questo non è critico, poiché non ci sarà inattività, ma è comunque fastidioso.
  2. Inserire l'attuale data e ora{{ .Release.Date }}.
    Questa opzione è simile al valore casuale con una variabile sempre unica.
  3. Un modo più corretto è utilizzare somme di controllo. Questo è l'immagine SHA o SHA dell'ultimo commit in git — {{ .Values.sha }}.
    Devono essere calcolate e inviate al client Helm sul lato chiamante, ad esempio in Jenkins. Se l'applicazione cambia, anche la somma di controllo cambierà. Pertanto, Helm aggiornerà l'applicazione solo quando necessario.

Riassumiamo i nostri tentativi

  • Helm apporta modifiche nel modo meno invasivo possibile, quindi qualsiasi cambiamento a livello di immagine dell'applicazione nel Docker Registry non porterà a un aggiornamento: dopo l'esecuzione del comando, non succede nulla.
  • Chiave --force viene utilizzato per ripristinare le release problematiche e non è collegato a un aggiornamento forzato.
  • Chiave --recreate-pods forzerà l'aggiornamento delle applicazioni, ma lo farà in modo distruttivo: spegnerà bruscamente tutti i container. Questo danneggerà gli utenti; non è consigliabile farlo in produzione.
  • Non bisogna apportare modifiche direttamente al cluster Kubernetes con il comando kubectl edit : comprometteremmo la consistenza e il comportamento varierà a seconda della versione di Helm.
  • Con l'uscita della nuova versione di Helm sono emersi molti dettagli. I problemi nel repository di Helm sono descritti in modo chiaro e aiuteranno a comprendere i dettagli.
  • Aggiungere un'annotazione modificabile nel chart lo renderà più flessibile. Questo consentirà di implementare l'applicazione correttamente, senza tempi di inattività.

Un pensiero del tipo 'pace nel mondo' che funziona in tutti gli ambiti della vita: leggi le istruzioni prima dell'uso, non dopo. Solo possedendo tutte le informazioni, è possibile costruire sistemi affidabili e rendere felici gli utenti.

Altri collegamenti sull'argomento:

  1. Introduzione a Helm 3
  2. Sito ufficiale di Helm
  3. Repository di Helm su GitHub
  4. 25 strumenti utili per Kubernetes: distribuzione e gestione

Questa presentazione è stata pronunciata per la prima volta a @Kubernetes Conference by Mail.ru Cloud Solutions. Guarda video altre presentazioni e iscriviti agli annunci di eventi su Telegram Attorno a Kubernetes in Mail.ru Group.

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster