Differences

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

Link to this comparison view

idp:laboratoare:02 [2021/03/11 18:53]
radu.ciobanu
idp:laboratoare:02 [2023/03/20 22:03] (current)
radu.ciobanu
Line 1: Line 1:
-===== Laboratorul 02 - Docker Compose =====+===== Laboratorul 02 - Docker Compose ​și Docker Swarm =====
  
-==== Introducere ​====+==== Docker Compose ​====
  
 În mod clasic, pentru rularea unor containere, este nevoie să rulați comanda aferentă de rulare (**//docker run//**) și să dați toți parametrii necesari. Acest proces poate deveni anevoios dacă este repetat pentru pornirea mai multor containere. Un mod de a „salva” configurația de rulare este să ne creăm scripturi. Problema în rularea mai multor scripturi este pierderea uniformității în configurare (ce container la ce rețea se conectează,​ cu cine comunică, etc.). În mod clasic, pentru rularea unor containere, este nevoie să rulați comanda aferentă de rulare (**//docker run//**) și să dați toți parametrii necesari. Acest proces poate deveni anevoios dacă este repetat pentru pornirea mai multor containere. Un mod de a „salva” configurația de rulare este să ne creăm scripturi. Problema în rularea mai multor scripturi este pierderea uniformității în configurare (ce container la ce rețea se conectează,​ cu cine comunică, etc.).
Line 7: Line 7:
 [[https://​docs.docker.com/​compose/​|Docker Compose]] este un utilitar creat de către Docker folosit pentru centralizarea configurării de rulare a containerelor în manieră declarativă. Utilizând fișiere de configurare YAML (Yet Another Markup Language), Docker Compose centralizează procesul de configurare într-o manieră naturală, declarativă. [[https://​docs.docker.com/​compose/​|Docker Compose]] este un utilitar creat de către Docker folosit pentru centralizarea configurării de rulare a containerelor în manieră declarativă. Utilizând fișiere de configurare YAML (Yet Another Markup Language), Docker Compose centralizează procesul de configurare într-o manieră naturală, declarativă.
  
-Mai mult decât atât, formatul pentru fișierele Compose este utilizat și în cadrul **//Docker Swarm//**, orchestratorul creat de Docker pentru gestiunea serviciilor Docker, despre care vom discuta ​în [[idp:​laboratoare:​03|laboratorul 3]].+Mai mult decât atât, formatul pentru fișierele Compose este utilizat și în cadrul **//Docker Swarm//**, orchestratorul creat de Docker pentru gestiunea serviciilor Docker, despre care vom discuta ​mai târziu.
  
 <note tip>​Veți observa că, în acest laborator, folosim termenii de servicii și containere în mod interschimbabil. Acest lucru se întâmplă pentru că Docker Swarm lucrează cu servicii, în timp ce Docker Compose cu containere. Ne referim la ambii termeni în același context deoarece configurația este, în proporție de 90%, identică, indiferent de utilizarea Swarm sau Compose.</​note>​ <note tip>​Veți observa că, în acest laborator, folosim termenii de servicii și containere în mod interschimbabil. Acest lucru se întâmplă pentru că Docker Swarm lucrează cu servicii, în timp ce Docker Compose cu containere. Ne referim la ambii termeni în același context deoarece configurația este, în proporție de 90%, identică, indiferent de utilizarea Swarm sau Compose.</​note>​
  
-==== Instalare ​====+=== Instalare ===
  
 Pentru sisteme Windows și MacOS, Docker Compose face parte din instalarea de Docker Desktop for Windows/​Mac. Pentru Linux, instalarea se realizează [[https://​docs.docker.com/​compose/​install/​|conform ghidului oficial]]. Pentru sisteme Windows și MacOS, Docker Compose face parte din instalarea de Docker Desktop for Windows/​Mac. Pentru Linux, instalarea se realizează [[https://​docs.docker.com/​compose/​install/​|conform ghidului oficial]].
  
-==== Elemente cheie ====+=== Elemente cheie ===
  
-=== Formatul unui fișier YAML ===+== Formatul unui fișier YAML ==
  
 Fișierele [[https://​docs.ansible.com/​ansible/​latest/​reference_appendices/​YAMLSyntax.html|YAML]] sunt folosite de obicei pentru a scrie configurări în mod declarativ. Formatul este unul foarte ușor de înțeles și folosit, astfel: Fișierele [[https://​docs.ansible.com/​ansible/​latest/​reference_appendices/​YAMLSyntax.html|YAML]] sunt folosite de obicei pentru a scrie configurări în mod declarativ. Formatul este unul foarte ușor de înțeles și folosit, astfel:
Line 23: Line 23:
   * se folosesc elemente de tip „cheie:​valoare”   * se folosesc elemente de tip „cheie:​valoare”
   * aliniatele indentate reprezintă proprietăți copii ale paragrafelor anterioare   * aliniatele indentate reprezintă proprietăți copii ale paragrafelor anterioare
-  * listele se delimiteaza ​prin „-”.+  * listele se delimitează ​prin „-”.
  
-=== Exemplu de fișier Docker Compose ​===+== Exemplu de fișier Docker Compose ==
 <code yaml> <code yaml>
 # docker-compose.yml # docker-compose.yml
Line 43: Line 43:
     postgres:     postgres:
         image: postgres:12         image: postgres:12
 +        secrets:
 +            - parola-mea-ultra-secreta
         environment:​         environment:​
             PGPASSWORD_FILE:​ /​run/​secrets/​parola-mea-ultra-secreta             PGPASSWORD_FILE:​ /​run/​secrets/​parola-mea-ultra-secreta
Line 62: Line 64:
 </​code>​ </​code>​
  
-== Version ​==+= Version =
  
 Descrie ce [[https://​docs.docker.com/​compose/​compose-file/​|funcționalități]] vor fi încărcate la rularea utilitarului Docker Compose. Descrie ce [[https://​docs.docker.com/​compose/​compose-file/​|funcționalități]] vor fi încărcate la rularea utilitarului Docker Compose.
Line 68: Line 70:
 <note warning>​Este obligatoriu să treceți versiunea în orice fișier Docker Compose.</​note>​ <note warning>​Este obligatoriu să treceți versiunea în orice fișier Docker Compose.</​note>​
  
-== Services ​==+= Services =
  
 Descrie serviciile/​containerele ce vor rula după ce configurația este pornită de către Compose. Fiecare serviciu reprezintă un container care va avea numele și configurația serviciului. În exemplul de mai sus, containerele se vor numi //**api**// și //​**postgres**//​. Cele mai importante proprietăți ale //​**services**//​ sunt următoarele:​ Descrie serviciile/​containerele ce vor rula după ce configurația este pornită de către Compose. Fiecare serviciu reprezintă un container care va avea numele și configurația serviciului. În exemplul de mai sus, containerele se vor numi //**api**// și //​**postgres**//​. Cele mai importante proprietăți ale //​**services**//​ sunt următoarele:​
  
-  * **//​build//​** - specifică ​director ​unde se află Dockerfile-ul de la care se va efectua construirea containerului+  * **//​build//​** - specifică ​directorul ​unde se află Dockerfile-ul de la care se va efectua construirea containerului
   * **//​image//​** - specifică numele imaginii folosite pentru rularea containerului   * **//​image//​** - specifică numele imaginii folosite pentru rularea containerului
   * **//​ports//​** - o listă de intrări de tipul „port_gazdă:​port_serviciu” unde este realizată expunerea și maparea de porturi   * **//​ports//​** - o listă de intrări de tipul „port_gazdă:​port_serviciu” unde este realizată expunerea și maparea de porturi
Line 78: Line 80:
   * **//​networks//​** - lista de rețele din care face parte serviciul/​containerul   * **//​networks//​** - lista de rețele din care face parte serviciul/​containerul
   * **//​secrets//​** - lista de secrete ce vor fi folosite în cadrul serviciului/​containerului   * **//​secrets//​** - lista de secrete ce vor fi folosite în cadrul serviciului/​containerului
-  * **//​environment//​** - obiect cu intrări de tipul „nume_variabilă_mediu_servici:valoare” care injectează variabilele de mediu specificate la rularea serviciului/​containerului.+  * **//​environment//​** - obiect cu intrări de tipul „nume_variabilă_mediu_serviciu:valoare” care injectează variabilele de mediu specificate la rularea serviciului/​containerului.
  
-**TODO**+<note important>​Opțiunile ​**//build//** și **//​image//​** sunt disjuncte.</​note>​ 
 +<note tip>​Secretele trebuie trecute și în cadrul variabilelor de mediu, conform documentației. De exemplu, [[https://​hub.docker.com/​_/​postgres|în configurația Postgres]], secretele trebuie trecute în variabile de mediu speciale, sufixate cu **//​_FILE//​**,​ alături de calea lor completă (adică //​**/​run/​secrets/​NUME_SECRET**//​).</​note>​
  
-<​hidden>​ += Volumes =
-<note important>​build si image sunt optiuni disjuncte</​note>​ +
-<note tip>​Secretele trebuie trecute si in cadrul variabilelor de mediu, conform documentatiei. De exemplu, [[https://​hub.docker.com/​_/​postgres|in configuratia Postgres]] trebuie trecute in variabile de mediu speciale, sufixate cu **_FILE**, impreuna cu calea lor completa (adica /​run/​secrets/​NUME_SECRET)</​note>​+
  
 +Descrie volumele utilizate în cadrul configurației. Volumele se trec sub formă de obiecte. Dacă nu se dorește schimbarea configurației implicite, valoarea este un câmp gol.
  
-=== Volumes ===+<note tip>​Proprietatea top-level **//​volumes//​** trebuie scrisă pe același nivel de indentare ca **//​services//​**. Nu trebuie confundată cu proprietatea copil **//​volumes//​** din interiorul configurației serviciilor.</​note>​
  
-**Volumes** descrie //NAMED VOLUMES// utilizate in cadrul configuratiei. += Networks =
-<note tip>​Observati ca **volumes**,​ ca si proprietate top level, este scrisa pe acelasi nivel de identatie ca **services**. Nu trebuie confundata cu proprietatea copil **volumes** din interiorul configuratiei serviciilor</​note>​+
  
-Volumele ​se trec sub forma de obiecte. ​Daca nu se doreste ​schimbarea ​configuratiei default, valoarea este un camp gol. In laboratorul urmator vom lucra cu volume NFS, unde va trebui oferita ​configuratie custom.+Descrie rețelele utilizate în cadrul configurației. Rețelele ​se trec sub formă ​de obiecte. ​Dacă nu se dorește ​schimbarea ​configurației implicite, valoarea este un câmp gol. Un exemplu de configurație de rețea este următorul (unde folosim ​rețea care deja există, pentru că a fost creată independent de fișierul Docker Compose):
  
-=== Networks ​===+<code yaml> 
 +networks: 
 +    reteaua-mea-care-de-fapt-exista:​ 
 +        external: true 
 +        name: reteaua-originala-care-deja-exista 
 +</​code>​ 
 + 
 +În cazul de mai sus, //​**reteaua-mea-care-de-fapt-exista**//​ este doar o „redenumire” a unei rețele deja existente. 
 + 
 +<note tip>​Proprietatea top-level **//​networks//​** trebuie scrisă pe același nivel de indentare ca **//​services//​**. Nu trebuie confundată cu proprietatea copil **//​networks//​** din interiorul configurației serviciilor.</​note>​ 
 + 
 +Secrets ​= 
 + 
 +Descrie secretele utilizate în cadrul configurației. Acestea rețin informații sensibile într-o manieră securizată,​ criptată, în cadrul Swarm. În Compose, secretele nu sunt securizate, însă au fost introduse pentru a ușura tranziția către Swarm. În cadrul Docker Compose, secretele pot proveni doar din fișiere externe, care trebuie specificate pentru fiecare secret în parte. 
 + 
 +<note tip>​Proprietatea top-level **//​secrets//​** este scrisă pe același nivel de indentare ca **//​services//​**. Nu trebuie confundată cu proprietatea copil **//​secrets//​** din interiorul configurației serviciilor.</​note>​ 
 + 
 +=== Comenzi Docker Compose ​=== 
 + 
 +Comenzile pentru interacțiunea cu Docker Compose seamănă, ca sintaxă, cu cele clasice de Docker atât pentru versiunea 1 cât și pentru versiunea 2. Mai jos, puteți observa cele mai utilizate comenzi. Pentru versiunea 1, utilitarul este "​docker-compose",​ iar pentru versiunea 2 utilitarul este tot "​docker"​ cu parametrul "​compose",​ iar pe restul le puteți studia în [[https://​docs.docker.com/​compose/​reference/​|documentația oficială pentru versiunea 1]] respectiv [[https://​docs.docker.com/​engine/​reference/​commandline/​compose/​|documentația oficială pentru versiunea 2]]. Diferența principala între versiunea 1 si 2 este ca exista mai multe opțiuni cum ar fi listarea stivelor de containere prin opțiunea "​ls"​. 
 + 
 +<code bash> 
 +$ docker-compose start                       # pornește containerele V1 
 +$ docker-compose stop                        # oprește containerele V1 
 +$ docker-compose pause                       # pune în stare de pauză containerele unui serviciu (se trimite SIGPAUSE) V1 
 +$ docker-compose unpause ​                    # scoate din starea de pauză containerele V1 
 +$ docker-compose ps                          # listează containerele active V1 
 +$ docker-compose up                          # face build, recreează, pornește și atașează containere la un serviciu V1 
 +$ docker-compose up -d                       # serviciile rulează în fundal, detașate de terminalul care le-a inițializat V1 
 +$ docker-compose up --build ​                 # creează imaginile înainte de pornire V1 
 +$ docker-compose -f my-docker-compose.yml up # se folosește fișierul de Compose specificat în loc de cel implicit V1 
 +$ docker-compose down                        # oprește containerele și le șterge, împreună cu rețelele, volumele și imaginile create la up V1 
 +$ docker-compose rm                          # șterge toate containerele oprite (se poate specifica la final și numele containerului care trebuie șters) V1 
 +$ docker-compose rm -s -v                    # cu -s se opresc toate containerele și cu -v se șterg și volumele anonime atașate V1 
 +$ docker compose start                       # pornește containerele V2 
 +$ docker compose pause                       # pune în stare de pauză containerele unui serviciu (se trimite SIGPAUSE) V2 
 +$ docker compose unpause ​                    # scoate din starea de pauză containerele V2 
 +$ docker compose ps                          # listează containerele active V2 
 +$ docker compose ls                          # listează toate stivele de containere V2 
 +$ docker compose -p my-project -f my-docker-compose.yml up # se folosește fișierul de Compose specificat în loc de cel implicit si cu un nume de proiect V2 
 +$ docker compose down                        # oprește containerele și le șterge, împreună cu rețelele, volumele și imaginile create la up V2 
 +$ docker compose rm                          # șterge toate containerele oprite (se poate specifica la final și numele containerului care trebuie șters) V2 
 +$ docker compose rm -s -v                    # cu -s se opresc toate containerele și cu -v se șterg și volumele anonime atașate V2 
 +</​code>​ 
 + 
 +=== Combinarea mai multor fișiere Docker Compose === 
 + 
 +Docker Compose este recomandat să fie utilizat doar în etapa de dezvoltare locală. Pentru medii de testare sau producție, se folosește Docker Swarm (sau alte orchestratoare,​ precum Kubernetes). 
 + 
 +Tocmai pentru că este folosit în etapa de dezvoltare, Docker Compose are un mecanism de a combina mai multe fișiere Compose pentru a crea diferite configurații de rulare, fără a replica părțile comune.  
 + 
 +Pentru a rula o configurație de Compose bazată pe mai multe fișiere YAML, puteți folosi comanda de mai jos. 
 + 
 +<code bash> 
 +$ docker-compose -f fisier-compose-1.yml -f fisier-compose-2.yml up --build ​       # V1 
 +$ docker compose -f fisier-compose-1.yml -f fisier-compose-2.yml up --build ​       # V2 
 +</​code>​ 
 + 
 +În comanda de mai sus, informațiile din //​**fisier-compose-2.yml**//​ vor suprascrie/​completa informațiile din //​**fisier-compose-1.yml**//​. Acest lucru este util pentru a testa rapid diverse configurații. 
 + 
 +==== Docker Swarm ==== 
 + 
 +În continuare, vom face tranziția de la Docker Compose la Docker Swarm, **//​orchestratorul de servicii//​** oferit de Docker. Acesta are rolul de a gestiona servicii de Docker pe una sau mai multe mașini într-o rețea (într-un cluster) de mașini fizice și/sau virtuale. Spre deosebire de Docker Compose, care rulează containere pe o singură gazdă, Docker Swarm rulează //​**servicii**//​ între mai multe gazde. La fel ca și Compose, Docker Swarm folosește fișiere de configurare YAML. 
 + 
 +=== Arhitectura Docker Swarm === 
 + 
 +Docker Swarm se bazează pe algoritmul distribuit [[https://​raft.github.io|Raft]],​ cu ajutorul căruia se menține consistentă starea internă a întregului cluster. În plus, traficul dintre nodurile din Swarm este criptat de către Raft. În imaginea de mai jos (preluată din [[https://​docs.docker.com/​engine/​swarm/​how-swarm-mode-works/​nodes/​|documentația oficială]]),​ se poate observa arhitectura unui cluster Docker Swarm. 
 + 
 +{{:​idp:​laboratoare:​swarm-diagram.png?​600|}} 
 + 
 +Mașinile gazdă care fac parte dintr-un Swarm se numesc **//​noduri//​** și pot avea două roluri: 
 +  * manager - rol administrativ și funcțional;​ menține consistența clusterului,​ lansează în execuție servicii, expune endpoint-uri de rețea 
 +  * worker - rol funcțional;​ execută serviciile. 
 + 
 +Dintre toate nodurile manager, un singur nod este **//​leader//​**,​ care are rolul de a crea task-uri și de a face logging. Task-urile sunt distribuite apoi nodurilor manager. 
 + 
 +<note important>​Întotdeauna trebuie să existe un nod leader.</​note>​ 
 + 
 +<note tip>​Deoarece toleranța este de (N - 1) / 2 noduri manager picate, este indicat să avem un număr impar de noduri și un număr impar de manageri. Docker recomanda 3, 5 sau 7 manageri.</​note>​ 
 + 
 +=== Crearea unui Docker Swarm === 
 + 
 +Odată ce avem un cluster de mașini pe care rulează Docker, ne putem inițializa un Docker Swarm. Astfel, putem rula următoarea comandă pe nodul care va fi leader (opțiunea //​**%%--%%advertise-addr**//​ este necesară atunci când nodul are mai multe interfețe de rețea și trebuie specificat pe care din ele se face advertising):​ 
 + 
 +<code bash> 
 +$ docker swarm init --advertise-addr 192.168.99.100 
 + 
 +Swarm initialized:​ current node (qtyx0t5z275wp46wibcznx8g5) is now a manager. 
 +To add a worker to this swarm, run the following command: 
 +    docker swarm join --token SWMTKN-1-4hd41nyin8kn1wx4bscnnt3e98xtlvyxw578qwxijw65jp1a3q-32rl6525xriofd5xmv0c1k5vj 192.168.99.100:​2377 
 +To add a manager to this swarm, run '​docker swarm join-token manager'​ and follow the instructions. 
 +</​code>​ 
 + 
 +<note tip>Așa cum se poate observa, comanda de mai sus generează alte două comenzi pe care le putem folosi pentru a introduce alte noduri în cluster, atât ca worker, cât și ca manager.</​note>​ 
 + 
 +Putem verifica dacă swarm-ul a fost creat cu succes dând comanda de mai jos pe mașina leader (unde avem două noduri numite //​**node1**//​ și //​**node2**//,​ primul din ele fiind leader, iar al doilea worker): 
 + 
 +<code bash> 
 +$ docker node ls 
 + 
 +ID                            HOSTNAME ​    ​STATUS ​      ​AVAILABILITY ​     MANAGER STATUS 
 +qtyx0t5z275wp46wibcznx8g5 *   ​node1 ​       Ready        Active ​           Leader 
 +0xbb9al1kuvn0jcapxiqni29z ​    ​node2 ​       Ready        Active ​      
 +</​code>​ 
 + 
 +=== Servicii și stive de servicii Docker Swarm === 
 + 
 +Atunci când vorbim de deployment-ul unei aplicații în Docker Swarm, trecem de la noțiunea de container la noțiunea de serviciu. Un serviciu Docker reprezintă o colecție de task-uri (unul sau mai multe), iar un task reprezintă un container. Așadar, un serviciu este format din unul sau mai multe containere identice. Serviciul controlează ciclul de viață al containerelor,​ încercând întotdeauna să mențină starea containerelor oferite în configurație. Cu alte cuvinte, un serviciu reprezintă un set de containere cu //​**orchestrare**//​. 
 + 
 +Mai departe, o stivă de servicii reprezintă mai multe astfel de servicii grupate în același spațiu de nume. Putem vizualiza o stivă de servicii ca fiind o aplicație Docker formată din mai multe servicii. Cel mai facil mod de a defini o stivă de servicii este prin intermediul unui fișier Docker Compose, așa cum am văzut mai devreme. Comportamentul serviciilor dintr-o stivă este similar cu cel al containerelor din Docker Compose, doar că politica de denumire este diferită. 
 + 
 +<note tip>​Orice entitate creată într-o stivă (serviciu, volum, rețea, secret) va fi prefixată de **//​NUME-STIVA_//​**.</​note>​
  
-**Networks** descrie ​//retelele// utilizate in cadrul configuratiei. +Docker Swarm are acces la o colecție nouă de opțiuni în cadrul fișierului YAML de Compose, ce vor fi trecute în proprietatea [[https://docs.docker.com/compose/compose-file/​compose-file-v3/#​deploy|deploy]] a unui serviciuImaginea ​de mai jos prezintă un fragment de fișier Docker Compose unde se exemplifică o parte din aceste opțiuni noi:
-<note tip>​Observati ca **networks**,​ ca si proprietate top level, este scrisa pe acelasi nivel de identatie ca **services**. Nu trebuie confundata cu proprietatea copil **networks** ​din interiorul configuratiei serviciilor</​note>​+
  
-Retelele se trec sub forma de obiecte. Daca nu se doreste schimbarea configuratiei default, valoarea este un camp gol. Un exemplu de configuratie de retea este atunci cand se foloseste o retea care deja exista, de exemplu: 
 <code yaml> <code yaml>
-networks+[...] 
-  ​reteaua-mea-care-de-fapt-exista+services
-    ​externaltrue +  ​web
-    ​namereteaua-originala-care-deja-exista+    ​imagemyimage 
 +    ​deploy: 
 +      replicas: 4 
 +      resources:​ 
 +        limits: 
 +          cpus: "​0.2"​ 
 +          memory: 50M 
 +      restart_policy:​ 
 +        condition: on-failure 
 +[...]
 </​code>​ </​code>​
  
-In cazul de mai sus, //reteaua-mea-care-de-fapt-exista// este doar "​redenumire"​ a unei retele deja existente.+În fragmentul de fișier YAML de mai sus, se rulează un serviciu numit //**web**// care are patru copii. Astfel, vor exista ​patru containere diferite care rulează imaginea ​//**myimage**//,​ oricare din ele putând răspunde la cereri pentru serviciul //​**web**//,​ în funcție de încărcare. De asemenea, fiecare instanță ​este limitată la 20% CPU (pe toate core-urile) și 50 MB de RAM. Nu în ultimul rând, un container al serviciului //**web**// se restartează imediat ce întâlnește ​eroare (scopul final fiind ca, la orice moment de timp, să existe 4 copii ale containerului în rețea).
  
-=== Secrets ===+== Rețele Swarm ==
  
-**Secrets** descrie ​//secretele// utilizate in cadrul configuratiei. +Spre deosebire de Docker clasic și Compose, rețelele create în Swarm nu mai sunt de tip bridge, ci de tip **//overlay//**O rețea de tip overlay este o rețea care se întinde peste toate nodurile dintr-un swarm. Din acest motivporturile publice expuse vor fi unice per rețea. Așadarnu pot fi expuse două porturi 3000 din două servicii diferite care se conectează la aceeași rețea overlay.
-<​note ​tip>​Observati ca **secrets**ca si proprietate top leveleste scrisa pe acelasi nivel de identatie ca **services**Nu trebuie confundata cu proprietatea copil **secrets** din interiorul configuratiei serviciilor</​note>​+
  
-Secretele retin informatii sensibile intr-o maniera securizata, criptata, in cadrul ​Swarm, despre care vom vorbi la laboratorul urmator. In compose nu sunt securizate, insa au fost introduse pentru a usura tranzitia catre Swarm.+<note tip>​Docker ​Swarm realizează balansare a încărcării ​la nivelul rețelei.</​note>​
  
-In cadrul composesecretele pot proveni doar din fisiere externeFisierele externe sunt mentionate pentru fiecare secret in parte.+Un serviciu la care s-a făcut deploy pe un anumit port totdeauna va avea acel port rezervatindiferent pe ce nod rulează de fapt containerul sau containerele sale. Diagrama de mai jos (preluată ​din [[https://​docs.docker.com/​engine/​swarm/​ingress/​|documentația oficială]]) prezintă o situație în care avem un serviciu numit //​**my-web**//​ publicat pe portul 8080 într-un cluster cu trei noduri. Se poate observa că, dacă ne conectăm pe portul 8080 de pe oricare adresă IP de nod din cluster, vom fi redirecționați către un container care rulează serviciul specific portului extern 8080, indiferent de nodul pe care rulează.
  
-==== Comenzi Docker Compose ====+{{:​idp:​laboratoare:​network.png?​600|}}
  
-Comenzile pentru interactiunea cu docker-compose seamana, ca si sintaxa, cu cele clasice ​de docker. Mai jos va oferim cele mai utilizate comenzi.+== Secrete Swarm == 
 + 
 +Secretele din Swarm trebuie create înainte ​de a fi rulată configurațiaPutem folosi următoarea comandă:
  
 <code bash> <code bash>
-# Porneste containerele +docker ​secret ​create ​mysecret file.txt 
-docker-compose start + 
-# Opreste containerele +fm49ig0i8x9pdq0xxa8wdchoy
-docker-compose stop +
-# Pune in stare de pauza conainerele unui serviciu. Diferenta fata de stop e ca la procesul din container se trimite SIGPAUSE +
-docker-compose pause +
-# Scoate din stare de pauza containerele +
-docker-compose unpause +
-# Listeaza containerele active +
-docker-compose ps +
-# Face build, recreaza, porneste si ataseaza containere la un serviciu +
-docker-compose up +
-# Serviciile ruleaza in background detasat de terminalul care le-a initializat +
-docker-compose up -d +
-# Creaza imaginile inainte de pornire unde a fost declarata calea pentru un Dockerfile pentru un container +
-docker-compose up --build +
-# Se foloseste fisierul de docker-compose specificat in loc de cel implicit +
-docker-compose -f my-docker-compose.yml up +
-# Opreste containerele si le sterge pe acestea impreuna cu retelele, volumele si imagine ​create ​la up+
-docker-compose down +
-# Sterge toate containerele oprite (se poate specifica la sfarsit si numele containerului care trebuie sters) +
-docker-compose rm +
-# Cu -s se opresc toate containerele si cu -v se sterg si volumele anonime atasate +
-docker-compose rm -s -v +
 </​code>​ </​code>​
  
-==== Composing a Composition of Compose Files ====+Putem lista secretele existente astfel:
  
-Docker Compose este recomandat sa fie utilizat **doar** in etapa de **dezvoltare locala**. Pentru medii de testare sau productie se foloseste Docker Swarm sau alte orchestratoare,​ precum Kubernetes. ​+<code bash> 
 +$ docker secret ls
  
-Tocmai pentru ca este folosit in etapa de dezvoltare, acesta are un mecanism de a combina mai multe fisiere compose pentru a crea mai multe configuratii de rulare, fara a replica partile comune. ​+ID                          NAME       ​DRIVER ​   CREATED ​        ​UPDATED 
 +fm49ig0i8x9pdq0xxa8wdchoy ​  ​mysecret ​            3 seconds ago   3 seconds ago 
 +</​code>​
  
-Pentru a rula o configuratie ​de compose bazata ​pe mai multe fisiere, este nevoie sa rulati ​+Secretele din Swarm sunt criptate în Raft și deci este recomandat să fie folosite în producție. 
 + 
 +== Diferențe între Docker Swarm și Docker Compose == 
 + 
 +Exista câteva diferențe între Swarm și Compose la nivelul fișierelor declarative YAML: 
 +  * deoarece Swarm rulează servicii în rețea, nu poate exista cuvântul-cheie **//​build//​**;​ serviciile trebuie obligatoriu să fie rulate pe baza unor imagini deja existente într-un registru 
 +  * stivele ​de servicii nu accepta fișiere **//​.env//​** (spre deosebire de Docker Compose) 
 +  * Docker Compose rulează containere în mod single-host, ​pe când Docker Swarm orchestrează servicii în mod multi-host. 
 + 
 +== Pornirea unei stive de servicii în Docker Swarm == 
 + 
 +Odată ce swarm-ul Docker a fost creat și inițializatcomanda prin care se face deployment la o stivă de servicii ​este următoarea (unde configurația se găsește în fișierul //​**my_stack.yml**//,​ iar numele stivei va fi //​**lab2**//​):​
  
 <code bash> <code bash>
-docker-compose -f fisier-compose-1.yml -f fisier-compose-2.yml up --build+docker ​stack deploy ​-c my_stack.yml lab2
 </​code>​ </​code>​
  
-Informatiile ​din //fisier-compose-2.yml// vor suprascrie/completa informatiile ​din fisier-compose-1.ymlAcest lucru este util pentru a testa diverse configuratii rapid.+<note important>​Dacă folosim un registru diferit de Docker (precum [[https://​docs.gitlab.com/​ee/​user/​packages/​container_registry/​|GitLab Container Registry]]),​ este nevoie să fim autentificați și să adăugăm opțiunea **//​-–with-registry-auth//​** atunci când lansăm o stivă de servicii.</​note>​ 
 + 
 +Odată ce o stivă de servicii a fost pornită, putem să îi vedem statusul prin următoarea comandă: 
 + 
 +<code bash> 
 +$ docker stack ps lab2                                                                                                      
 + 
 +ID             ​NAME ​                  ​IMAGE ​                                  ​NODE ​     DESIRED STATE    CURRENT STATE           ​ERROR ​              ​PORTS 
 +cuktma92gm62 ​  ​lab2_adminer.1 ​        ​adminer:​latest ​                         myvm2     ​Running ​         Running 9 minutes ago                        
 +njak2qzaobtt ​  ​lab2_db.1 ​             postgres:​12 ​                            ​myvm1 ​    ​Running ​         Running 8 minutes ago                        
 +m811buil7e63 ​  ​lab2_io-service.1 ​     mobylab/​idp-laborator2-io:​latest ​       myvm1     ​Running ​         Running 9 minutes ago                        
 +jnfw37e34kz3 ​  ​lab2_books-service.1 ​  ​mobylab/​idp-laborator2-books:​latest ​    ​myvm1 ​    ​Running ​         Running 9 minutes ago                        
 +pzlzkgsxxc00 ​  ​lab2_gateway.1 ​        ​mobylab/​idp-laborator2-gateway:​latest ​  ​myvm2 ​    ​Running ​         Running 9 minutes ago                        
 +kpaahb931rbq ​  ​lab2_io-service.2 ​     mobylab/​idp-laborator2-io:​latest ​       myvm1     ​Running ​         Running 9 minutes ago                        
 +num87yijgxrg ​  ​lab2_books-service.2 ​  ​mobylab/​idp-laborator2-books:​latest ​    ​myvm2 ​    ​Running ​         Running 9 minutes ago                        
 +d9m63k9h7ium ​  ​lab2_gateway.2 ​        ​mobylab/​idp-laborator2-gateway:​latest ​  ​myvm1 ​    ​Running ​         Running 9 minutes ago                        
 +lkmy60wpy0gv ​  ​lab2_io-service.3 ​     mobylab/​idp-laborator2-io:​latest ​       myvm2     ​Running ​         Running 9 minutes ago                        
 +fy21iizn0reb ​  ​lab2_gateway.3 ​        ​mobylab/​idp-laborator2-gateway:​latest ​  ​myvm2 ​    ​Running ​         Running 9 minutes ago                        
 +</​code>​ 
 + 
 +De asemenea, putem vedea lista de stive pornite astfel: 
 + 
 +<code bash> 
 +$ docker stack ls                                                                                                            
 + 
 +NAME      SERVICES ​     ORCHESTRATOR 
 +lab2      5             ​Swarm 
 +</​code>​ 
 + 
 +Putem vedea lista de servicii (din toate stivele pornite) astfel: 
 + 
 +<code bash> 
 +$ docker service ls                                                                                                          
 + 
 +ID               ​NAME ​                ​MODE ​          ​REPLICAS ​              ​IMAGE ​                                 PORTS 
 +dekzzyais8g7 ​    ​lab2_adminer ​        ​replicated ​    1/1                    adminer:​latest ​                        ​*:​8080->​8080/tcp 
 +74y84hvq4irn ​    ​lab2_books-service ​  ​replicated ​    2/2 (max 1 per node)   ​mobylab/​idp-laborator2-books:​latest ​     
 +ns9mxet1rkx5 ​    ​lab2_db ​             replicated ​    ​1/​1 ​                   postgres:​12 ​                             
 +dh3sv3q74fy6 ​    ​lab2_gateway ​        ​replicated ​    3/3 (max per node)   ​mobylab/​idp-laborator2-gateway:​latest ​ *:​3000->​80/​tcp 
 +ru0rd7g2ypu8 ​    ​lab2_io-service ​     replicated ​    3/3 (max 2 per node)   ​mobylab/​idp-laborator2-io:​latest 
 +</​code>​ 
 + 
 +=== Deployment-ul unui cluster Docker === 
 + 
 +În cadrul laboratoarelor de IDP, avem două variante principale cu ajutorul cărora putem să ne creăm un cluster Docker format din mai multe mașini: [[https://​docs.docker.com/machine/|Docker Machine]] sau [[https://​labs.play-with-docker.com|Play with Docker]]. 
 + 
 +== Docker Machine == 
 + 
 +<note important>​Recent,​ Docker Machine a devenit deprecated, deci cei de la Docker nu mai mențin acest proiect. Puteți totuși testa un deployment multi-nod folosind Docker Machine, dar vă recomandăm varianta Play with Docker sau un cluster propriu (fizic sau virtual).</​note>​ 
 + 
 +Docker Machine este un utilitar care permite rularea Docker Engine pe gazde virtuale (atât local, cât și în cloud, la provideri ca AWS, Azure sau DigitalOcean),​ precum și gestiunea facilă a acestora ​din terminal. Docker Machine trebuie instalat separat de Docker, conform [[https://​docs.docker.com/​machine/​install-machine/​|documentației oficiale]]. 
 + 
 +În Docker Machine, putem folosi drivere pentru a crea noduri virtuale configurate pentru a rula Docker. Exista drivere pentru a crea noduri direct în cloud, dar și drivere pentru a crea mașini virtuale pe gazda locală. În exemplul de mai jos, se creează un nod virtual local folosind driverul pentru VirtualBox:​ 
 + 
 +<​code>​ 
 +$ docker-machine create --driver virtualbox myvm1 
 + 
 +Running pre-create checks... 
 +Creating machine... 
 +(myvm1) Copying /​home/​radu/​.docker/​machine/​cache/​boot2docker.iso to /​home/​radu/​.docker/​machine/​machines/​myvm1/​boot2docker.iso... 
 +(myvm1) Creating VirtualBox VM... 
 +(myvm1) Creating SSH key... 
 +(myvm1) Starting the VM... 
 +(myvm1) Check network to re-create if needed... 
 +(myvm1) Waiting for an IP... 
 +Waiting for machine to be running, this may take a few minutes... 
 +Detecting operating system of created instance... 
 +Waiting for SSH to be available... 
 +Detecting the provisioner... 
 +Provisioning with boot2docker... 
 +Copying certs to the local machine directory... 
 +Copying certs to the remote machine... 
 +Setting Docker configuration on the remote daemon... 
 +Checking connection to Docker... 
 +Docker is up and running! 
 +To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: docker-machine env myvm1 
 +</​code>​ 
 + 
 +Putem verifica rularea corectă a comenzilor și alte informații utile despre starea nodurilor virtuale astfel: 
 + 
 +<​code>​ 
 +$ docker-machine ls 
 +NAME    ACTIVE ​  ​DRIVER ​      ​STATE ​    ​URL ​                        ​SWARM ​  ​DOCKER ​       ERRORS 
 +myvm1   ​- ​       virtualbox ​  ​Running ​  ​tcp://​192.168.99.100:​2376 ​          ​v17.09.0-ce ​   
 +</​code>​ 
 + 
 +Prin comanda //​**docker-machine ssh**//, putem trimite comenzi prin SSH către un nod virtual Docker pe care îl specificăm prin nume, așa cum se poate observa mai jos. 
 + 
 +<​code>​ 
 +$ docker-machine ssh myvm1 "ls -la" 
 +</​code>​ 
 + 
 +În mod similar, există și comanda //​**docker-machine scp**//: 
 + 
 +<​code>​ 
 +$ docker-machine scp file.txt myvm1:. 
 +</​code>​ 
 + 
 +De asemenea, există și comenzi pentru oprirea, respectiv ștergerea, nodurilor virtuale create. 
 + 
 +<​code>​ 
 +$ docker-machine stop myvm1 
 +</​code>​ 
 + 
 +<​code>​ 
 +$ docker-machine rm myvm1 
 +</​code>​ 
 + 
 +== Play with Docker == 
 + 
 +Play with Docker este un mediu online de învățare Docker ce oferă mașini virtuale pe o durată de 4 ore. 
 + 
 +{{:​idp:​laboratoare:​playwithdocker.png?​900}} 
 + 
 +=== Comenzi utile === 
 + 
 +== Interacțiune servicii == 
 + 
 +<note tip>​Aceste comenzi pot fi rulate doar de pe noduri manager.</​note>​ 
 + 
 +<code bash> 
 +$ docker service create --name <​NUME_SERVICIU>​ <​IMAGINE_DOCKER>​ # creează un serviciu pornind de la o imagine 
 +$ docker service ls                                             # afișează toate serviciile din sistem 
 +$ docker service inspect <​NUME_SERVICIU> ​                       # afișează informații despre un serviciu 
 +$ docker service logs –f <​NUME_SERVICIU> ​                       # afișează log-urile unui serviciu 
 +$ docker service ps <​NUME_SERVICIU> ​                            # afișează task-urile (și statusurile lor) pentru un serviciu 
 +$ docker service update --replicas <N> <​NUME_SERVICIU> ​         # actualizează serviciul, replicând containerele de N ori 
 +$ docker service rm <​NUME_SERVICIU> ​                            # șterge un serviciu 
 +</​code>​ 
 + 
 +== Interacțiune cluster == 
 + 
 +<note tip>​Aceste comenzi pot fi rulate doar de pe noduri manager.</​note>​ 
 + 
 +<code bash> 
 +$ docker node ls                            # afișează nodurile din cluster 
 +$ docker node promote <​NUME_NOD> ​           # promovează nodul din worker în manager 
 +$ docker node demote <​NUME_NOD> ​            # retrogradează nodul din manager în worker 
 +$ docker swarm init [--advertise-addr <IP>] # creează un cluster Docker 
 +$ docker swarm join --token <​TOKEN>​ <​IP> ​   # se alătură unui cluster Docker 
 +</​code>​ 
 + 
 +== Docker Machine == 
 + 
 +<code bash> 
 +$ docker-machine create [--driver <​DRIVER>​] <​NUME>​ # creează o mașină virtuală Docker 
 +$ docker-machine start <​NUME> ​                     # pornește o mașină virtuală Docker 
 +$ docker-machine stop <​NUME> ​                      # oprește o mașină virtuală Docker 
 +$ docker-machine rm <​NUME> ​                        # șterge o mașină virtuală Docker 
 +$ docker-machine ls                                # listează toate mașinile virtuale Docker 
 +$ docker-machine ssh <​NUME> ​                       # se conectează prin SSH la o mașină virtuală Docker 
 +$ docker-machine scp <​FISIER>​ <​NUME>:<​DESTINATIE> ​ # copiază un fișier pe o mașină virtuală Docker 
 +</​code>​ 
 + 
 +==== Exerciții ==== 
 + 
 +=== Docker Compose === 
 + 
 +<note tip>​Puteți accesa resursele practice pentru acest laborator pe [[https://​gitlab.com/​mobylab-idp/​laborator-2|repository-ul oficial]] al materiei IDP. Exercițiile urmăresc înțelegerea conceptelor de Docker Compose.</​note>​ 
 + 
 +  - Scrieți configurația containerelor de la ultimul set de exerciții din [[idp:​laboratoare:​01|laboratorul ​1]] în maniera Compose: 
 +    - pentru containerul de API, folosiți sursele și Dockerfile-ul din directorul //**API**// aflat pe repository, sau direct imaginea //​**mobylab/​idp-laborator2-api**//​ de pe Docker Hub 
 +    - pentru containerul de Postgres, găsiți fișierul //**init-db.sql**// în directorul //​**Database**//​ din repository. 
 +  - Introduceți un al treilea serviciu bazat pe imaginea **//​adminer//​**,​ care face parte dintr-o rețea comună cu baza de date, alta decât cea pe care baza de date o folosește la comunicația cu API-ul (așadar, trebui să aveți două rețele). 
 +  - Spargeți configurația în două fișiere de Compose, unul de bază și unul care să folosească secrete (găsiți fișierele pentru secrete în directorul //​**secrets**//​ din repository). Rulați cele două configurații împreună. 
 + 
 +<note important>​După ce veți sparge configurația inițială în două, o să observați că trebuie să renunțați la niște variabile de mediu ale bazei de date din fișierul de bază, și anume //​**POSTGRES_USER**//​ și //​**POSTGRES_PASSWORD**//​. În configurația cu secrete, numele de utilizator și parola vor fi setate prin variabilele de mediu //​**POSTGRES_USER_FILE**//​ și //​**POSTGRES_PASSWORD_FILE**//,​ care sunt disjuncte cu cele menționate anterior. Este important de menționat că valorile pentru aceste două variabile de mediu reprezintă căile //​**complete**//​ ale fișierelor secret, de forma //​**/​run/​secrets/​NUME_SECRET**//​.</​note>​ 
 + 
 +<note important>​Pentru a introduce secrete și în serviciul de API, trebuie să setați variabila de mediu //​**NODE_ENV**//​ la valoarea „staging” și să setați variabilele de mediu //​**PGPASSWORD_SECRET**//​ și //​**PGUSER_SECRET**//​ doar cu numele secretului, nu cu toată calea //​**/​run/​secrets/​NUME_SECRET**//​ precum în cazul bazei de date.</​note>​ 
 + 
 +=== Docker Swarm === 
 + 
 +Pentru exercițiile din această secțiune, vom lucra cu o variantă extinsă a aplicației bibliotecă de mai sus. Astfel, codul (care se găsește pe [[https://​gitlab.com/​mobylab-idp/​laborator3|repository-ul oficial IDP]]) ​este format din trei mici microservicii scrise în NodeJS și un script de inițializare pentru o bază de date PostgreSQL. Cele trei microservicii sunt: 
 +  * //​**ApiGateway**//​ - mediază accesul dinspre lumea exterioară și redirecționează cererile HTTP către serviciul de cărți 
 +  * //​**Books**//​ - se ocupă de partea de „business logic” ce ține de cărți și apelează serviciul IO pentru date 
 +  * //**IO**// - gestionează datele sistemului și realizează comunicația cu baza de date. 
 + 
 +== Scop exerciții == 
 + 
 +Scopul exercițiilor este ca, plecând de la codul propus, să realizați o stivă de servicii care să funcționeze corect. Funcționalitatea este reprezentată de trei acțiuni: 
 +  * adăugarea unei cărți în bibliotecă 
 +  * vizualizarea informațiilor despre toate cărțile din bibliotecă 
 +  * vizualizarea detaliilor unei cărți. 
 + 
 +Pe scurt, va trebui să scrieți unul sau mai multe fișier Docker Compose pe care să le folosiți ​pentru a rula configurația sub forma unei stive de servicii Docker Swarm. Stiva creată va fi formată din 5 servicii: 
 +  * //​**gateway**//​ - puteți să creați imaginea pe baza surselor din repository, sau puteți folosi imaginea //​**mobylab/​idp-laborator2-gateway**//​ 
 +  * //​**books-service**//​ - puteți să creați imaginea pe baza surselor din repository, sau puteți folosi imaginea //​**mobylab/​idp-laborator2-books**//​ 
 +  * //​**io-service**//​ - puteți să creați imaginea pe baza surselor din repository, sau puteți folosi imaginea //​**mobylab/​idp-laborator2-io**//​ 
 +  * //**db**// - folosiți imaginea //​**postgres:​12**//​ 
 +  * //​**adminer**//​ - folosiți imaginea //​**adminer**//​. 
 + 
 +== Variabile de mediu == 
 + 
 +Variabilele de mediu ce vor trebui puse in fișierul Docker Compose sunt următoarele:​ 
 +  * serviciul //​**gateway**//:​ 
 +    * BOOKS_SERVICE_API_ROUTE:​ books-service/​api 
 +    * NODE_ENV: development 
 +  * serviciul //​**books-service**//:​ 
 +    * IO_SERVICE_API_ROUTE:​ io-service/​api 
 +    * NODE_ENV: development 
 +  * serviciul //​**io-service**//:​ 
 +    * PGUSER: admin 
 +    * PGPASSWORD: admin 
 +    * PGHOST: db 
 +    * PGPORT: 5432 
 +    * PGDATABASE: books 
 +    * NODE_ENV: development 
 +  * serviciul //​**db**//:​ 
 +    * POSTGRES_DB:​ books 
 +    * POSTGRES_USER:​ admin 
 +    * POSTGRES_PASSWORD:​ admin. 
 +  
 +== Rețele == 
 + 
 +Pentru a izola accesul serviciilor asupra clusterului,​ sunt necesare mai multe rețele, astfel: 
 + 
 +  * serviciul //​**gateway**//​ va comunica doar cu serviciul //​**books-service**//​ 
 +  * serviciul //​**books-service**//​ va comunica atât cu serviciul de //​**gateway**//,​ cât și cu //​**io-service**//​ 
 +  * serviciul //​**io-service**//​ va comunica atât cu serviciul //​**books-service**//,​ cât și cu serviciul //​**db**//​ 
 +  * serviciul //**db**// va comunica atât cu serviciul //​**io-service**//,​ cât și cu //​**adminer**//​. 
 + 
 +== Volume și bind mounts == 
 + 
 +Configurația de volume și bind mounts este la fel ca cea de la exercițiile de mai sus. Astfel, serviciul de bază de date are nevoie de un volum pentru persistență și de un bind mount pentru a se injecta scriptul de inițializare. 
 + 
 +== Porturi publice == 
 + 
 +Singurele servicii accesibile din exterior vor fi //​**gateway**//​ și //​**adminer**//​. Pentru //​**gateway**//,​ trebuie expus portul intern 80, peste care se mapează alt port (de exemplu, 3000), iar pentru //​**adminer**//​ trebuie expus portul intern 8080 (peste care se poate de asemenea mapa alt port extern). 
 + 
 +== Rute HTTP == 
 + 
 +Dacă reușiți să rulați configurația,​ puteți să o testați folosind cURL sau [[https://​learning.postman.com/​docs/​getting-started/​sending-the-first-request/​|Postman]] pe următoarele rute: 
 + 
 +  * //**POST localhost:​PORT_PUBLIC/​api/​books**//​ cu corpul JSON ''​%%{"​title":​ "Harry Potter and the Prisoner of Azkaban",​ "​author":​ "J.K. Rowling",​ "​genre":​ "​Fantasy"​}%%''​ 
 +  * //**GET localhost:​PORT_PUBLIC/​api/​books**//​ 
 +  * //**GET localhost:​PORT_PUBLIC/​api/​books/<​ID_CARTE>​**//​.
  
-==== Exercitii ====+<note tip>​Pentru a adăuga un corp JSON unei cereri POST in Postman, selectați Body -> Raw -> JSON și scrieți JSON-ul aferent.</​note>​
  
-Resursele practice pentru acest laborator le puteti accesa pe [[https://​gitlab.com/​mobycloudcomputing/​laborator-3.git|repo-ul oficial al materiei Cloud Computing]]+== Secrete ==
  
-Exercitiile urmaresc intelegerea conceptelor ​de composeSunt optionaleinsa va recomandam sa le lucrati ​pentru ​a dobandi deprindere ​de lucru.+Opțional, puteți adăuga secrete aplicației,​ pentru numele ​de utilizator și parola necesare logării în baza de dateAstfel, serviciile care vor avea nevoie de secrete sunt //​**io-service**//​ și //**db**//. În cele două servicii, va trebui să sufixați variabilele de mediu destinate numelui de utilizator și parolei cu //​**_FILE**//​ și să puneți valorile acestor variabile de mediu în funcție de documentație:​ 
 +  * pentru ​//​**io-service**//,​ la variabilele de mediu pentru numele de utilizator și parolă se pune doar **//numele secretului//​** iar NODE_ENV se setează la **//​staging//​** 
 +  * pentru serviciul //**db**//, la variabilele ​de mediu se pune toată calea secretului (//​**/​run/​secrets/​nume-secret**//​).
  
-  - Scrieti configuratia containerelor de la laboratorul 2 in maniera compose +== Enunțuri ==
-  - Introduceti un al 3-lea serviciu, **adminer** care face parte dintr-o **retea comuna** cu baza de date, alta decat cea pe care baza de date o foloseste la comunicarea cu api-ul +
-  - Spargeti configuratia in 2 fisiere, unul de baza, si unul care sa foloseasca secrete. Rulati cele 2 configuratii impreuna. +
-<note important>​Dupa ce veti sparge configuratia initiala in 2, o sa observati ca trebuie sa renuntati la niste variabile de mediu ale bazei de date din fisierul de baza, si anume POSTGRES_USER si POSTGRES_PASSWORD. In configuratia cu secrete, username-ul si parola vor fi setate prin variabilele de mediu POSTGRES_USER_FILE si POSTGRES_PASSWORD_FILE,​ care sunt disjuncte cu cele mentionate anterior.</​note>​+
  
-<note tip>​Pentru a introduce secrete si in API, trebuie sa setati variabila de mediu NODE_ENV = staging si sa setati variabilele ​de mediu PGPASSWORD_SECRET si PGUSER_SECRET ​**doar cu numele secretului**, nu cu toata calea //run/​secrets/​NUME_SECRET//​ precum in cazul bazei de date</​note>​ +  - Scrieți un fișier Docker Compose care să folosească un build local și rulați pe mașina voastră 
-</​hidden>​+  - Construiți imaginile și urcați-le pe Docker Hub sau orice alt registru 
 +  - Scrieți un fișier Docker Compose care să folosească imaginile din registru și rulați pe mașina voastră 
 +  - Adăugați elemente ​de Docker Swarm la serviciile din fișierul Docker Compose (la proprietatea //**deploy**//) și rulați stiva de servicii într-un cluster (folosind Play with Docker sau Docker Machine) 
 +  - Modificați fișierul Docker Compose ca să utilizați secrete externe pentru numele de utilizator și parolă în containerele de IO și bază de date.
idp/laboratoare/02.1615481634.txt.gz · Last modified: 2021/03/11 18:53 by radu.ciobanu
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