Differences

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

Link to this comparison view

rl:labs:11:contents:03 [2022/11/15 11:13]
florin.stancu
rl:labs:11:contents:03 [2024/01/08 12:35] (current)
vlad_iulius.nastase [03. [10p] VPC Subnets]
Line 1: Line 1:
-==== 03. [20pDocker Networking====+====== 03. [10pVPC Subnets ======
  
-In cazul rulării unui container Docker există necesitatea stabilirii comunicației către exterior prin rețele virtuale sau prin configurații particulare de rețea. Avantajul major îl constituie faptul că multe din aspectele anevoioase de configurare sunt abstractizate, ​ fiind reduse la un număr mic de obiecte predefinite ce pot fi utilizate pentru scenarii complexe. O parte din terminologia aferentă Docker networking se poate găsi în tabelul următor, unde vom defini Driverele Docker - acele obiecte de rețea predefinite ​ cu care vine Docker Engine-ul și care facilitează comunicarea la nivelul containerelor:​ 
  
-^    Driver network ​     ^     ​Descriere ​      ^ +Pentru a lansa instanțe într-un ​**VPC** trebuie să avem cel puțin un **subnet**. Vom avea nevoie ​de alte 3 **subnets** diferite create, similar cu cea de la pasul anterior, fiecare ​**subnet** având definită o subrețea diferită.
-|  ​**bridge**    ​| ​ tip de driver utilizat în mod implicit, util pentru aplicații care stau în containere individuale și care au nevoie de conectivitate între ele sau către exterior ​ | +
-|  ​**host**   |  disponibil doar în SWARM mode, tip de network care partajează rețeaua cu mașina gazdă ​   | +
-|  ​**overlay**    ​| ​ tip de driver care permite comunicarea între containere aflate pe noduri Docker diferite din rețele diferite - comunicare ​la nivel 2 utilizând VXLAN     | +
-|  ​**macvlan**  ​| ​ tip de network care alocă containerelor adrese MAC și permit atașarea container-ului în aceiași rețea cu sistemul gazdă  | +
-|  **none** ​ |  tip de driver care dezactivează conectivitatea la rețea ​ |+
  
-Referințe:  +În laboratorul de astăzi toate subrețelele vor fi definite ​în aceeași regiune (aceeași cu a VPC Network-ului creat la punctul anterior)
-  * https://​www.youtube.com/​watch?​v=Yr6-2ddhLVo +
-  * http://​blog.nigelpoulton.com/​demystifying-docker-overlay-networking/​ +
-  * https://​docs.docker.com/​network/​ +
-În continuare vom începe să construim aplicația de sharing de imagini, realizând ​în paralel ​și comunicația între serviciile componente, în concordanță ​cu modelul slab cuplat ales.+
  
-=== Expunerea către exterior a serviciilor dintr-un container ===+Mai departe, vom crea 3 subnetări in VPC creat la pasul anterior(pentru instanțele **Red**, **Green**, **Blue**).
  
-Să încercăm să lansăm serviciul ​de frontend. Întrucât acesta va fi expus către exterior, ​pentru ​a fi accesibil din browser, vom publica portul 80 al containerului:​ +Masca de rețea corespunzătoare (/24 pentru ​subnet-urile private):
-<code bash> +
-student@aldebaran:​~$ docker run -d --name=rl-frontend ​ \ +
-   -e BACKEND_SERVER=rl-backend \ +
-   -p 8080:80 \ +
-   ​rlrules/​docker-lab-frontend +
-</​code>​+
  
-Parametrul -p (publish) cu valoarea 8080:80 (<port sistem gazdă>:<​port container>​) expune/alocă pe mașina gazdă portul TCP 8080, urmând ca traficul orientat către acest port să fie trimis, mai departe, către socket-ul containerului expus pe portul TCP 80.  +  * **10.$X$.1.0/24** 
-<note important>​Unde ați mai văzut un astfel de setup? Cum se numește acest procedeu?<​/note>+  * **10.$X$.2.0/​24** 
 +  * **10.$X$.3.0/24**, unde $X$ - id-ul studentului
  
-Prin abstractizarea implementată prin flag-ul publish, Docker crează, în backstage, o regulă iptables de DNAT (port-forwarding) care redirecționează traficul venit pe portul TCP/8080 al mașinii gazdă către portul TCP/80 de pe containerÎn plus, o altă regulă definită prin utilizarea publish, permite traficul destinat interfeței virtuale docker0 (network de tip bridge, creat implicit la instalarea Docker, util pentru a conecta toate containerele care nu au o configurație de rețea particulară).+Recomandăm ca numele pentu subnet-uri să fie sugestivePentru exercițiul nostru:
  
-<code bash> +  * **student$X$-red** 
-student@aldebaran:​~sudo iptables ​-L -nv -t filter +  * **student$X$-green** 
-student@aldebaran:​~sudo iptables ​--nv -t nat +  * **student$X$-blue**, unde $X$ id-ul studentului
-</​code>​+
  
-<note important>​Care sunt regulile de iptables care au fost generate de parametrul publish?</​note>​ 
  
-<code bash> +Din secțiunea VPC Networksdacă mergem ​pe **Subnets in current project** și selectădoar VPC-network-ul creat de noi anterior ​(excludem default), ar trebui ​să avem următoarea listă:
-student@aldebaran:​~$ sudo iptables -L -nv -t filter | grep -i 80 -A 3 -B 3 +
-student@aldebaran:​~$ sudo iptables -L -nv -t nat | grep -i 8080 -A 3 -B 3 +
-</​code>​ +
- +
-Un bridge network, așa cum se auto-definește,​ este un echipament (appliance) virtual care permite comunicarea la nivel 2 a entităților de rețea conectate la acesta. În sensul terminologiei Dockerun bridge network adaugă suplimentar capabilității anterior definite, o configurație de Default Gateway la nivelul interfeței virtuale a containerului și implementarea de **Masquerade - Network Address Translation/​Port Address Translation (NAT/​PAT)**. În acest fel, containerul va putea accesa, utilizând conectivitatea sistemului gazdă, resurse externe din afara rețelei sau Internet. +
- +
-<note important>​ +
-**Dacă rulați ​pe platforma OpenStack a facultății**, rețeaua ''​10.9.X.Y''​ nu este accesibilă din Internet, și, din păcate, nici de pe Wifi-ul facultății :(  +
-Așadar, va trebui să mai facem încă 2 port forwarduri folosind tunele SSH folosind comenzile de mai jos (veți afla mai multe la lab08): +
-<​code>​ +
-# porniți terminal nou de pe stația locală: +
-ssh -L 8080:​localhost:​8080 username@fep.grid.pub.ro +
-# de pe terminalul FEP, rulați comanda similară pentru a vă conecta pe VM-ul de pe OpenStack cu portul 8080 forwardat:​ +
-ssh -i ~/​.ssh/​openstack.key -L 8080:​localhost:​8080 student@10.9.X.Y +
-</​code>​  +
-**NU ÎNCHIDEȚI TERMINALELE!** Cât timp conexiunile SSH rămân deschise, veți putea accesa din browserul vostru pagina http://​localhost:​8080 care va duce către portul din container (prin vreo 2 tunele :D). +
-</​note>​ +
- +
-<note important>​Dacă folosiți Play with Docker, pentru a accesa portul 8080 pentru serviciul de frontend, pur și simplu dati click pe 8080 </​note>​ +
- +
-=== Service Discovery === +
- +
-Am observat că serviciul de frontend funcționează (''​%%http://<​IP mașină gazdă>:​8080%%''​),​ însă pare că nu reușește să încarce conținut. Acest comportament se petrece deoarece aplicația încearcă să consume date de la un serviciu de backend (componentă ce înmagazinează toate funcțiile de procesare a informației) și așteaptă să îi devină disponibil. Este foarte important ca în design-ul unei aplicații, componenta de frontend să ofere doar interfața grafică (de interacțiune) și nimic mai mult, urmând ca procesele de manipulare a datelor să se petreacă în backend. +
- +
-Ca în orice configurație loosely coupled (slab-cuplată), trebuie să ne asigurăm de faptul că elementele componente ale unei soluții pot comunica între ele. Pentru a obține acest rezultat, va trebui să creăm un Docker bridge în care să conectăm containerele aplicației. Pentru a crește un pic complexitatea din perspectiva izolării traficului, vom crea două rețele: o rețea între frontend și backend și o rețea între backend și baza de date: +
- +
-{{:​rl:​labs:​11:​contents:​appnet-dbnet.png?​171 |}} +
- +
-<code bash> +
-student@aldebaran:​~$ docker ​network ​create ​--driver bridge appnet +
-student@aldebaran:​~$ docker network create --driver bridge dbnet +
-</​code>​ +
- +
-În continuare vom afișa cele două entități nou create: +
-<code bash>​student@aldebaran:​~$ docker network ls --filter name=net</​code>​ +
- +
-Întrucât rețelele sunt deja construite, vom lansa cele 2 servicii suplimentare din componența aplicației - +
-backend și baza de date: +
- +
-<code bash> +
-student@aldebaran:​~$ docker run -d --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=dbnet \ +
-   ​mysql +
-[...] +
-</​code>​ +
-<code bash> +
-student@aldebaran:​~$ docker run -d --name=rl-backend ​ \ +
-   -e DB_SERVER=rl-database \ +
-   ​--network=dbnet \ +
-   ​rlrules/​docker-lab-backend +
-[...] +
-</​code>​ +
-<code bash> +
-student@aldebaran:​~$ docker network connect appnet rl-backend +
-[...] +
-student@aldebaran:​~$ docker network connect appnet rl-frontend +
-[...] +
-</​code>​ +
-Va trebui să așteptăm câteva secunde pentru inițializarea bazei de date. +
-Să testăm funcționalitatea platformei accesând aplicația din Browser ​(''​%%http://<​IP mașină gazdă>:​8080%%''​)+
- +
-Dacă Pacman a dispărut de pe ecraniar în locul lui a apărut o colecție impresionantă de meme-uri, înseamnă că platforma funcționează! În cazul în care întâmpinați probleme: +
-<code bash>​student@aldebaran:​~$ docker restart rl-frontend</​code>​ +
- +
-<note important>​Dar cum au reușit serviciile ​să se conecteze între ele?</​note>​ +
- +
-În lumea Docker conectivitatea cu alte servicii se face pe bază de nume. Să presupunem că vrem să ne conectăm la baza de date. În conectivitatea clasică, de cele mai multe ori, trebuie specificată adresa IP a bazei de date, portul dacă nu este cel standard soluției de baze de date, user-ul bazei de date și parola.  +
-În Docker, simplul re-deployment al unui container nu asigură persistența adresei IP alocat interfeței virtuale și deci, nu putem utiliza adresarea IP pentru a asigura conectivitatea dintre două servicii. Pentru a abstractiza elementul de configurare,​ Docker propune un model de Service Discovery bazat pe DNS. În acest sens, un identificator care rămâne nemodificat între două rulări succesive ale aceluiași container, reprezintă numele pe care îl atribuim containerului (în exemplul nostru%%--%%name rl-frontend,​ %%--%%name rl-backend, %%--%%name rl-database). În cele mai multe cazuri, aplicațiile împachetate în container au hardcodate astfel de nume pentru a stabili conectivitatea,​ și totodată un set implicit de credențiale. În setup-uri mai inteligente,​ coordonatele de conectare între servicii pot fi configurate prin variabile de mediu (parametrul -e) admise la runtime, prin fișiere de configurare partajate cu sistemul gazdă etc.  +
- +
-În continuare vom testa funcționalitatea mecanismului de service discovery. Ne vom conecta la instanța de backend: +
-<code bash>​student@aldebaran:​~$ docker exec -it rl-backend bash</​code>​ +
- +
-Și vom rula utilitarele clasice de testare a conectivității -  ping, telnet și host (pentru validarea rezoluției de nume) +
- +
-<code bash> +
-root@rl-backend:​~$ ping rl-frontend +
-[...] +
-root@rl-backend:​~$ apt update && apt install -y host && host rl-frontend +
-[...] +
-root@rl-backend:​~$ telnet rl-frontend 80  +
-[...] +
-</​code>​ +
-<note tip>​Pentru a ieși ''​CTRL + ]''​ sau comanda ''​quit''</​note>​ +
- +
-<code bash> +
-root@rl-backend:​~$ ping rl-database +
-[...] +
-root@rl-backend:​~$ host rl-database +
-[...] +
-exit +
-</​code>​ +
- +
-Dacă ștergem containerul de frontend și îl reconstruim:​ +
-<code bash> +
-student@aldebaran:​~$ docker rm -f rl-frontend +
-</​code>​ +
- +
-<code bash>​student@aldebaran:​~$ docker run -d --name=rl-frontend \ +
-   -e BACKEND_SERVER=rl-backend \ +
-   -p 8080:80 --network appnet \ +
-   ​rlrules/​docker-lab-frontend +
-</​code>​ +
-<code bash>​student@aldebaran:​~$ docker exec -it rl-backend host rl-frontend</​code>​ +
-<code bash>​student@aldebaran:​~$ docker exec -it rl-frontend ip a</​code>​ +
- +
-Vom vedea că serviciul de DNS se va actualiza cu noua adresă IP a containerului,​ în cazul în care aceasta a fost schimbată între cele 2 rulări consecutive. În caz particular, este puțin probabil ca Docker engine să aloce o altă adresă IP. +
- +
-În continuarea laboratorului,​ perspectiva va fi mutată pe date și persistența acestora.+
  
 +{{ :​rl:​labs:​12:​contents:​subnets.png?​700 |}}
rl/labs/11/contents/03.1668503588.txt.gz · Last modified: 2022/11/15 11:13 by florin.stancu
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