Laboratorul 1 - Docker
Introducere
Docker este o platformă de containere software, folosită pentru a împacheta și rula aplicații atât local, cât și pe sisteme Cloud, eliminând probleme de genul "pe calculatorul meu funcționează". Docker poate fi deci privit ca un mediu care permite rularea containerelor pe orice platformă, bazat pe containerd. Ca beneficii, oferă compilare, testare, deployment, actualizare și recuperare în caz de eroare mai rapide față de modul standard de deployment al aplicațiilor.
Docker oferă un mediu uniform de dezvoltare și producție, unde nu se mai pune problema compatibilității aplicațiilor cu sistemul de operare și nu mai există conflicte între versiunile de biblioteci/pachete de pe sistemul gazdă. Containerele sunt efemere, așa că stricarea sau închiderea unuia nu duce la căderea întregului sistem. Ele ajută la asigurarea consistenței stricte între comportamentul în mediul de dezvoltare cu cel în mediul de producție.
De asemenea, Docker oferă flexibilitate maximă. Dacă, într-un proiect de mari dimensiuni, avem nevoie de unelte software noi pentru că se schimbă anumite cerințe, le putem împacheta în containere și apoi să le legăm foarte ușor la sistem. Dacă avem nevoie de replicarea infrastructurii pe alt mediu, putem refolosi imginile de Docker salvate în registru (un fel de repository de containere). Dacă avem nevoie de actualizarea anumitor componente, Docker ne permite să rescriem imaginile, ceea ce înseamnă că se vor lansa, mereu, cele mai noi versiuni ale componentelor sub formă de containere.
📄️ Imagini și containere
Containerele Docker au la bază imagini, care sunt pachete executabile lightweight de sine stătătoare ce conțin tot ce este necesar pentru rularea unor aplicații software, incluzând cod, runtime, biblioteci, variabile de mediu și fișiere de configurare. Imaginile au o dimensiune variabilă, nu conțin versiuni complete ale sistemelor de operare, și sunt stocate în cache-ul local sau într-un registru. O imagine Docker are un sistem de fișiere de tip union, unde fiecare schimbare asupra sistemului de fișiere sau metadate este considerată ca fiind un strat (layer), mai multe astfel de straturi formând o imagine. Fiecare strat este identificat unic (printr-un hash) și stocat doar o singură dată.
📄️ Arhitectura Docker
Docker are o arhitectură de tip client-server, așa cum se poate observa în imaginea de mai jos (preluată din documentația oficială Docker). Clientul Docker comunică, prin intermediul unui API REST (peste sockeți UNIX sau peste o interfață de rețea), cu daemon-ul de Docker (serverul), care se ocupă de crearea, rularea și distribuția de containere Docker. Clientul și daemon-ul pot rula pe același sistem sau pe sisteme diferite. Un registru Docker are rolul de a stoca imagini.
📄️ Instalare
Docker este disponibil în două variante: Community Edition (CE) și Enterprise Edition (EE). Docker CE este util pentru dezvoltatori și echipe mici care vor să construiască aplicații bazate pe containere. Pe de altă parte, Docker EE a fost creat pentru dezvoltare enterprise și echipe IT care scriu și rulează aplicații critice de business pe scară largă. Versiunea Docker CE este gratuită, pe când EE este disponibilă cu subscripție. În cadrul laboratorului de Cloud Computing, vom folosi Docker Community Edition. Docker este disponibil atât pe platforme desktop (Windows, macOS), cât și Cloud (Amazon Web Services, Microsoft Azure) sau server (CentOS, Fedora, Ubuntu, Windows Server 2016, etc.).
📄️ Testarea instalării
Pentru a verifica dacă instalarea s-a realizat cu succes, putem rula un container simplu de tip Hello World:
📄️ Rularea unui container
Am văzut mai sus cum putem rula un Hello World într-un container simplu, însă putem rula imagini mult mai complexe. Putem să ne creăm propria imagine sau putem descărca o imagine dintr-un registru, cum ar fi Docker Hub. Acesta conține imagini publice, care variază de la sisteme de operare (Ubuntu, Alpine, Amazon Linux, etc.) la limbaje de programare (Java, Ruby, Perl, Python, etc.), servere Web (NGINX, Apache), etc.
📄️ Crearea unei imagini
Până acum, am rulat imagini deja existente, însă acum vom vedea cum putem să ne creăm și publicăm propria noastră aplicație. Vom porni de la nivelul de jos al unei astfel de ierarhii, care este reprezentat de container. Deasupra acestui nivel se află serviciile, care definesc modul în care containerele se comportă în producție, iar la nivelul cel mai sus se află stiva, care definește interacțiunile dintre servicii. Sursele pentru acest exemplu se găsesc în arhiva de laborator.
📄️ Publicarea unei imagini într-un registru
Mai devreme, am creat o imagine de Docker pe care am rulat-o local într-un container. Pentru a putea rula imaginea creată în orice alt sistem, este necesar să o publicăm, deci să o urcăm într-un registru pentru a putea să facem deploy de containere cu imaginea noastră în producție. Un registru este o colecție de repository-uri, iar un repository este o colecție de imagini (similar cu GitHub, cu diferența că, într-un registru Docker, codul este deja construit și se rețin modificările făcute în straturile imaginilor de Docker, nu în cod). Există numeroase registre pentru imagini Docker (Docker Hub, Gitlab Registry, etc.), iar la laborator vom folosi registrul public Docker, pentru că este gratuit și pre-configurat.
📄️ Networking
Subsistemul de networking Docker este de tip pluggable și folosește drivere. Mai multe astfel de drivere există implicit, ele oferind funcționalitate de bază pentru componenta de rețea. Driverul de rețea implicit este bridge, și presupune crearea unui bridge software care permite containerelor conectate la aceeași rețea de acest tip să comunice între ele, oferind totodată izolare față de containerele care nu sunt conectate la această rețea bridge. Driverul de bridge Docker instalează automat reguli pe mașina gazdă astfel încât containerele de pe rețele bridge diferite nu pot comunica direct unele cu altele. Rețelele de tip bridge se aplică doar containerelor care rulează pe aceeași mașină Docker.
📄️ Volume și bind mounts
În Docker, datele dintr-un container nu sunt persistate în exterior. Pentru a ilustra acest lucru, putem rula un container simplu de Alpine, în care creăm un fișier apoi ieșim.
📄️ Docker pe Windows și pe MacOS
Docker a fost creat nativ pentru Linux, utilizând componente de kernel specifice Linux, cum ar fi cgroups sau namespaces, folosite pentru a izola procese și alte componente ale sistemului de operare. Începând din 2016, el poate rula nativ și pe Windows, dar doar pentru versiunile Windows Server 2016 și Windows 10. De aceea, pentru a rula pe un sistem de operare desktop precum un Windows mai vechi sau MacOS, Docker necesită rularea virtualizată.
📄️ Comenzi utile
Vă recomandăm să vă documentați de pe site-ul oficial Docker, întrucât comenzile oferite aici sunt minimul necesar de care aveți nevoie să puteți lucra cu Docker. În realitate, sunt mult mai multe comenzi, fiecare din ele având mult mai multe argumente.
📄️ Exerciții
Comenzi de bază