Dezvoltarea aplicațiilor și Blue-Green deployment, bazându-se pe metodologia The Twelve-Factor App cu exemple în php și docker

Dezvoltarea aplicațiilor și Blue-Green deployment, bazându-se pe metodologia The Twelve-Factor App cu exemple în php și docker

Pentru început, un pic de teorie. Ce este Aplicația în Douăsprezece Factori?

Pe scurt, acesta este un document destinat să simplifice dezvoltarea aplicațiilor SaaS, ajutându-i pe dezvoltatori și inginerii DevOps să înțeleagă problemele și practicile care au fost întâlnite cel mai des în dezvoltarea aplicațiilor moderne.

Documentul este elaborat de dezvoltatorii platformei Heroku.

Metodologia aplicației în douăsprezece factori (The Twelve-Factor App) poate fi aplicată aplicațiilor scrise în orice limbaj de programare și care utilizează orice combinații de servicii externe (backing services) (baze de date, cozi de mesaje, memorie cache etc.).

Iată pe scurt factorii pe care se bazează această metodologie:

  1. Baza de cod – O singură bază de cod, urmărită în sistemul de control al versiunilor, – multe desfășurări
  2. Dependințe – Declarați și izolați clar dependențele
  3. Configurație – Păstrați configurația în mediu de execuție
  4. Servicii externe (Backing Services) – Considerați serviciile externe (backing services) ca resurse interconectabile
  5. Compilare, lansare, execuție – Separați strict etapele de compilare și execuție
  6. Procese – Rulați aplicația ca unul sau mai multe procese fără stare (stateless)
  7. Legarea de porturi (Port binding) – Exportați serviciile prin legarea de porturi
  8. Paralelism – Scalarea aplicației prin procese
  9. Utilizabilitate (Disposability) – Maximizează fiabilitatea prin pornire rapidă și oprire corectă
  10. Paritatea dezvoltării / rulării aplicației – Mențineți mediile de dezvoltare, desfășurare intermediară (staging) și desfășurare în producție cât mai asemănătoare
  11. Jurnalizare (Logs) – Tratați jurnalul ca un flux de evenimente
  12. Sarcini administrative – Executați sarcini administrative / de gestionare prin procese unice

Mai multe informații despre cei 12 factori pot fi obținute din următoarele resurse:

Ce este implementarea Blue-Green?

Implementarea Blue-Green este o metodă de livrare a aplicației pe producție astfel încât clientul final să nu observe nicio schimbare din partea lui. Cu alte cuvinte, desfășurarea aplicației cu zero timp de nefuncționare.

Schema clasică BG Deploy arată așa cum este indicat în imaginea de mai jos.

Dezvoltarea aplicațiilor și Blue-Green deployment, bazându-se pe metodologia The Twelve-Factor App cu exemple în php și docker

  • La început, există 2 servere fizice cu un cod absolut identic, aplicație, proiect și există un router (împărțitor de sarcini).
  • Routerul direcționează inițial toate cererile către unul dintre servere (verde).
  • În momentul în care trebuie să facem din nou un release, întreg proiectul este actualizat pe cealaltă server (albastru), care în acel moment nu prelucrează nicio cerere.
  • După ce codul de pe albastru server este complet actualizat, routerului i se dă comanda că trebuie să comute de la verde pe albastru server.
  • Acum toți clienții pot vedea rezultatul muncii codului de pe serverul albastru. O perioadă,
  • serverul servește ca backup în caz de un deploy ratat pe verde server și în caz de eșec și buguri, routerul comutează fluxul utilizatorilor înapoi pe albastru server cu vechea versiune stabilă, iar noul cod este trimis pentru îmbunătățire și testare. verde Și la finalul procesului, la fel se actualizează
  • serverul. Și după actualizarea acestuia, routerul comutează fluxul cererilor înapoi pe verde Arată foarte bine și, la prima vedere, nu ar trebui să existe probleme. verde server.

Dar, având în vedere că trăim în lumea modernă, opțiunea cu comutarea fizică, așa cum este indicat în schema clasică, nu ni se potrivește. Rețineți informația deocamdată, ne vom întoarce la ea mai târziu.
Sfaturi bune și proaste

: În exemplele de mai jos sunt indicate utilitarele / metodologiile pe care le folosesc eu, puteți folosi absolut orice alternative cu funcții similare.

DeclinareaCea mai mare parte din exemple va intersecta în oarecare măsură dezvoltarea web (surpriză), cu PHP și Docker.

În punctele de mai jos este o descriere practică simplă a utilizării factorilor pe anumite exemple, dacă doriți mai multă teorie pe această temă, consultați sursele de mai sus.

1. Baza de cod

Folosiți FTP și FileZilla pentru a încărca fișiere pe servere câte unu, nu păstrați codul altundeva decât pe serverul de producție.

În proiect ar trebui să existe întotdeauna o bază de cod unică, adică, tot codul provine dintr-o

Git Git repository. Serverele (production, staging, test1, test2, etc.) folosesc cod din ramuri ale unui singur repository comun. Astfel, obținem consistența codului.

2. Dependențe

Descărcați toate bibliotecile în foldere direct în rădăcina proiectului. Actualizările le faceți prin simpla transferare a noului cod în folderul cu versiunea curentă a bibliotecii. Instalați toate utilitarele direct pe serverul de hosting unde funcționează deja 20 de servicii.

Proiectul trebuie să aibă întotdeauna o listă clară de dependențe (sub dependențe înțeleg și mediu). Toate dependențele trebuie să fie definite flagrant și izolate.
Ca exemplu, să luăm Composer și Docker.

Composer — un manager de pachete care permite instalarea bibliotecilor în PHP. Composer oferă posibilitatea de a specifica versiuni strict sau liber și de a le defini clar. Pe server pot exista 20 de proiecte diferite și fiecare va avea propria listă de pachete și biblioteci, independent de celălalt.

Docker — un utilitar care permite definirea și izolarea mediu în care va funcționa aplicația. Așadar, similar cu composer, dar mai tematic, putem defini cu ce lucrează aplicația. Alegeți o anumită versiune PHP, instalați doar pachetele necesare pentru funcționarea proiectului, fără a adăuga nimic suplimentar. Și cel mai important, fără a se suprapune cu pachetele și mediul mașinii de hosting și al altor proiecte. Adică toate proiectele de pe server care funcționează prin Docker pot folosi orice set de pachete și medii complet diferite.

3. Configurare

Păstrați configurațiile ca constante direct în cod. Constate separate pentru serverul de testare, separate pentru producție. Legați funcționarea aplicației de mediu direct în logica de business a proiectului folosind structuri if else.

Configurări — aceasta este singura diferență între desfășurările proiectului (deployment). Ideal, configurațiile ar trebui să fie transmise prin variabile de mediu (env vars).

Adică, chiar dacă veți păstra mai multe fișiere de configurare .config.prod .config.local și le veți redenumi în momentul desfășurării în .config (configurația principală din care aplicația citește datele) — aceasta nu va fi o abordare corectă, deoarece, în acest caz, informațiile din configurații vor fi accesibile tuturor dezvoltatorilor aplicației și datele de pe serverul de producție vor fi compromise. Toate configurațiile trebuie să fie stocate direct în sistemul de desfășurare (CI/CD) și generate pentru diferite medii cu valori diferite necesare pentru fiecare mediu exact în momentul desfășurării.

4. Servicii externe (Backing Services)

Legat strâns de mediu, folosiți conexiuni diferite pentru aceleași servicii în medii specifice.

Acest punct se suprapune foarte mult cu punctul despre configurații, deoarece fără această cerință nu se pot crea date de configurare corespunzătoare, iar posibilitatea de configurare va dispărea complet.

Toate conexiunile la servicii externe, cum ar fi servere de mesaje, baze de date, servicii de cache, trebuie să fie identice atât pentru mediu local, cât și pentru mediu extern / de producție. Cu alte cuvinte, în orice moment, pot schimba linia de conexiune înlocuind apelurile la baza de date #1 cu baza de date #2 fără a modifica codul aplicației. Sau, pentru a anticipa, ca exemplu, la scalarea serviciului, nu va trebui să specificați o conexiune specială pentru un server de cache suplimentar.

5. Construire, lansare, execuție

Aveți pe server doar versiunea finală a codului, fără șanse de a reveni la o versiune anterioară. Nu este nevoie să ocupați spațiu pe disc. Cine crede că poate lansa un cod pe producție cu o eroare este un programator slab!

Toate etapele desfășurării trebuie să fie separate între ele.

Aveți opțiunea de a reveni înapoi. Faceți lansări păstrând în acces rapid copii vechi ale aplicației (deja construite și pregătite pentru utilizare), astfel încât, în cazul erorilor, să puteți restabili versiunea anterioară. Așa că, ipotetic, există un folder releases și un folder current, și după desfășurarea și construcția reușită, folderul current este legat printr-un link simbolic de noua lansare care se află în interior releases cu un nume asociat numărului de lansare.

Aici ne amintim de Blue-Green deployment, care permite nu doar comutarea între cod, ci și între toate resursele și chiar medii, cu posibilitatea de a reveni asupra tuturor schimbărilor.

6. Procese

Păstrați datele stărilor aplicației direct în aplicație. Utilizați sesiuni în memoria operațională a aplicației. Folosiți cât mai multe resurse partajate între serviciile externe. Asigurați-vă că aplicația poate avea un singur proces și nu permiteți scalarea.

În legătură cu sesiunile, păstrați datele doar în cache-ul controlat de serviciile externe (memcached, redis), astfel încât, chiar dacă aveți 20 de procese ale aplicației în execuție, orice proces care accesează cache-ul va putea continua să lucreze cu clientul în aceeași stare în care utilizatorul a fost când a interacționat cu aplicația din alt proces. Cu această abordare, indiferent câte copii ale serviciilor externe utilizați, totul va funcționa corespunzător și fără probleme în accesarea datelor.

7. Legarea porturilor (Port binding)

Numai serverul web trebuie să știe cum să lucreze cu serviciile externe. Sau ar fi mai bine să ridicați serviciile externe direct în serverul web. De exemplu, ca modul PHP în Apache.
Toate serviciile dumneavoastră trebuie să fie accessible unul altuia printr-o adresă și un port (localhost:5432, localhost:3000, nginx:80, php-fpm:9000), astfel, din nginx pot accesa atât php-fpm, cât și postgres, iar din php-fpm pot accesa postgres și nginx, iar din fiecare serviciu pot accesa alt serviciu. Astfel, viabilitatea unui serviciu nu depinde de viabilitatea altui serviciu.

8. Paralelism

Lucrați cu un singur proces, altfel, mai multe procese s-ar putea să nu funcționeze bine împreună!

Lăsați posibilitatea de scalare. Docker Swarm este un instrument excelent pentru acest lucru.
Docker Swarm este un instrument pentru crearea și gestionarea clusterelor de containere atât între diferite mașini, cât și între mai multe containere pe aceeași mașină.

Folosind swarm, pot determina cât de multe resurse voi aloca pentru fiecare proces și câte procese din același serviciu voi lansa, iar echilibratorul intern, primind date pe un port prestabilit, va face automat proxy pentru procesele respective. Astfel, observând că încărcarea pe server a crescut, pot adăuga mai multe procese, reducând astfel încărcarea pe anumite procese.

9. Utiilizabilitate (Disposability)

Nu folosiți cozi pentru a lucra cu procese și date. Oprirea unui proces ar trebui să influențeze funcționarea întregii aplicații. Dacă un serviciu se prăbușește, toate se prăbușesc.

Fiecare proces și serviciu pot fi oprite în orice moment și acest lucru nu ar trebui să afecteze celelalte servicii (aici nu mă refer la faptul că un serviciu va deveni inaccesibil pentru alt serviciu, ci că alt serviciu nu se va opri în urma acestuia). Toate procesele trebuie să se încheie în mod suav, astfel încât, la finalizarea lor, datele să nu fie afectate și la următoarea pornire sistemul să funcționeze corect. Adică chiar și în cazul unei opriri accidentale, datele nu ar trebui să fie afectate (aici se aplică mecanismul tranzacțiilor, cererile în bd funcționează doar în grupuri, și dacă măcar o cerere din grup nu a fost executată sau a fost executată cu eroare, atunci nici o altă cerere din grup nu va fi, în realitate, executată).

10. Paritatea dezvoltării/execuției aplicației

Produsul, stagingul și versiunea locală a aplicației trebuie să fie diferite. Pe producție avem frameworkul Yii Lite, iar local Yii, pentru a funcționa mai repede în producție!

În realitate, toate desfășurările și lucrul cu codul ar trebui să se efectueze într-un mediu aproape identic (nu este vorba despre hardware fizic). De asemenea, codul pe producție ar trebui să poată fi desfășurat, la nevoie, de orice membru al echipei de dezvoltare, nu doar de un departament devops specializat, care poate ridica aplicația în producție doar datorită unei puteri speciale.

Acest lucru ne ajută și Docker. Respectând toate punctele anterioare, utilizarea Docker va reduce procesul de desfășurare a mediului, atât pe producție, cât și pe mașina locală, la introducerea a una sau două comenzi.

11. Jurnalizare (Logs)

Scriem logurile în fișiere și bd! Nu curățăm fișiere și bd de loguri. Vom cumpăra pur și simplu un hard disk de 9000 de petabyte și va fi bine.

Toate logurile trebuie considerate ca un flux de evenimente. Aplicația în sine nu ar trebui să se ocupe cu procesarea logurilor. Logurile ar trebui fie să fie emise în stdout, fie să fie trimise printr-un protocol precum udp, astfel încât munca aplicației cu logurile să nu cauzeze nicio problemă. Graylog este o alegere bună pentru aceasta. Graylog, primind toate logurile prin udp (acest protocol nu necesită așteptarea unui răspuns pentru confirmarea recepției pachetului) nu interferează în niciun fel cu aplicația și se ocupă doar de structurarea și procesarea logurilor. Logica aplicației nu se schimbă pentru a lucra cu astfel de abordări.

12. Sarcini de administrare

Pentru actualizarea datelor, a bazei de date etc., utilizați un endpoint creat separat în API, executarea acestuia de două ori consecutiv va duce la duplicarea tuturor datelor. Dar voi nu sunteți proști, nu veți apăsa de două ori, iar migrațiile nu ne sunt necesare.

Toate sarcinile de administrare trebuie executate în aceeași mediu ca și tot codul, la nivelul versiunilor. Așadar, dacă trebuie să schimbăm structura bazei de date, nu vom face acest lucru manual prin schimbarea numelui coloanelor și adăugarea de noi coloane prin diferite instrumente vizuale de gestionare a bazei de date. Pentru asemenea lucruri creăm scripturi separate – migrații, care sunt executate oriunde și în toate medii uniform, cu un rezultat comun și clar. Pentru toate celelalte sarcini, cum ar fi popularea proiectului cu date, trebuie aplicate metodologii similare.

Exemplu de implementare pe PHP, Laravel, Laradock, Docker-Compose

P.S. Toate exemplele au fost realizate pe MacOS. Cele mai multe se potrivesc și pentru Linux. Utilizatorilor de Windows, îmi pare rău, dar nu am mai lucrat cu Windows de mult.

Să presupunem că pe PC-ul nostru nu este instalată nicio versiune de PHP și de fapt nu avem nimic.
Instalăm docker și docker-compose în cele mai recente versiuni. (acest lucru poate fi găsit pe internet)

docker -v && 
docker-compose -v

Dezvoltarea aplicațiilor și Blue-Green deployment, bazându-se pe metodologia The Twelve-Factor App cu exemple în php și docker

1. Instalăm Laradock

git clone https://github.com/Laradock/laradock.git && 
ls

Dezvoltarea aplicațiilor și Blue-Green deployment, bazându-se pe metodologia The Twelve-Factor App cu exemple în php și docker

Despre Laradock pot spune că este un lucru foarte grozav, în care sunt adunate multe containere și instrumente auxiliare. Dar nu aș recomanda utilizarea Laradock așa cum este fără modificări în producție din cauza excesului său. Este mai bine să creați propriile containere bazate pe exemplele din Laradock, astfel veți avea multe opțiuni de optimizare, deoarece nimănui nu-i trebuie tot ce există acolo simultan.

2. Configurăm Laradock pentru a funcționa cu aplicația noastră.

cd laradock && 
cp env-example .env

Dezvoltarea aplicațiilor și Blue-Green deployment, bazându-se pe metodologia The Twelve-Factor App cu exemple în php și docker

2.1. Deschidem catalogul habr (folderul părinte în care a fost clonat laradock) într-un editor. (În cazul meu, PHPStorm)

În acest stadiu, setăm doar numele proiectului.

Dezvoltarea aplicațiilor și Blue-Green deployment, bazându-se pe metodologia The Twelve-Factor App cu exemple în php și docker

2.2. Pornim imaginea workspace. (În cazul vostru, imaginile vor fi construite pentru o vreme)
Workspace-ul este o imagine special pregătită pentru a lucra cu framework-ul din perspectiva dezvoltatorului.

Accesăm în interiorul containerului folosind

docker-compose up -d workspace && 
docker-compose exec workspace bash

Dezvoltarea aplicațiilor și Blue-Green deployment, bazându-se pe metodologia The Twelve-Factor App cu exemple în php și docker

2.3. Instalăm Laravel

composer create-project --prefer-dist laravel/laravel application

Dezvoltarea aplicațiilor și Blue-Green deployment, bazându-se pe metodologia The Twelve-Factor App cu exemple în php și docker

2.4. După instalare, verificăm dacă a fost creată directorul cu proiectul și oprim compose.

ls
exit
docker-compose down

Dezvoltarea aplicațiilor și Blue-Green deployment, bazându-se pe metodologia The Twelve-Factor App cu exemple în php și docker

2.5. Ne întoarcem în PHPStorm și setăm calea corectă către aplicația noastră Laravel în fișierul .env.

Dezvoltarea aplicațiilor și Blue-Green deployment, bazându-se pe metodologia The Twelve-Factor App cu exemple în php și docker

3. Adăugăm tot codul în Git.

Pentru aceasta, vom crea un repository pe Github (sau altundeva). Accesăm terminalul în directorul habr și executăm următorul cod.

echo "# habr-12factor" >> README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin git@github.com:nzulfigarov/habr-12factor.git # aici va fi linkul către repository-ul vostru
git push -u origin master
git status

Verificăm dacă totul este în regulă.

Dezvoltarea aplicațiilor și Blue-Green deployment, bazându-se pe metodologia The Twelve-Factor App cu exemple în php și docker

Pentru confort, recomand să folosiți o oarecare interfață vizuală pentru Git, în cazul meu aceasta este GitKraken. (aici este un link de referral)

4. Pornim!

Înainte de a porni, asigurați-vă că nu aveți nimic pe porturile 80 și 443.

docker-compose up -d nginx php-fpm

Dezvoltarea aplicațiilor și Blue-Green deployment, bazându-se pe metodologia The Twelve-Factor App cu exemple în php și docker

Astfel, proiectul nostru constă în 3 servicii separate:

  • nginx — server web
  • php-fpm — php pentru preluarea cererilor de la serverul web
  • workspace — php pentru dezvoltator

Până în acest moment, am reușit să creăm o aplicație care corespunde deja la 4 puncte din 12, și anume:

1. Baza de cod — tot codul se află într-un singur repository (o mică observație: ar putea fi mai corect să integrăm docker în proiectul Laravel, dar nu este esențial).

2. Dependințe — Toate dependențele noastre sunt clar specificate în application/composer.json și în fiecare Dockerfile al fiecărui container.

3. Servicii externe (Backing Services) — Fiecare dintre servicii (php-fpm, nginx, workspace) trăiește viața sa și este conectată din exterior, iar atunci când lucrăm cu un serviciu, celelalte nu vor fi afectate.

4. Procese — fiecare serviciu reprezintă un proces. Fiecare dintre servicii nu își păstrează starea internă.

5. Legarea de porturi (Port binding)

docker ps

Dezvoltarea aplicațiilor și Blue-Green deployment, bazându-se pe metodologia The Twelve-Factor App cu exemple în php și docker

După cum vedem, fiecare serviciu este pornit pe propriul său port și este disponibil pentru toate celelalte servicii.

6. Paralelism

Docker ne permite să ridicăm mai multe procese ale acelorași servicii cu un balans automat al încărcării între ele.

Oprim containerele și le pornim cu ajutorul flag-ului —scale

docker-compose down && 
docker-compose up -d --scale php-fpm=3 nginx php-fpm

Dezvoltarea aplicațiilor și Blue-Green deployment, bazându-se pe metodologia The Twelve-Factor App cu exemple în php și docker

După cum vedem, containerul php-fpm a creat copii. Nu trebuie să facem nimic în lucrul cu acest container. De asemenea, continuăm să ne conectăm la el pe portul 9000, iar Docker reglează sarcina între containere.

7. Utilizabilitate (Disposability) — fiecare container poate fi oprit fără a afecta altul. Oprirea sau repornirea unui container nu va afecta funcționarea aplicației la lansările ulterioare. Fiecare container poate fi, de asemenea, ridicat oricând.

8. Paritatea dezvoltării / rulării aplicației — toate mediile noastre sunt identice. Rulând sistemul pe server în producție, nu va trebui să schimbi nimic în comenzile tale. Totul va fi bazat exact pe Docker.

9. Jurnalizare (Logs) — toate log-urile din aceste containere ies pe flux și sunt vizibile în consola Docker. (în acest caz, de fapt, cu alte containere personalizate, poate să nu fie așa dacă nu te ocupi de asta)

 docker-compose logs -f

Dezvoltarea aplicațiilor și Blue-Green deployment, bazându-se pe metodologia The Twelve-Factor App cu exemple în php și docker

Dar, aici este o problemă, deoarece valorile implicite în PHP și Nginx scriu de asemenea log-uri în fișier. Pentru a respecta cele 12 principii, este necesar a dezactiva scrierea log-urilor în fișier în configurațiile fiecărui container separat.

De asemenea, Docker oferă posibilitatea de a direcționa log-urile nu doar în stdout, ci și în lucruri precum graylog despre care am vorbit mai sus. Iar în interiorul graylog, putem opera log-urile cum dorim și aplicația noastră nu va observa asta.

10. Sarcini administrative — toate sarcinile de administrare sunt rezolvate de Laravel prin instrumentul artisan exact așa cum și-ar dori creatorii aplicației de 12 factori.

Ca exemplu, voi arăta cum se execută câteva comenzi.
Intrăm în container.

 
docker-compose exec workspace bash
php artisan list

Dezvoltarea aplicațiilor și Blue-Green deployment, bazându-se pe metodologia The Twelve-Factor App cu exemple în php și docker

Acum putem folosi orice comandă. (rețineți că nu am configurat baza de date și cache-ul, așa că jumătate din comenzi nu se vor executa corect, deoarece sunt destinate lucrului cu cache-ul și baza de date).

Dezvoltarea aplicațiilor și Blue-Green deployment, bazându-se pe metodologia The Twelve-Factor App cu exemple în php și docker

11. Configurări și 12. Compilare, lansare, execuție

Această parte voiam să o dedic Blue-Green Deployment, dar s-a dovedit prea extinsă pentru acest articol. Voi scrie un articol separat despre asta.

Pe scurt, conceptul se bazează pe sistemele CI/CD de tipul Jenkins și Gitlab CI. Atât în unul, cât și în celălalt, poți defini variabile de mediu legate de un mediu specific. Prin urmare, în acest context, se va realiza punctul cu Configurațiile.

Iar punctul despre Compilare, lansare, execuție se rezolvă prin funcțiile încorporate în ambele instrumente cu numele Pipeline.

Pipeline permite divizarea procesului de deploy în mai multe etape, evidențiind etapele de construire, lansare și execuție. De asemenea, în Pipeline, veți putea crea backup-uri și, în general, orice doriți. Acest instrument are un potențial nelimitat.

Codul aplicației se află pe Github.
Nu uitați să inițializați submodulele la clonarea acestui repository.

P.S.: Toate aceste metode pot fi folosite cu orice alte utilitare și limbaje de programare. Important e ca esența să nu se schimbe.

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster