This is an old revision of the document!


Laborator 11. Virtualizare în Docker

Cunoștințe și abilități ce vor fi dobândite

  • Intoducere în Docker CLI
  • Docker Container vs Docker Image
  • Dockerfile și construcția de Imagini
  • Union File System: Overlay2 - image layers
  • Docker Volumes
  • Docker Networking: bridge & overlay (VXLAN)
  • Docker SWARM
  • Introducere în arhitecturi pe microservicii
  • Arhitecturi pe microservicii vs Arhitecturi monolite

Pregătire infrastructură de laborator

Creați 2 mașini virtuale.

Folosiți imaginea Ubuntu 16.04 Xenial cu flavor m1.medium pe Openstack.

Atenție ! Utilizatorul NU este student, ci ubuntu.

ubuntu@hostname:~# sudo apt-get update
ubuntu@hostname:~# sudo apt-get install docker
ubuntu@hostname:~# sudo apt-get install docker.io
ubuntu@hostname:~# cat /etc/hostname
$MY_HOSTNAME
ubuntu@hostname:~# cat /etc/hosts   # Adăugați linia următoare în fișierul /etc/hosts
127.0.0.1 $MY_HOSTNAME
[...]
ubuntu@hostname:~# sudo usermod -aG docker $USER
ubuntu@hostname:~# exit # LOGOUT
 
$FEP_USER@fep.grid.pub.ro:~$ ssh -i ~/.ssh/id_rsa ubuntu@$VM_IP_ADDRESS # LOGIN

Pentru instalarea Docker pe Ubuntu urmăriți procedura de aici [1]. Suplimentar față de pașii descriși anterior, rulați comanda: sudo usermod -aG docker $USER desprinsă din documentația [2]

Introducere

Iată că ne regăsim la sfârșitul semestrului I din anul 3, după o lungă și dificilă călătorie prin tainele ingineriei Calculatoarelor, traseu ce a adus în planul de studiu și materia Rețele locale.

Întrucât, preponderența claselor din anii anteriori a fost cu precădere orientată pe multe din aspectele complexe ale dezvoltării de software, în laboratorul de azi ne propunem să oferim o altă perspectivă în conceperea unei aplicații sau a unei soluții. Aspecte precum volumul de date de procesat, toleranța la defecte, portabilitatea sau scalabilitatea sunt constrângeri esențiale care trebuie tratate în procesul de implementare a unei soluții sau aplicații.

Standardele și cerințele dictate de industrie se focalizează din ce în ce mai mult pe adoptarea modelului de cloud, menit, de cele mai multe ori, să ofere un șablon/pattern care să adreseze parțial sau integral constrângerile (sau oportunitățile) menționate anterior.

Laboratorul curent își propune o introducere pragmatică în modele clasice de system design & architecture încercând să atingă gradual mici elemente de complexitate, care pot aduce un plus de valoare unei aplicații în contextul de cloud.

Modelele prezentate pot fi puncte de plecare importante pentru parcurgerea unor interviuri de Site Reliability Engineer, Cloud Engineer sau DevOps Engineer.

Mai mult, laboratorul deservește, în egală măsură, o introducere în Docker, Docker Networking & Docker Orchestration, facilitând implementarea graduală a unui serviciu web, de la concept până într-o formă care ar putea răspunde unor cerințe reale de producție. Laboratorul se adresează în egală măsură atât oamenilor cu înclinații către dezvoltare cât și oamenilor care se orientează spre poziții operaționale.

Ben Treynor VP of Engineers @ Google și inventatorul termenului Site Reliability Engineer încercând să definească conceptul: “Fundamentally, it’s what happens when you ask a software engineer to design an operations function”

Înainte de a pătrunde în tainele containerizarii cu Docker, vom încerca să definim un model arhitectural care să se încadreze în tipul de aplicație pentru care Docker devine o unealtă importantă.

Arhitectura Monolită vs. Arhitectura bazată pe microservicii

Este greșit să plecăm de la premisa că o abordare este mai bună decât cealaltă, fiecare fiind o opțiune optimă în contextul potrivit. O abordare monolită implică dezvoltarea întregului stack de aplicație pe un singur nod, un singur sistem, în timp ce, în cadrul modelului bazat pe microservicii, fiecare unitate funcțională va avea propriul mediu izolat în care rulează. Gradul de rezoluție pentru definirea unității funcționale poate varia, de la viziunea macro, cu 2 componente: Frontend - Backend, până la nivelul de granularitate prin care putem avea fiecare feature al aplicației dezvoltat ca un microserviciu (ca un obiect rulând individual).

O comparație minimală între cele două modele arhitecturale, reliefând aspecte pozitive și problematice în ambele abordări, poate fi văzută în tabelul următor:

Arhitecturi Monolite Arhitecturi bazate pe Microservicii
Modulele unei aplicații sunt Tightly Coupled (ex: Comunicare Inter Proces - IPC) Serviciile unei aplicații sunt Loosely Coupled (ex: communicare peste rețea utilizând mesaje HTTP via REST API microservices)
Fiecare funcționalitate nouă trebuie scrisă în același limbaj de programare. Fiecare serviciu component al aplicației poate fi scris într-un limbaj diferit.
Modificarea codului presupune recompilarea și reinstalarea (redeployment-ul) întregii aplicații. Modificarea unui serviciu/feature necesită reinstalarea acelui serviciu, celelalte rămânând intacte și operaționale.
Simplu de dezvoltat. Poate aduce un nivel de complexitate mult prea mare (ex: pentru fiecare serviciu trebuie construit un API care să faciliteze comunicația între microservicii)
Scalarea aplicației se aplică întregului stack. Procedurile de scalare pot fi aplicate pe servicii individuale (eg: multiplicarea serviciului de Frontend al unui magazin online în timpul reducerilor de Black Friday)

Abordarea pe care vom merge în continuare este una bazată pe servicii, cu amendamentul că unitățile funcționale vor fi construite la un nivel de rezoluție macro: Frontend și Backend, la care vom atașa și o bază de date. Să presupunem că avem o cerere din partea unui angajator de a dezvolta un site de stocare și partajare de imagini. Trebuie să ne asigurăm că acesta îndeplinește un set minimal de caracteristici, înainte de a fi lansat în producție:

  • nivelul de utilizare va fi unul mediu
  • va porni cu un set minimal de funcționalități, dar va fi extins în timp
  • echipa de dezvoltatori este foarte dinamică din perspectiva migrării către alte proiecte, iar cunoștințele legate de anumite limbaje de programare sunt neuniforme
  • se dorește ca serviciul să aibă o rată de availability care să tindă spre procentul de 99% (Maxim 7 ore 18 minute și 17.5 secunde downtime pe lună - https://uptime.is/ )
  • se estimează că în perioada sărbătorilor vor exista spike-uri în utilizare, întrucât audiența va căuta activ poze cu mesaje motivaționale.

Aplicația construită pentru laborator va aborda o arhitectură simplificată, bazată pe servicii, Vom încerca să utilizăm Docker pentru a ne asigura că îndeplinim cât mai multe din cerințele date. Înainte de a parcurge cerințele proiectului, ne vom familiariza cu tehnologia de containerizare.

Exerciții

00. Completare formular de feedback

Vă invităm să evaluați activitatea echipei de RL și să precizați punctele tari și punctele slabe și sugestiile voastre de îmbunătățire a materiei. Feedback-ul vostru este foarte important pentru noi să creștem calitatea materiei în anii următori și să îmbunătățim materiile pe care le veți face în continuare.

Găsiți formularul de feedback în partea dreaptă a paginii principale de RL de pe curs.pub.ro într-un frame numit FEEDBACK.

Vă mulțumim!

01. [0p] Definere proiect

Din stanga sus, de lângă logo-ul Google Cloud se poate fie selecta proiectul de lucru, fie crea un nou proiect.

Dacă cream un nou proiect (apăsăm pe butonul aferent), pagina pentru proiect nou va fi deschisă pe ecran de unde putem seta numele proiectului și organizația la care este asociat.

Pentru acest laborator, ne vom folosi de proiectul upb-retele-locale-2024 prin contul oferit de catre asistent.

Dacă nu vă apare proiectul în listă, încercați să îl căutați folosind numele proiectului (upb-retele-locale-2024).

02. [10p] VPC Networks

După accesarea proiectului, proiectul va avea atașat un VPC network numit default, care are alocat subnet-urile implicite pentru fiecare regiune.

Care era subrețeua folosită de Google Cloud pentru range-urile predefinite din fiecare regiune ?

GCP impune o limitare de maxim 5 Cloud Router pentru fiecare regiune. Deoarece un Cloud Router este atașat la o rețea, va trebui să avem maxim 5 VPC Networks per regiune. Înainte de a selecta regiunea pentru VPC Network verificați că nu sunt deja 5 VPC Networks în acea regiune.

Avem nevoie de un VPC custom pe care îl putem crea apăsând pe butonul CREATE VPC NETWORK aflat sub câmpul de căutare. În pagina de creare a unui nou VPC trebuie să completăm următoarele detalii:

  1. Numele VPC-ului (doar caractere mici, cifre și cratimă sunt acceptate) și opțional o descriere - student$X$-vpc-<name> (e.g. student1-vpc)
  2. Numele unui subnet definit în interiorul acestui VPC (aceleași limitări ca mai sus la caracterele acceptate) - student$X$-host (e.g. student1-host)
  3. Regiunea (este important să cream toate subnet-urile din acest laborator în aceeași regiune, preferabil europe-west1)
  4. Range-ul de adrese IP din subnet - 10.$X$.0.0/24 (unde $X$ e id-ul de student )
  5. Regulile de firewall aplicate pe VPC (nu uitați să bifați regulile de permitere SSH cel puțin). Vom edita regulile mai târziu pentru fiecare VPC.

03. [10p] VPC Subnets

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ă.

Î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).

Mai departe, vom crea 3 subnetări in VPC creat la pasul anterior(pentru instanțele Red, Green, Blue).

Masca de rețea corespunzătoare (/24 pentru subnet-urile private):

  • 10.$X$.1.0/24
  • 10.$X$.2.0/24
  • 10.$X$.3.0/24, unde $X$ - id-ul studentului

Recomandăm ca numele pentu subnet-uri să fie sugestive. Pentru exercițiul nostru:

  • student$X$-red
  • student$X$-green
  • student$X$-blue, unde $X$ - id-ul studentului

Din secțiunea VPC Networks, dacă mergem pe Subnets in current project și selectăm doar VPC-network-ul creat de noi anterior (excludem default), ar trebui să avem următoarea listă:

04. [10p] Rezervare adresă IP publică

Dorim să ne rezervăm propria adresă IP publică statică pentru a o asocia mai târziu unei instanțe din topologia noastră. În VPC Network, alegem secțiunea IP addresses și opțiunea Reserve External Static IP Address (păstrăm setările default), setăm Name cu valoarea student$X$-public, Network Service Tier bifăm Standard, selectăm tipul Regional și aceeași regiune definită pe VPC-ul creat mai devreme (preferabil europe-west1) și apăsăm Reserve.

Este un cost pentru fiecare adresă IP publică statică care nu este alocată unei instanțe (“totul în viață se plătește”).

Acum avem în lista de adrese IP publice statice din contul nostru, adresa IP alocată mai devreme.

05. [15p] Cloud Router

Căutăm în câmpul din centru Cloud Router din secțiunea Hybrid Connectivity și selectăm Create Router.

Căutați Cloud Router în bara de căutare pentru a găsi secțiunea.

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.

Regiunea selectată va fi aceeași ca la subpunctele anterioare (preferabil europe-west1).

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.

06. [15p] Cloud NAT

Căutăm Cloud NAT din secțiunea Network Services și selectăm Get Started pentru a configura un Cloud NAT gateway.

Căutați Network Services în bara de căutare pentru a găsi secțiunea.

Întâi trebuie ales un nume pentru noul gateway și putem utiliza student$X$-gw. (student1-gw)

În secțiunea dedicată selecției Cloud Router-ului trebuie mai întâi să selectăm VPC-ul definit mai devreme, apoi regiunea (aceeași ca la pașii anteriori). Ultimul pas este selectarea instanței de Cloud Router definită la pasul precedent. Tot la acest pas se poate selecta care dintre subrețelele definite sunt mapate către Cloud NAT Gateway. Avem opțiunea fie de a include toate subrețelele, fie de a selecta individual fiecare rețea în parte.

De asemenea, avem fie opțiunea de a selecta o adresă IP publică rezervată sau de a utiliza o adresă în mod automat.

07. [30p] Instanțe Compute Engine

În pagina de start a Google Cloud avem un buton Create a VM.

Prima data creăm instanța Host.

Vom selecta următoarele configurații:

În secțiunea Machine configuration: e2-small.

În secțiunea Boot Disk alegeți imaginea sistemului de operare: Ubuntu 22.04 x86_64.

Expandând secțiunea Advanced options putem accesa secțiunea Networking.

În această secțiune setăm tipul de interfață de rețea ( gVNIC sau VirtIO ).

gVNIC - Google Virtual NIC este un tip de interfață virtuală de rețea creat pentru Compute Engine ca alternativă la virtIO, oferind performanțe mai bune și o mai bună consistență.

Alegem VPC-ul corespunzător creat anterior.

În meniul de selecție pentru adresa IP internă ( Primary internal IPv4 address ) putem selecta ca adresă IP fie o adresă de tip efemer, fie una custom. Adresele IP de tip efemer nu se vor schimba dacă instanța va fi oprită sau repornită, se schimbă doar în cazul în care instanța va fi ștearsă.

În meniul de selecție pentru adresa IP externă ( External IPv4 address ) vom folosi adresa IP creată la exercițiul anterior doar pentru interfața către internet, pentru celelalte interfețe nu vom adaugă nicio adresa publică. În cazul în care această nu apare, vom crea altă adresa IP publică.

Pentru a ne putea conecta pe instanțele create prin SSH avem două modalități.

Prima modalitate este să folosim conectarea din browser, GCP va genera automat chei de ssh pentru terminalul din browser, iar numele de utilizator creat implicit pe instanță este numele de utilizator aferent Google (Ex. popescuion@gmail.com va avea utilizatorul implicit popescuion).

A doua modalitate este utilizarea de chei proprii de SSH, le puteți salva în secțiunea Security → Manage Access → Add Item fie în momentul în care creați mașina virtuală, fie editând detaliile ulterior. Nu adăugați chei de ssh pentru utilizatorul implicit folosind terminalul pentru că vor fi șterse. Această metodă necesită creare unor chei de SSH în prealabil.

Odată adăugată cheia, GCP va crea și un utilizator nou, la fel că cel menționat în cheie. De exemplu, dacă cheia are formatul <CHEIE_PUBLICA> andrei@hostname-andrei, atunci GCP va crea un nou utilizator andrei pe care îl puteți folosi să va conectați prin SSH.

Continuăm cu celelalte instanțe Blue, Red și Green.

În secțiunea Machine configuration: e2-small.

În secțiunea Boot Disk alegeți imaginea sistemului de operare: Ubuntu 22.04 x86_64.

Expandând secțiunea Advanced options putem accesa secțiunea Networking.

În meniul de selecție pentru adresa IP internă ( Primary internal IPv4 address ) vom selecta adresa de tip efemer.

În meniul de selecție pentru adresa IP externă ( External IPv4 address ) nu vom selecta nicio adresă, folosind None.

În cazul în care ați adăugat cheia de SSH publică pe toate cele 4 instanțe, vă puteți loga pe instanța Host folosind adresa IP publică a acesteia. În cazul în care folosiți (recomandat) și un agent ssh, puteți adăuga la comanda ssh și opțiunea -A, iar ulterior vă puteți loga de pe instanța Host pe celelalte 3.

ssh -i [private_key] <google-username>@[ip_public] -A

Pentru a ne putea conecta prin ssh de pe Host și la celelalte instanțe fără a utiliza ssh-agent, va trebui să copiem cheia privată de pe stația locală pe Host:

# pe Linux:
scp -i [private_key] [private_key] <google-username>@[ip_public]:~

(pe Windows, puteți folosi WinSCP)

Verificați conectivitatea la Internet pe cele 4 instanțe (Host, Red, Green, Blue).

08. [10p] ICMP

În cazul în care atunci când ați creat VPC-ul nu ați bifat și regula de permitere ICMP veți observa că nu putem să dăm ping de pe oricare stație către oricare stație.

Pentru a permite traficul de ICMP, adăugăm câte o nouă regulă în fiecare VPC în acest scop.

Verificați conectivitatea între Red, Green și Blue.

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
rl/labs/11.1575896158.txt.gz · Last modified: 2019/12/09 14:55 by marius.calapod
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