Actualizarea unui cluster Kubernetes fără timp de nefuncționare

Actualizarea unui cluster Kubernetes fără timp de nefuncționare

Procesul de actualizare pentru clusterul dvs. Kubernetes

La un moment dat, atunci când utilizați un cluster Kubernetes, este nevoie să actualizați nodurile care rulează. Aceasta poate include actualizări de pachete, actualizări ale nucleului sau implementarea de noi imagini de mașini virtuale. În terminologia Kubernetes, acest lucru se numește „Perturbare voluntară”.

Această postare face parte dintr-o serie de 4 postări:

  1. Acest post.
  2. Închiderea corectă a podurilor într-un cluster Kubernetes
  3. Terminare întârziată a unui pod atunci când este șters
  4. Cum să evitați timpul de nefuncționare al clusterului Kubernetes folosind PodDisruptionBudgets

(aproximativ. Așteptați-vă traduceri ale articolelor rămase din serie în viitorul apropiat)

În acest articol, vom descrie toate instrumentele pe care Kubernetes le oferă pentru a obține un timp de nefuncționare zero pentru nodurile care rulează în clusterul dvs.

Definirea problemei

Vom adopta o abordare naivă la început, vom identifica problemele și vom evalua riscurile potențiale ale acestei abordări și vom construi cunoștințe pentru a rezolva fiecare dintre problemele pe care le întâlnim pe parcursul ciclului. Rezultatul este o configurație care folosește cârlige pentru ciclul de viață, sonde de pregătire și bugete de întrerupere a podului pentru a atinge obiectivul nostru de nefuncționare zero.

Pentru a începe călătoria noastră, să luăm un exemplu concret. Să presupunem că avem un cluster Kubernetes de două noduri, în care rulează o aplicație cu două pod-uri situate în spate Service:

Actualizarea unui cluster Kubernetes fără timp de nefuncționare

Să începem cu două pod-uri cu Nginx și Service care rulează pe cele două noduri ale clusterului Kubernetes.

Dorim să actualizăm versiunea de kernel a două noduri de lucru din clusterul nostru. Cum facem asta? O soluție simplă ar fi să pornești noduri noi cu configurația actualizată și apoi să închizi nodurile vechi în timp ce le pornești pe cele noi. Deși acest lucru va funcționa, vor exista câteva probleme cu această abordare:

  • Când dezactivați nodurile vechi, podurile care rulează pe ele vor fi, de asemenea, oprite. Ce se întâmplă dacă podurile trebuie curățate pentru o oprire grațioasă? Este posibil ca sistemul de virtualizare pe care îl utilizați să nu aștepte finalizarea procesului de curățare.
  • Ce se întâmplă dacă dezactivați toate nodurile în același timp? Veți obține timp de nefuncționare decent în timp ce podurile se mută în noduri noi.

Avem nevoie de o modalitate de a migra cu grație pod-urile de la nodurile vechi, asigurându-ne în același timp că niciunul dintre procesele noastre de lucru nu rulează în timp ce facem modificări nodului. Sau când facem o înlocuire completă a clusterului, ca în exemplu (adică înlocuim imaginile VM), vrem să transferăm aplicațiile care rulează de la noduri vechi la altele noi. În ambele cazuri, dorim să împiedicăm programarea noilor poduri pe nodurile vechi și apoi să scoatem toate podurile care rulează din ele. Pentru a atinge aceste obiective putem folosi comanda kubectl drain.

Redistribuirea tuturor podurilor dintr-un nod

Operația de scurgere vă permite să redistribuiți toate podurile dintr-un nod. În timpul execuției drenării, nodul este marcat ca neprogramabil (flag NoSchedule). Acest lucru împiedică apariția noilor păstăi pe el. Apoi drenajul începe să scoată păstăile din nod, închide containerele care rulează în prezent pe nod, trimițând un semnal TERM recipiente într-o păstaie.

Deși kubectl drain va face o treabă grozavă de evacuare a păstăilor, există alți doi factori care pot duce la eșecul operațiunii de scurgere:

  • Aplicația dvs. trebuie să se poată termina cu grație la trimitere TERM semnal. Când podurile sunt evacuate, Kubernetes trimite un semnal TERM containere și așteaptă ca acestea să se oprească pentru o anumită perioadă de timp, după care, dacă nu s-au oprit, le oprește forțat. În orice caz, dacă containerul dvs. nu percepe semnalul corect, puteți totuși stinge incorect podurile dacă rulează în prezent (de exemplu, o tranzacție în baza de date este în curs).
  • Pierzi toate podurile care conțin aplicația ta. Este posibil să nu fie disponibil atunci când containere noi sunt lansate pe noduri noi sau dacă podurile dvs. sunt implementate fără controlere, este posibil să nu repornească deloc.

Evitarea timpului de nefuncţionare

Pentru a minimiza timpul de nefuncționare din cauza întreruperii voluntare, cum ar fi de la o operațiune de scurgere pe un nod, Kubernetes oferă următoarele opțiuni de gestionare a defecțiunilor:

În restul seriei, vom folosi aceste caracteristici Kubernetes pentru a atenua impactul migrării podului. Pentru a ușura urmărirea ideii principale, vom folosi exemplul nostru de mai sus cu următoarea configurație a resurselor:

---
apiVersion: apps/v1
kind: Deployment
metadata:
 name: nginx-deployment
 labels:
   app: nginx
spec:
 replicas: 2
 selector:
   matchLabels:
     app: nginx
 template:
   metadata:
     labels:
       app: nginx
   spec:
     containers:
     - name: nginx
       image: nginx:1.15
       ports:
       - containerPort: 80
---
kind: Service
apiVersion: v1
metadata:
 name: nginx-service
spec:
 selector:
   app: nginx
 ports:
 - protocol: TCP
   targetPort: 80
   port: 80

Această configurație este un exemplu minim Deployment, care gestionează podurile nginx din cluster. În plus, configurația descrie resursa Service, care poate fi folosit pentru a accesa pod-urile nginx într-un cluster.

De-a lungul ciclului, vom extinde iterativ această configurație, astfel încât să includă în cele din urmă toate capabilitățile pe care Kubernetes le oferă pentru a reduce timpul de nefuncționare.

Pentru o versiune complet implementată și testată a actualizărilor clusterului Kubernetes pentru zero timpi de nefuncționare pe AWS și nu numai, vizitați Gruntwork.io.

Citiți și alte articole de pe blogul nostru:

Sursa: www.habr.com

Adauga un comentariu