Il dispositivo Helm e le sue insidie

Il dispositivo Helm e le sue insidie
Concetto di trasportatore di merci Typhon, Anton Swanepoel

Mi chiamo Dmitry Sugrobov, sono uno sviluppatore presso Leroy Merlin. In questo articolo ti dirò perché è necessario Helm, come semplifica il lavoro con Kubernetes, cosa è cambiato nella terza versione e come utilizzarlo per aggiornare le applicazioni in produzione senza tempi di inattività.

Questo è un riassunto basato su un discorso ad una conferenza @Conferenza Kubernetes by Mail.ru soluzioni cloud — se non vuoi leggere, guarda il video.

Perché utilizziamo Kubernetes in produzione

Leroy Merlin è leader nel mercato al dettaglio del fai da te in Russia e in Europa. La nostra azienda ha più di cento sviluppatori, 33 dipendenti interni e un numero enorme di persone che visitano gli ipermercati e il sito web. Per renderli tutti felici, abbiamo deciso di seguire gli approcci standard del settore. Sviluppare nuove applicazioni utilizzando l'architettura dei microservizi; utilizzare contenitori per isolare gli ambienti e garantire una corretta consegna; e utilizzare Kubernetes per l'orchestrazione. Il prezzo per l’utilizzo degli orchestratori sta diventando sempre più basso: sul mercato cresce il numero di ingegneri esperti in questa tecnologia e compaiono provider che offrono Kubernetes come servizio.

Tutto ciò che fa Kubernetes, ovviamente, può essere fatto in altri modi, ad esempio coprendo alcuni Jenkins e docker-compose con script, ma perché complicare la vita se esiste una soluzione già pronta e affidabile? Ecco perché siamo arrivati ​​a Kubernetes e lo utilizziamo in produzione ormai da un anno. Attualmente disponiamo di ventiquattro cluster Kubernetes, il più vecchio dei quali ha più di un anno, con circa duecento pod.

La maledizione dei file YAML di grandi dimensioni 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 prossima applicazione scriveremo lo stesso pacchetto di stipiti, con il terzo ne scriveremo un altro, e così via. Se moltiplichiamo il numero di documenti per il numero di ambienti, otterremo già centinaia di file, e questo non tiene ancora conto degli ambienti dinamici.

Il dispositivo Helm e le sue insidie
Adam Reese, manutentore principale di Helm, ha introdotto il concetto di "Ciclo di sviluppo in Kubernetes", che assomiglia a questo:

  1. Copia YAML: copia un file YAML.
  2. Incolla YAML: incollalo.
  3. Correggi rientri: correggi i rientri.
  4. Ripeti: ripeti ancora.

L'opzione funziona, ma devi copiare i file YAML più volte. Per cambiare questo ciclo, è stato inventato Helm.

Cos'è Helm

Innanzitutto, Timone - gestore dei pacchetti, che ti aiuta a trovare e installare i programmi di cui hai bisogno. Per installare, ad esempio, MongoDB, non è necessario andare sul sito ufficiale e scaricare i binari, basta eseguire il comando helm install stable/mongodb.

In secondo luogo, Helm - motore del modello, aiuta a parametrizzare i file. Torniamo alla situazione con i file YAML in Kubernetes. È più semplice scrivere lo stesso file YAML, aggiungervi alcuni segnaposto, in cui Helm sostituirà i valori. Cioè, invece di un ampio insieme di impalcature, ci sarà una serie di modelli in cui i valori richiesti verranno sostituiti al momento giusto.

In terzo luogo, Elmo - maestro della distribuzione. Con esso puoi installare, ripristinare e aggiornare le applicazioni. Scopriamo come farlo.

Il dispositivo Helm e le sue insidie

Come utilizzare Helm per distribuire le tue applicazioni

Installiamo il client Helm sul tuo computer, seguendo la procedura ufficiale istruzione. Successivamente, creeremo un set di file YAML. Invece di specificare valori specifici, lasceremo dei segnaposto, che Helm riempirà con le informazioni in futuro. Un insieme di tali file è chiamato grafico Helm. Può essere inviato al client della console Helm in tre modi:

  • indicare una cartella con modelli;
  • comprimere l'archivio in un file .tar e puntarlo;
  • inserisci il modello in un repository remoto e aggiungi un collegamento al repository nel client Helm.

Hai anche bisogno di un file con valori: value.yaml. I dati da lì verranno inseriti nel modello. Creiamolo anche noi.

Il dispositivo Helm e le sue insidie
La seconda versione di Helm ha un'applicazione server aggiuntiva: Tiller. Si blocca all'esterno di Kubernetes e attende le richieste dal client Helm e, quando chiamato, sostituisce i valori richiesti nel modello e lo invia a Kubernetes.

Il dispositivo Helm e le sue insidie
Helm 3 è più semplice: invece di elaborare i modelli sul server, le informazioni vengono ora elaborate interamente sul lato client Helm e inviate direttamente all'API Kubernetes. Questa semplificazione migliora la sicurezza del cluster e facilita lo schema di implementazione.

Come funziona tutto?

Esegui il comando helm install. Indichiamo il nome della versione dell'applicazione e diamo il percorso a valori.yaml. Alla fine indicheremo il repository in cui si trova il grafico e il nome del grafico. Nell'esempio sono rispettivamente “lmru” e “bestchart”.

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

Il comando può essere eseguito una sola volta, se invece viene eseguito nuovamente install bisogno di usare upgrade. Per semplicità, invece di due comandi, puoi eseguire il comando upgrade con chiave aggiuntiva --install. Quando eseguito per la prima volta, Helm invierà un comando per installare la versione e la aggiornerà in futuro.

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

Insidie ​​legate alla distribuzione di nuove versioni di un'applicazione con Helm

A questo punto della storia, sto giocando a Chi Vuol Essere Milionario con il pubblico e stiamo cercando di capire come convincere Helm ad aggiornare la versione dell'app. Guarda il video.

Mentre stavo imparando come funziona Helm, sono rimasto sorpreso da uno strano comportamento durante il tentativo 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 distribuzione e non è successo nulla. Di seguito sono riportati alcuni modi non del tutto efficaci per aggiornare le applicazioni. Studiando ciascuno di essi più nel dettaglio, si inizia a comprendere la struttura interna dello strumento e le ragioni di questo comportamento non scontato.

Metodo 1. Non modificare le informazioni dall'ultimo avvio

Come giocare sito ufficiale Helm: "I grafici Kubernetes possono essere grandi e complessi, quindi Helm cerca di non toccare nulla troppo." Pertanto, se aggiorni la versione più recente dell'immagine dell'applicazione nel registro del docker ed esegui il comando helm upgrade, allora non succederà nulla. Helm penserà che non è cambiato nulla e non è necessario inviare un comando a Kubernetes per aggiornare l'applicazione.

Qui e di seguito, l'ultimo tag è mostrato esclusivamente a titolo di esempio. Quando specifichi questo tag, Kubernetes scaricherà ogni volta l'immagine dal registro del docker, indipendentemente dal parametro imagePullPolicy. L'utilizzo delle ultime novità in produzione non è auspicabile e provoca effetti collaterali.

Metodo 2. Aggiorna LABEL nell'immagine

Come scritto nello stesso documentazione, "Helm aggiornerà un'applicazione solo se è cambiata dall'ultima versione." Un'opzione logica per questo sembrerebbe aggiornare l'ETICHETTA nell'immagine della finestra mobile stessa. Tuttavia, Helm non esamina le immagini dell'applicazione e non ha idea di eventuali modifiche ad esse. Di conseguenza, durante l'aggiornamento delle etichette nell'immagine, Helm non ne verrà a conoscenza e il comando di aggiornamento dell'applicazione non verrà inviato a Kubernetes.

Metodo 3: utilizzare una chiave --force

Il dispositivo Helm e le sue insidie
Passiamo ai manuali e cerchiamo la chiave richiesta. La chiave ha più senso --force. Nonostante il nome ovvio, il comportamento è diverso da quello previsto. Invece di forzare un aggiornamento dell'applicazione, il suo vero scopo è ripristinare una versione che si trova nello stato FAILED. Se non si utilizza questo tasto, è necessario eseguire i comandi in sequenza helm delete && helm install --replace. Si consiglia invece di utilizzare la chiave --force, che automatizza l'esecuzione sequenziale di questi comandi. Maggiori informazioni in questo richiesta pull. Per dire a Helm di aggiornare la versione dell'applicazione, sfortunatamente, questa chiave non funzionerà.

Metodo 4. Modifica le etichette direttamente in Kubernetes

Il dispositivo Helm e le sue insidie
Aggiornamento dell'etichetta direttamente nel cluster utilizzando il comando kubectl edit - cattiva idea. Questa azione comporterà un'incoerenza delle informazioni tra l'applicazione in esecuzione e quella originariamente inviata per la distribuzione. Il comportamento di Helm durante la distribuzione in questo caso è diverso dalla sua versione: Helm 2 non farà nulla e Helm 3 distribuirà la nuova versione dell'applicazione. Per capire perché, devi capire come funziona Helm.

Come funziona il timone?

Per determinare se un'applicazione è cambiata rispetto al suo ultimo rilascio, Helm può utilizzare:

  • eseguire l'applicazione in Kubernetes;
  • nuovi valori.yaml e grafico attuale;
  • Informazioni sulla versione interna di Helm.

Per i più curiosi: dove Helm memorizza le informazioni interne sui rilasci?Eseguendo il comando helm history, otterremo tutte le informazioni sulle versioni installate utilizzando Helm.

Il dispositivo Helm e le sue insidie
Sono inoltre disponibili informazioni dettagliate sui modelli e sui valori inviati. Possiamo richiederlo:

Il dispositivo Helm e le sue insidie
Nella seconda versione di Helm, queste informazioni si trovano nello stesso namespace in cui è in esecuzione Tiller (kube-system per impostazione predefinita), nella ConfigMap, contrassegnato con l'etichetta “OWNER=TILLER”:

Il dispositivo Helm e le sue insidie
Quando è apparsa la terza versione di Helm, le informazioni sono state spostate nei segreti e nello stesso spazio dei nomi in cui era in esecuzione l'applicazione. Grazie a ciò è diventato possibile eseguire più applicazioni contemporaneamente in diversi namespace con lo stesso nome di versione. Nella seconda versione era un vero grattacapo quando gli spazi dei nomi erano isolati ma potevano influenzarsi a vicenda.

Il dispositivo Helm e le sue insidie

Il secondo Helm, quando cerca di capire se è necessario un aggiornamento, utilizza solo due fonti di informazioni: ciò che gli viene fornito ora e le informazioni interne sui rilasci, che si trovano nella ConfigMap.

Il dispositivo Helm e le sue insidie
Il terzo Helm utilizza una strategia di fusione a tre vie: oltre a queste informazioni, tiene conto anche dell'applicazione attualmente in esecuzione in Kubernetes.

Il dispositivo Helm e le sue insidie
Per questo motivo la vecchia versione di Helm non farà nulla, poiché non tiene conto delle informazioni dell'applicazione nel cluster, ma Helm 3 riceverà le modifiche e invierà la nuova applicazione per il deploy.

Metodo 5. Utilizza l'opzione --recreate-pods

Con una chiave --recreate-pods puoi ottenere ciò che avevi originariamente pianificato di ottenere con la chiave --force. I contenitori si riavvieranno e, secondo la policy imagePullPolicy: Always for the latest tag (ulteriori informazioni nella nota a piè di pagina sopra), Kubernetes scaricherà e avvierà una nuova versione dell'immagine. Ciò non verrà fatto nel migliore dei modi: senza tenere conto dello StrategyType di distribuzione, spegnerà improvvisamente tutte le vecchie istanze dell'applicazione e inizierà ad avviarne di nuove. Durante il riavvio, il sistema non funzionerà, gli utenti ne soffriranno.

Anche nello stesso Kubernetes esisteva da molto tempo un problema simile. E ora, 4 anni dopo l'apertura Problema, il problema è stato risolto e, a partire dalla versione 1.15 di Kubernetes, appare la possibilità di riavviare i pod.

Helm disattiva semplicemente tutte le applicazioni e avvia nuovi contenitori nelle vicinanze. Non è possibile farlo in produzione, per non causare tempi di inattività dell'applicazione. Ciò è necessario solo per esigenze di sviluppo e può essere eseguito solo in ambienti scenici.

Come aggiornare la versione dell'applicazione utilizzando Helm?

Modificheremo i valori inviati a Helm. In genere si tratta di valori che vengono sostituiti al posto del tag immagine. Nel caso dell'ultimo, che viene spesso utilizzato per ambienti improduttivi, l'informazione modificabile è un'annotazione, inutile per Kubernetes stesso, e per Helm fungerà da segnale per la necessità di aggiornare l'applicazione. Opzioni per inserire il valore dell'annotazione:

  1. Valore casuale utilizzando la funzione standard - {{ randAlphaNum 6 }}.
    C'è un avvertimento: dopo ogni distribuzione che utilizza un grafico con tale variabile, il valore dell'annotazione sarà univoco e Helm presuppone che siano presenti modifiche. Si scopre che riavvieremo sempre l'applicazione, anche se non ne abbiamo modificato la versione. Questo non è fondamentale, poiché non ci saranno tempi di inattività, ma è comunque spiacevole.
  2. Incolla corrente data e ora - {{ .Release.Date }}.
    Una variante è simile a un valore casuale con una variabile permanentemente univoca.
  3. Un modo più corretto è usare checksum. Questo è lo SHA dell'immagine o lo SHA dell'ultimo commit in git - {{ .Values.sha }}.
    Dovranno essere conteggiati e inviati al client Helm dal lato chiamante, ad esempio in Jenkins. Se l'applicazione è cambiata, anche il checksum cambierà. Pertanto, Helm aggiornerà l'applicazione solo quando necessario.

Riassumiamo i nostri tentativi

  • Helm apporta modifiche nel modo meno invasivo, quindi qualsiasi modifica a livello di immagine dell'applicazione nel registro Docker non comporterà un aggiornamento: non accadrà nulla dopo l'esecuzione del comando.
  • Chiave --force utilizzato per ripristinare versioni problematiche e non è associato ad aggiornamenti forzati.
  • Chiave --recreate-pods aggiornerà forzatamente le applicazioni, ma lo farà in modo vandalico: spegnerà improvvisamente tutti i contenitori. Gli utenti ne soffriranno; non dovresti farlo in produzione.
  • Apporta direttamente modifiche al cluster Kubernetes utilizzando il comando kubectl edit non farlo: interromperemo la coerenza e il comportamento varierà a seconda della versione di Helm.
  • Con il rilascio della nuova versione di Helm sono emerse molte sfumature. I problemi nel repository Helm sono descritti in un linguaggio chiaro e ti aiuteranno a comprendere i dettagli.
  • L'aggiunta di un'annotazione modificabile a un grafico lo renderà più flessibile. Ciò ti consentirà di implementare l'applicazione correttamente, senza tempi di inattività.

Un pensiero di “pace nel mondo” che funziona in tutti gli ambiti della vita: leggere le istruzioni prima dell'uso, non dopo. Solo con informazioni complete sarà possibile costruire sistemi affidabili e rendere felici gli utenti.

Altri link correlati:

  1. Conoscere Casco 3
  2. Sito ufficiale del timone
  3. Repository Helm su GitHub
  4. 25 Strumenti utili di Kubernetes: distribuzione e gestione

Questo rapporto è stato presentato per la prima volta a @Conferenza Kubernetes di Mail.ru Soluzioni cloud. Aspetto video altri spettacoli e iscriviti agli annunci degli eventi su Telegram Intorno a Kubernetes nel gruppo Mail.ru.

Fonte: habr.com

Aggiungi un commento