Differences

This shows you the differences between two versions of the page.

Link to this comparison view

rl:labs:11:contents:05 [2019/12/08 22:04]
cosmin.prunaru [06. [BONUS - 10p] Feedback]
rl:labs:11:contents:05 [2024/01/10 10:28] (current)
laura.ruse [05. [15p] Cloud Router]
Line 1: Line 1:
-==== 05. [20pOrchestrare cu Docker SWARM ====+====== 05. [15pCloud Router ======
  
-Am ajuns în punctul în care trebuie să lansăm site-ul în producție și stim că trebuie să ne preocupăm de aspecte precum scalabilitate (capacitatea de a suporta o încărcătură mai mare de lucru - un caz particular pentru perioada sărbătorilor),​ high-availability (Service-Level Agreement stabilit la 99%), redundanță sau toleranță la defecte (auto-healing). În forma standard, Docker Engine nu poate asigura niciunul din aspectele prezentate anterior, el furnizând doar un runtime de containerizare. Pentru a suporta constrângerile de producție, într-o formă autonomă și automată, este necesar un sistem de clusterizare și orchestrare. Soluția pe care o vom utiliza poartă numele de Docker SWARM. ​ 
  
-Docker SWARM este o soluție existentă în piață pentru orchestrarea de containere de tip Docker, ​în competiție cu platforme precum Kubernetes, Apache Mesos, OpenShift ș.a. Avantajul principal cu care vine platforma este ușurința în instalare ​și configurare,​ fiind un produs integrat nativ în Engine-ul de Docker. Din perspectivă arhitecturală,​ un cluster de Docker SWARM este alcătuit din două tipuri de noduri: Master Node - implementează nivelul de control, preluând cererile de deployment și monitorizând continuu starea cluster-ului Docker; Worker Node - asigură execuția containerelor solicitate de nivelul de control+Căutăîn câmpul din centru **Cloud Router** din secțiunea **Hybrid Connectivity** ​și selectăm **Create Router**.
  
-{{ :​rl:​labs:​11:​contents:​swarm.png?nolink |}}+<note tip> Căutați **Cloud Router** în bara de căutare pentru a găsi secțiunea</​note>​
  
-În cadrul laboratorului,​ vom utiliza o implementare simplificată, cu 2-3 noduri (1 master care are rol și de worker și 1-2 workers dedicați). ​**Pentru a simplifica necesarul de resurse, veți lucra în echipe de câte 2 sau 3 persoaneO mașină virtuală va avea rol de Master, iar celelalte VM-uri vor deservi ca Workers:**+Numele pe care îl alocăm Routerului nou creat este **student$X$-router**. (e.g. student1-router) 
 +Trebuie să îl alocăm VPC-ului creat la exercițiul anterior.
  
-{{ :​rl:​labs:​11:​contents:​master-worker-simple.png?​nolink |}} +Regiunea selectată va fi aceeași ca la subpunctele anterioare ​(preferabil ​**europe-west1**).
- +
-Înainte de a începe secțunea următoare, vom curăța nodurile de obiectele Docker create în exercițiile anterioare:​ +
- +
- +
-<code bash>​student@aldebaran:​~$ docker rm -f rl-frontend rl-backend rl-database</​code>​ +
-<code bash>​student@aldebaran:​~$ docker volume prune</​code>​ +
-<code bash>​student@aldebaran:​~$ docker system prune</​code>​ +
- +
-Totodată, pentru a simplifica terminologia utilizată în continuare, numim: +
-  * MASTER - nodul/VM-ul care a fost ales, în cadul echipei, ca Docker SWARM master +
-  * WORKER - nodurile/​VM-urile care au fost alese, în cadrul echipei, ca Docker SWARM workers  +
- +
-Pe nodul (VM) MASTER: +
-<code bash>​student@aldebaran:​~$ docker swarm init --advertise-addr <IP interfață eth0></​code>​ +
- +
-Din outputul anterior puteți obține comanda de join pe care o puteți utiliza pe nodurile care vor deservi ca workers. In cazul în care ulterior doriți să atașați noi noduri clusterului,​ puteți obține comanda anterioară astfel: +
-<code bash>​student@aldebaran:​~$ docker swarm join-token worker</​code>​ +
- +
-Pe celelalte noduri (pe nodurile WORKER): +
- +
-<code bash>​student@aldebaran:​~$ docker swarm join --token <SWARM cluster token> <IP interfață eth0 MASTER>:​2377</​code>​ +
- +
-Pe MASTER: +
-<code bash>​student@aldebaran:​~$ docker node ls</​code>​ +
- +
-În continuare vom vedea cum utilizarea unei soluții de orchestrare poate simplifica mentenanța,​ în producție, a unei aplicații critice, oferind capabilități și mecanisme de  auto-healing,​ scheduling sau replicare.  +
- +
-Pe MASTER vom face o cerere de construire a unui tip special de setup de rețea, facil rulării aplicației noastre în mod distribuit, pe diverse noduri ale clusterului:​ +
- +
-<code bash>​student@aldebaran:​~$ docker network create -d overlay rlapp-overlay</​code>​ +
- +
-Ulterior acestui pas, vom crea fiecare componentă a aplicație. În configurația curentă, toate cele 3 servicii vor fi conectate la același obiect de rețea: +
- +
-<code bash>​student@aldebaran:​~$ docker service create --name=rl-database \ +
-   -e MYSQL_DATABASE=rl-database \ +
-   -e MYSQL_USER=rl-user \ +
-   -e MYSQL_PASSWORD=rl-specialpassword \ +
-   -e MYSQL_ROOT_PASSWORD=root \ +
-   -e TZ=Europe/​Bucharest \ +
-   ​--network=rlapp-overlay \ +
-   ​--replicas 1 \ +
-   ​mysql +
-[...] +
-student@aldebaran:​~$ docker service create --name=rl-backend ​ \ +
-   -e DB_SERVER=rl-database \ +
-   ​--network=rlapp-overlay \ +
-   ​--replicas 1 \ +
-   ​rlrules/​docker-lab-backend +
-[...] +
-student@aldebaran:​~$ docker service create --name=rl-frontend ​ \ +
-   -e BACKEND_SERVER=rl-backend \ +
-   -p 8080:80 --network rlapp-overlay \ +
-   ​--replicas 1 \ +
-   ​rlrules/​docker-lab-frontend +
-[...] +
-</​code>​ +
- +
-Pentru a verifica distribuția serviciilor containerizate pe nodurile disponibilite:​ +
-<code bash>​student@aldebaran:​~$ docker service ls</​code>​ +
-<code bash>​student@aldebaran:​~$ docker service ps <numele serviciului></​code>​ +
- +
-Pentru a vedea doar acele containere care sunt în running state: +
-<code bash>​student@aldebaran:​~$ docker service ps <numele serviciului>​ -f desired-state=running</​code>​ +
- +
-Pentru simplitate, vom putea utiliza filtre: +
-<code bash>​student@aldebaran:​~$ docker service ps $(docker service ls -q) -f desired-state=running</​code>​ +
- +
-Din perspectiva unui orchestrator,​ Docker SWARM trebuie să se asigure că starea serviciilor pe care le-am lansat este consistentă. În cazul în care un serviciu(container) pică, SWARM trebuie să readucă starea clusterului la cea configurată. Pentru fiecare serviciu lansat anterior, am setat o constrângere particulară,​ care desemnează o stare a clusterului pe care o vrem constantă: ''​--replicas 1''​. Să validăm faptul că Docker SWARM are capabilitatea de self-healing,​ aspect ce ne permite să stabilim prerogativele asigurării unui disponibilități crescute a aplicației web de partajare de imagini.  +
- +
-<code bash>​student@aldebaran:​~$ docker service ps rl-frontend -f desired-state=running</​code>​ +
-În coloana NODE vedem unde a fost planificată execuția containerului asociat serviciului de frontend. +
- +
-Pe nodul anterior obținut vom șterge container-ul de frontend: +
-<code bash>​student@aldebaran:​~$ docker ps -f name=rl-frontend*</​code>​ +
-<code bash>​student@aldebaran:​~$ docker rm -f <nume container sau id container></​code>​ +
- +
-Pe MASTER: +
-<code bash>​student@aldebaran:​~$ watch docker service ps rl-frontend -f desired-state=running</​code>​ +
- +
-Se poate vedea cum Docker SWARM a sesizat modificările aduse stării clusterului și a relansat unui nou container de frontend. +
- +
-Într-un scenariu realist, simpla oprire a execuției unui container nu este singurul scenariu valid, ce trebuie luat în considerare,​ pentru a stabili dacă un serviciu este disponibil sau nu. Ce se întâmplă dacă aplicația rulează în continuare în container, dar intră într-un context de eroare ​ca de exemplu: o buclă infinită? Docker poate asigura mecanisme de probing, însă, într-un design matur, efortul de auto-healing trebuie susținut atât de runtime-ul de containerizare cât și de aplicația care rulează în container. +
- +
-Știm, din incipit, faptul că în perioada sărbătorilor va exista un spike în utilizarea platformei de sharing de poze, astfel încât se conturează scenariul probabil ca serviciul de frontend, expus către exterior, să fie bombardat de cereri HTTP și să cedeze în fața numărului de conexiuni lansate către acesta. O soluție simplă pentru o astfel de problemă o reprezintă multiplicarea serviciului preconizat a fi afectat. Traficul HTTP va trebui, totodată, balansat echitabil între instanțele (replicile) serviciului multiplicat. +
- +
-{{ :​rl:​labs:​11:​contents:​architecture-comparison.png?​nolink |}} +
- +
-Cu Docker SWARM implementarea unui astfel de model de rețea redundant se poate realiza simplu, întrucât orchestratorul oferă posibilitatea creșterii numărului de replici ale unui container și totodată oferă nativ funcția de balansare între instanțele aplicației replicate. Să validăm aceste capabilități:​ +
- +
-<code bash>​student@aldebaran:​~$ docker service scale rl-frontend=3</​code>​ +
-<code bash>​student@aldebaran:​~$ docker service ps rl-frontend -f desired-state=running</​code>​ +
- +
-Din browser, incercați să vă conectați ​la aplicație utilizând IP-ul MASTER-ului atât dintr-o fereastră normală cât și dintr-o fereastră incognito/​private. +
-<note important>​Dați refresh de mai multe ori paginii. Ce observați?</​note>​  +
- +
-{{ :​rl:​labs:​11:​contents:​load-balancer-node-difference.png?​nolink |}} +
- +
-Id-ul din colțul dreapta sus este id-ul unic al containerului în care rulează instanța de frontend. Întrucât am creat 3 replici ale aplicației,​ Docker SWARM va balansa traficul(load) către toate instanțele generate. +
- +
-Mai mult, încercați să vă conectați la aplicație utilizând IP-ul Worker1 sau/și IP-ul Worker2. Funcționează?​ +
-Un port expus în cadrul unui cluster Docker SWARM este disponibil pe întreaga componență a clusterului. Astfel, pentru accesa o aplicație expusă este suficient să cunosc una din adresele nodurilor clusterului și portul aplicației,​ fără a conta explicit unde rulează containerul. +
- +
-<note tip>​Chiar și cu capabilitatea nativă de balansare pe care o aduce Docker SWARM, în producția reală, în cele mai multe cazuri, ​ se recomandă utilizarea unor appliances dedicate, optimizate pentru funcția de **Load Balancing**.</​note>​  +
- +
-Revenind la comparația dintre arhitecturi pe microservicii și arhitecturi monolite, observăm oportunitatea de scalare granulară, per serviciu/​feature,​ cu care vine un model loosely coupled. În imaginea de mai jos se poate vedea metoda de scalare orizontală ce poate fi aplicată în ambele abordări: aplicații monolit și aplicații distribuite pe microservicii.  +
- +
-{{ :​rl:​labs:​11:​contents:​microservice-scaling.png?​nolink |}} +
- +
-Deși aparențele pot sugera faptul că o aplicație modelată pe microservicii poate rezolva multe din problemele de producție, efortul dezvoltării unei aplicații pe microservicii poate fi semnificativ mai mare, amintind aici faptul că trebuie definit și dezvoltat un mecanism de comunicare slab cuplat (exemplu REST API), trebuie asigurate mecanisme pentru consistența datelor, în contexul scalării orizontale prin multiplicare (acces atomic asupra bazei de date etc.), trebuie realizată o distribuției echitabilă a efortului de procesare pe diversele replici, trebuie asigurate mecanisme de comunicare asincronă (așa cum se poate vedea în Scenariul complex de mai sus) etc. Cu toate acestea piața oferă framework-uri care să faciliteze dezvoltarea de aplicații construite peste o infrastructura de tipcloud și peste un model bazat pe microservicii. Spre exemplu: SpringBoot - framework de Java, Kabanero, lansat în vara anului 2019 de către IBM, oferă unelte pentru dezvoltarea directă peste Kubernetes etc. +
- +
-Pentru a reveni la structura inițială, după trecerea perioadei sărbătorilor,​ putem face scale-down:​ +
-<code bash>​student@aldebaran:​~$ docker service scale rl-frontend=1</​code>​ +
-<code bash>​student@aldebaran:​~$ docker service ps rl-frontend</​code>​ +
- +
-În acest laborator am iterat prin câteva concepte din lumea Docker și totodată am adresat probleme și concepte de system design. Echipa de RL speră să vi le însușiți și să vă fie benefice în carieră. +
- +
-Cunoștințe acumulate:​ +
-  * Intoducere în Docker CLI +
-  * Docker Container vs Docker Image +
-  * Dockerfile și construcția de Imagini +
-  * CMD vs ENDPOINT +
-  * Union File System: Overlay2 - image layers +
-  * Docker Volumes +
-  * Mount binding vs volumes +
-  * Docker Networking: bridge & overlay (VXLAN) +
-  * Docker SWARM +
-  * Introducere în arhitecturi pe microservicii +
-  * Arhitecturi pe microservicii vs Arhitecturi monolite+
  
 +<note warning>​GCP impune o limitare de maxim **5 Cloud Router pentru fiecare regiune**. Dacă nu mai puteți face un Cloud Router în regiunea **europe-west1**,​ îl puteți face în altă regiune din Europa. **Această regiune trebuie să fie aceeași cu cea a VPC-ului creat anterior**.</​note>​
  
 +{{ :​rl:​labs:​12:​contents:​cloud-router.png?​600 |}}
rl/labs/11/contents/05.1575835482.txt.gz · Last modified: 2019/12/08 22:04 by cosmin.prunaru
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0