ProHoster > BLOG > administrare > Implementarea aplicațiilor în mai multe clustere Kubernetes cu Helm
Implementarea aplicațiilor în mai multe clustere Kubernetes cu Helm
Cum folosește Dailymotion Kubernetes: Implementarea aplicației
Noi, cei de la Dailymotion, am început să folosim Kubernetes în producție acum 3 ani. Dar implementarea aplicațiilor în mai multe clustere este distractivă, așa că în ultimii ani am încercat să ne îmbunătățim instrumentele și fluxurile de lucru.
De unde a început
Aici vom acoperi modul în care implementăm aplicațiile noastre în mai multe clustere Kubernetes din întreaga lume.
Pentru a implementa mai multe obiecte Kubernetes simultan, folosim Cârmă, iar toate diagramele noastre sunt stocate într-un singur depozit git. Pentru a implementa o stivă completă de aplicații din mai multe servicii, folosim așa-numita diagramă rezumat. În esență, aceasta este o diagramă care declară dependențe și vă permite să inițializați API-ul și serviciile sale cu o singură comandă.
De asemenea, am scris un mic script Python deasupra lui Helm pentru a face verificări, a crea diagrame, a adăuga secrete și a implementa aplicații. Toate aceste sarcini sunt efectuate pe o platformă centrală CI folosind o imagine docker.
Să trecem la subiect.
Notă. Pe măsură ce citiți acest lucru, primul candidat pentru lansare pentru Helm 3 a fost deja anunțat. Versiunea principală conține o serie întreagă de îmbunătățiri pentru a rezolva unele dintre problemele pe care le-am întâlnit în trecut.
Flux de lucru pentru dezvoltarea graficelor
Folosim ramificarea pentru aplicații și am decis să aplicăm aceeași abordare diagramelor.
Ramura dev folosit pentru a crea diagrame care vor fi testate pe clustere de dezvoltare.
Când o cerere de extragere este trimisă către maestru, sunt verificate în staging.
În cele din urmă, creăm o cerere de extragere pentru a comite modificările în ramură prod și să le aplici în producție.
Fiecare mediu are propriul său depozit privat care stochează diagramele noastre și le folosim Chartmuseum cu API-uri foarte utile. În acest fel, asigurăm izolarea strictă între medii și testarea diagramelor în lumea reală înainte de a le folosi în producție.
Arhivele de diagrame în diferite medii
Este demn de remarcat faptul că atunci când dezvoltatorii împing o ramură către dev, o versiune a diagramei lor este trimisă automat în dev Chartmuseum. Astfel, toți dezvoltatorii folosesc același depozit de dezvoltare și trebuie să specificați cu atenție versiunea diagramei pentru a nu folosi accidental modificările altcuiva.
Mai mult, micul nostru script Python validează obiectele Kubernetes cu specificațiile Kubernetes OpenAPI folosind Kubeval, înainte de a le publica pe Chartmusem.
Descrierea generală a fluxului de lucru pentru dezvoltarea graficelor
Configurarea sarcinilor pipeline conform specificațiilor gazr.io pentru controlul calității (scame, test unitar).
Impingerea unei imagini docker cu instrumente Python care implementează aplicațiile noastre.
Creșteți automat versiunea unei diagrame și a diagramelor părinte ale acesteia (diagrame care depind de diagrama care este schimbată).
Trimiterea unei diagrame la un Chartmuseum care se potrivește cu mediul său
Gestionarea diferențelor între clustere
Federația Clusterelor
A fost o vreme când am folosit federație de clustere Kubernetes, unde obiectele Kubernetes ar putea fi declarate de la un singur punct final API. Dar au apărut probleme. De exemplu, unele obiecte Kubernetes nu au putut fi create în punctul final de federație, ceea ce face dificilă întreținerea obiectelor federate și a altor obiecte pentru clustere individuale.
Pentru a rezolva problema, am început să gestionăm clusterele în mod independent, ceea ce a simplificat foarte mult procesul (am folosit prima versiune de federație; s-ar putea să se fi schimbat ceva în a doua).
Platformă geo-distribuită
Platforma noastră este distribuită în prezent în 6 regiuni - 3 local și 3 în cloud.
Implementare distribuită
Valorile globale Helm
Cele 4 valori globale Helm vă permit să identificați diferențele dintre clustere. Toate graficele noastre au valori minime implicite.
Aceste valori ajută la definirea contextului aplicațiilor noastre și sunt utilizate în diverse scopuri: monitorizare, urmărire, înregistrare în jurnal, efectuarea de apeluri externe, scalare etc.
„cloud”: avem o platformă hibridă Kubernetes. De exemplu, API-ul nostru este implementat în zonele GCP și în centrele noastre de date.
„env”: Unele valori se pot schimba pentru mediile care nu sunt de producție. De exemplu, definiții de resurse și configurații de autoscaling.
„regiune”: aceste informații ajută la determinarea locației clusterului și pot fi utilizate pentru a determina punctele finale din apropiere pentru servicii externe.
„clusterName”: dacă și când vrem să definim o valoare pentru un cluster individual.
Iată un exemplu concret:
{{/* Returns Horizontal Pod Autoscaler replicas for GraphQL*/}}
{{- define "graphql.hpaReplicas" -}}
{{- if eq .Values.global.env "prod" }}
{{- if eq .Values.global.region "europe-west1" }}
minReplicas: 40
{{- else }}
minReplicas: 150
{{- end }}
maxReplicas: 1400
{{- else }}
minReplicas: 4
maxReplicas: 20
{{- end }}
{{- end -}}
Exemplu de șablon Helm
Această logică este definită într-un șablon de ajutor pentru a evita aglomerarea Kubernetes YAML.
Anunțul de aplicare
Instrumentele noastre de implementare se bazează pe mai multe fișiere YAML. Mai jos este un exemplu despre modul în care declarăm un serviciu și topologia lui de scalare (numărul de replici) într-un cluster.
Aceasta este o schiță a tuturor pașilor care definesc fluxul nostru de lucru de implementare. Ultimul pas implementează aplicația în mai multe clustere de lucrători simultan.
Pașii de implementare Jenkins
Dar secrete?
În ceea ce privește securitatea, urmărim toate secretele din diferite locuri și le stocăm într-un seif unic Boltă în Paris.
Instrumentele noastre de implementare extrag valori secrete din Vault și, când vine timpul de implementare, le introduc în Helm.
Pentru a face acest lucru, am definit o mapare între secretele din Vault și secretele de care au nevoie aplicațiile noastre:
Am definit reguli generale de urmat la înregistrarea secretelor în Vault.
Dacă secretul se aplică la un anumit context sau cluster, trebuie să adăugați o anumită intrare. (Aici, clusterul context1 are propria sa valoare pentru parola secretă stack-app1-parola).
În caz contrar, se utilizează valoarea implicit.
Pentru fiecare articol din această listă în Secretul Kubernetes este inserată o pereche cheie-valoare. Prin urmare, șablonul secret din diagramele noastre este foarte simplu.
Acum separăm dezvoltarea diagramelor și a aplicațiilor. Aceasta înseamnă că dezvoltatorii trebuie să lucreze în două depozite git: unul pentru aplicație și unul pentru definirea implementării acesteia în Kubernetes. 2 depozite git înseamnă 2 fluxuri de lucru și este ușor pentru un începător să se încurce.
Gestionarea diagramelor generalizate este o bătaie de cap
După cum am spus deja, diagramele generice sunt foarte utile pentru identificarea dependențelor și implementarea rapidă a mai multor aplicații. Dar folosim --reuse-valuespentru a evita trecerea tuturor valorilor de fiecare dată când implementăm o aplicație care face parte din această diagramă generalizată.
Într-un flux de lucru de livrare continuă, avem doar două valori care se schimbă în mod regulat: numărul de replici și eticheta de imagine (versiune). Alte valori, mai stabile, sunt modificate manual, iar acest lucru este destul de dificil. Mai mult, o greșeală în implementarea unei diagrame generalizate poate duce la eșecuri grave, așa cum am văzut din propria noastră experiență.
Actualizarea mai multor fișiere de configurare
Când un dezvoltator adaugă o nouă aplicație, trebuie să schimbe mai multe fișiere: declarația aplicației, lista de secrete, adăugarea aplicației ca dependență dacă aceasta este inclusă în diagrama generalizată.
Permisiunile Jenkins sunt prea extinse în Vault
Acum avem unul AppRole, care citește toate secretele din Seif.
Procesul de rollback nu este automatizat
Pentru a derula înapoi, trebuie să rulați comanda pe mai multe clustere, iar acest lucru este plin de erori. Efectuăm această operație manual pentru a ne asigura că este specificat ID-ul corect al versiunii.
Ne îndreptăm către GitOps
Scopul nostru
Dorim să returnăm diagrama în depozitul aplicației pe care o implementează.
Fluxul de lucru va fi același ca pentru dezvoltare. De exemplu, atunci când o ramură este împinsă la master, implementarea va fi declanșată automat. Principala diferență între această abordare și fluxul de lucru actual ar fi aceea totul va fi gestionat în git (aplicația în sine și modul în care este implementată în Kubernetes).
Există mai multe avantaje:
Mult mai clar pentru dezvoltator. Este mai ușor să înveți cum să aplici modificările într-o diagramă locală.
Definiția de implementare a serviciului poate fi specificată chiar acolo unde este codul serviciu.
Gestionarea eliminării diagramelor generalizate. Serviciul va avea propria versiune Helm. Acest lucru vă va permite să gestionați ciclul de viață al aplicației (rollback, upgrade) la cel mai mic nivel, pentru a nu afecta alte servicii.
Beneficiile git pentru managementul diagramelor: anulați modificările, jurnalul de audit etc. Dacă trebuie să anulați o modificare a unei diagrame, puteți face acest lucru folosind git. Implementarea începe automat.
Ați putea lua în considerare îmbunătățirea fluxului de lucru de dezvoltare cu instrumente precum Scaffold, cu care dezvoltatorii pot testa modificările într-un context apropiat de producție.
Migrație în doi pași
Dezvoltatorii noștri folosesc acest flux de lucru de 2 ani, așa că dorim ca migrarea să fie cât mai nedureroasă posibil. Prin urmare, am decis să adăugăm un pas intermediar pe drumul către obiectiv.
Prima etapă este simplă:
Păstrăm o structură similară pentru configurarea implementării aplicației, dar într-un singur obiect numit DailymotionRelease.
1 lansare per aplicație (fără diagrame generalizate).
Diagrame din depozitul git al aplicației.
Am vorbit cu toți dezvoltatorii, așa că procesul de migrare a început deja. Prima etapă este încă controlată folosind platforma CI. Voi scrie o altă postare în curând despre faza a doua: cum am trecut la un flux de lucru GitOps Flux. Vă voi spune cum am configurat totul și ce dificultăți am întâmpinat (mai multe depozite, secrete etc.). Urmăriți știrile.
Aici am încercat să descriem progresul nostru în fluxul de lucru de implementare a aplicațiilor în ultimii ani, ceea ce a condus la gânduri despre abordarea GitOps. Încă nu am atins obiectivul și vom raporta rezultatele, dar acum suntem convinși că am procedat corect atunci când am decis să simplificăm totul și să-l apropiem de obiceiurile dezvoltatorilor.