Differences

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

Link to this comparison view

rl:labs:11:contents:02 [2022/11/13 12:55]
vlad.traista [02. [20p] Docker Images]
rl:labs:11:contents:02 [2024/01/08 12:34] (current)
vlad_iulius.nastase [02. [10p] VPC Networks]
Line 1: Line 1:
-==== 02. [20pDocker Images ​====+====== 02. [10pVPC Networks ======
  
-Făcând o analogie cu lumea sistemelor de operareputem considera ​un Docker image ca fiind similar unui binar - o componenta statică ce poate fi lansată în execuție. Un Docker container este asemănător procesuluio componenta dinamică ​care este o instanță aflată în execuție a unei imagini Docker.+După accesarea proiectuluiproiectul va avea atașat ​un **VPC network** numit default, care are alocat subnet-urile implicite pentru fiecare regiune
  
-{{ :rl:labs:11:contents:docker-steps.png?600 |}}+{{ :rl:labs:12:contents:vpc-network.png?700 |}}
  
-<​note>​ +<note tip>Care era subrețeua folosită de Google Cloud pentru ​range-urile predefinite ​din fiecare ​regiune ​? </​note>​
-În cadrul secțiunii curente vom parcurge etapele construcției unei imagini Docker scoțând în evidență câteva particularități de implementare. +
-</​note>​ +
- +
-Pentru început, să listăm imaginile stocate local. În lista desfășurată veți vedea imaginile pe care le-am utilizat în secțiunea 1: +
-<code bash> +
-student@aldebaran:​~$ docker image ls +
-REPOSITORY ​         TAG                 IMAGE ID            CREATED ​            ​SIZE +
-alpine ​             latest ​             965ea09ff2eb ​       6 weeks ago         ​5.55MB +
-hello-world ​        ​latest ​             fce289e99eb9 ​       11 months ago       ​1.84kB +
-</​code>​ +
- +
-Ca strategie, Docker își propune să ofere o bibliotecă extrem de largă de servicii gata configurate,​ împachetate sub formă de containere. În cazul în care ne dorim să căutăm o aplicație, un middleware, un runtime etc. care ne-ar fi utile pentru a rezolva o cerință sau a dezvolta o soluție complexă, putem căuta în upstream dacă există deja o astfel de imagine dezvoltată. Pentru a face acest lucru avem diferite metode, atât din CLI cât și din browser. Implicit, engine-ul docker va căuta în **DockerHub registry**, echivalentul GitHub pentru imagini Docker. În terminologia Docker, un registry este un repository de imagini Docker: ''​docker search <nume imagine cautata>''​ +
-<note tip> +
-  * ''​docker search alpine''​ +
-  * ''​docker search httpd''​ +
-  * ''​docker search tomcat''​ +
-  * ''​docker search %%--filter%% is-official=true golang''​ +
-</​note>​ +
- +
-<note important>​ +
-Un aspect foarte important din output-ul anterior îl reprezintă coloana Official, atribut ce garantează faptul că imaginea vizată este întreținută și verificată de către o comunitate de încredere, validată de către Docker. +
-</​note>​  +
- +
-Online putem accesa: ​ https://​hub.docker.com +
-Pentru informații despre imagine de Alpine: ​ https://​hub.docker.com/​_/​alpine +
-Meniul tags este utilizat pentru diferențierea imaginilor pe versiuni/pe releases: https://​hub.docker.com/​_/​alpine?​tab=tags +
- +
-Să creăm o imagine pornind de la imaginea oficială **Alpine** cu versiunea de release **latest**. În folder-ul home al utilizatorului curent creați un fișier numit ''​Dockerfile''​ și scrieți următoarele 2 linii: +
-<code bash> +
-student@aldebaran:​~$ cat Dockerfile +
-FROM alpine:​latest +
-CMD ["​echo",​ "Am facut si bune am facut si RL"] +
-</​code>​ +
- +
-Se poate observa ușor forma declarativă,​ auto-descriptivă,​ a instrucțiunilor Docker.  +
- +
-Urmând același flux ca în cazul construcției de software, vom compila codul Docker anterior scris, rezultatul fiind un obiect de tip Docker Image. Timpul de execuție poate varia și poate dura chiar și câteva minute. +
- +
-<code bash> +
-student@aldebaran:​~$ docker build -t rlrules/​rlhello:​v1.0 . +
-</​code>​ +
- +
-Înainte de a merge mai departe, să disecăm succint convenția de nume anterior ​folosită+
-Numele imaginii Docker are în general următorul format:  +
- +
-''​%%<​DockerHub User (Repository) >/<​Nume Aplicație (Nume Imagine)>:<​tag (versiune, release)>​ +
-rlrules/​rlhello:​v1.0%%''​ +
- +
-<​spoiler ​ Convenție ​de nume extinsă>​ +
-În sens mai extins, în cazul în care organizația în care lucrăm deține propriul repository de artefacte Docker (propriul Docker Registry), similar cu menținerea propriului Code Repository (ex: GitHub Enterprise, GitLab on premise, Atlassian Bitbucket etc.), convenția de nume este extinsă: +
- +
-''​%%<​adresă/​hostname registry>:<​port (oficial 5000)>/<​user (repository)>/<​Nume Aplicație (Nume Imagine)>:<​tag (versiune, release)>​ +
-mypersonalregistry:​5000/​rlrules/​rlhello:​v1.0%%''​ +
-</​spoiler>​\\ +
-Respectarea unui astfel de format ne permite ulterior să putem face operațiuni de push sau pull asemănător acțiunilor pe care le putem face în GitHub/git server ​pentru ​un repository în care putem versiona și stoca codul. +
- +
-În continuare vom rula imaginea anterior creată: +
-<code bash> +
-student@aldebaran:​~$ docker run rlrules/​rlhello:​v1.0 +
-Am facut si bune am facut si RL +
-</​code>​ +
- +
-Utilizarea instucțiunii **CMD**, din Dockerfile, ne oferă, suplimentar,​ capabilitatea suprascrierii la runtime a comenzii specificate în declarație. Să testăm: +
-<code bash> +
-student@aldebaran:​~$ docker run rlrules/​rlhello:​v1.0 "​hello,​ world"​ +
-docker: Error response from daemon: OCI runtime create failed: container_linux.go:​346:​ starting container process caused "exec: \"​hello,​ world\":​ executable file not found in $PATH":​ unknown. +
-</​code>​ +
- +
-Eroarea apărută se datorează faptului că "​hello,​ world" nu este o comandă viabilă în Linux și deci nu este interpretată de către shell-ul utilizat (ex: bash, sh etc.)  +
- +
-<code bash> +
-student@aldebaran:​~$ docker run rlrules/​rlhello:​v1.0 cat /​etc/​issue +
-Welcome to Alpine Linux 3.10 +
-Kernel \r on an \m (\l) +
- +
-student@aldebaran:​~$ docker run rlrules/​rlhello:​v1.0 echo "​hello,​ world"​ +
-hello, world +
-</​code>​ +
- +
-Cele două comenzi vor rula cu succes, prima afișând o informație de pe container în timp ce a doua afișează mesajul transmis comenzii ''​echo'':​ ''​hello,​ world''​ +
- +
-Să modificăm imaginea anterioară înlocuind instrucțiunea **CMD** cu instrucțiunea **ENTRYPOINT**. +
-<code bash> +
-student@aldebaran:​~$ cat Dockerfile +
-FROM alpine:​latest +
-ENTRYPOINT ["​echo",​ "Am facut si bune am facut si RL"] +
-</​code>​ +
-În etapa de build vom construi un nou release v2.0: +
- +
-<code bash>​student@aldebaran:​~$ docker build -t rlrules/​rlhello:​v2.0 .</​code>​ +
- +
-Rularea release-ului v2.0 va avea același outcome ca în cazul versiunii anterioare : +
- +
-<code bash>​student@aldebaran:​~$ docker run rlrules/​rlhello:​v2.0</​code>​ +
- +
-Rezultatul utilizării celor 2 instrucțiuni (**CMD** și **ENTRYPOINT**) este același! Care este totuși diferența între **CMD** și **ENTRYPOINT**?​ +
- +
-Pentru a vedea acest lucru, să încercăm să rulăm imaginea nouă utilizând, de data aceasta, argumente:​ +
-<code bash> +
-student@aldebaran:​~$ docker run rlrules/​rlhello:​v2.0 "​hello,​ world"​ +
-Am facut si bune am facut si RL hello, world +
-student@aldebaran:​~$ docker run rlrules/​rlhello:​v2.0 cat /​etc/​issue +
-Am facut si bune am facut si RL cat /​etc/​issue +
-student@aldebaran:​~$ docker run rlrules/​rlhello:​v2.0 echo "​hello,​ world"​ +
-Am facut si bune am facut si RL echo hello, world +
-</​code>​ +
- +
-Vedem că în cazul **ENTRYPOINT**,​ indiferent de argumentul adăugat la finalul comenzii docker run, acesta va fi anexat la comanda setată în instrucțiunea ​din Dockerfile. Întrucât comanda configurată este ''​echo <​string>'',​ șirurile de caractere adăugate ulterior vor fi atașate stringului "Am făcut și bune, am făcut și RL". Într-o descriere mai pragmatică,​ **ENTRYPOINT** imprimă rolul unui executabil clasic asupra imaginii docker. +
- +
-<​hidden>​ +
-<note important>​ +
-Challenge: Ce hack putem utiliza pentru a rula o altă comandă pe container?​ +
-<​solution>​ +
-<code bash> +
-docker run --entrypoint '/​bin/​ls'​ rlrules/​rlhello:​v2.0 # Comanda bună +
-docker run rlrules/​rlhello:​v2.0 ;cat /etc/passwd # WRONG - cat-ul e rulat pe host +
-</​code>​ +
-</​solution>​ +
-</​note>​ +
-</​hidden>​ +
-Un mecanism frecvent utilizat este conjuncția dintre cele două instrucțiuni. Putem folosi **ENTRYPOINT** pentru a desemna comanda fixă, explicit atașată containerului,​ în timp ce instrucțiunea **CMD** oferă argumentul default, interschimbabil,​ al comenzii definite de **ENTRYPOINT**. +
- +
- +
-Vom modifica imaginea astfel încât să reflecte scenariul definit anterior: +
-<code bash> +
-student@aldebaran:​~$ cat Dockerfile +
-FROM alpine:​latest +
- +
-ENTRYPOINT ["​echo"​] +
-CMD ["Am facut si bune, am facut si RL"] +
-</​code>​ +
- +
-Comanda echo este fixă, imutabilă, în timp ce string-ul ''​Am făcut și bune, am făcut și RL''​ devine valoare implicită în cazul în care niciun argument suplimentar nu este specificat în comanda docker run. +
- +
-Compilăm și rulăm noua imagine: +
- +
-<code bash> +
-student@aldebaran:​~$ docker build -t rlrules/​rlhello:​v3.0 . +
-student@aldebaran:​~$ docker run rlrules/​rlhello:​v3.0 +
-Am facut si bune, am facut si RL +
-student@aldebaran:​~$ docker run rlrules/​rlhello:​v3.0 "​hello,​ world"​ +
-hello, world +
-student@aldebaran:​~$ docker run rlrules/​rlhello:​v3.0 cat /​etc/​issue +
-cat /​etc/​issue +
-student@aldebaran:​~$ docker run rlrules/​rlhello:​v3.0 echo "​hello,​ world"​ +
-echo hello, world +
-</​code>​ +
- +
-Lista instrucțiunilor Docker nu se rezumă doar la **FROM** sau **CMD**%%/​%%**ENTRYPOINT**. Pentru configurații mai complexe există o colecție largă de comenzi ce pot fi declarate la nivelul unui Dockerfile. Referințe despre aceste opțiuni se pot găsi pe site-ul Docker (https://​docs.docker.com/​engine/​reference/​builder/​) +
- +
-În continuare vom crește complexitatea și vom construi un Dockerfile extins: +
-<code bash> +
-student@aldebaran:​~$ cat Dockerfile +
-FROM ubuntu:​latest +
-MAINTAINER rl-awesome-students-team +
- +
-RUN apt-get update && apt-get -y install cowsay +
-ENV RL_EXEC_PATH "/​usr/​games/"​ +
-ENV PATH=${PATH}:​${RL_EXEC_PATH} +
- +
-ENTRYPOINT ["​cowsay"​] +
-CMD ["Am facut si bune, am facut si RL"] +
-</​code>​ +
- +
-<​note>​ +
-Daca rularea comenzilor de mai jos dureaza foarte mult (mai mult de 5 minute), incercati urmatorul "​hack":​ +
-<code bash>​student@aldebaran:​~$ cp /​etc/​apt/​sources.list . # dati cu sudo daca va da Permission Denied</​code>​ +
- +
-Modificati fisierul Dockerfile prin introducerea dupa comanda de FROM a urmatorii comenzi: +
-<​code>​COPY ./​sources.list /​etc/​apt/</​code>​ +
-</​note>​ +
- +
-Vom compila și rula imaginea nou definită:​ +
-<code bash>​student@aldebaran:​~$ docker build -t rlrules/​rlhello:​v4.0 .</​code>​ +
-<code bash>​student@aldebaran:​~$ docker run rlrules/​rlhello:​v4.0</​code>​ +
-<code bash>​student@aldebaran:​~$ docker run rlrules/​rlhello:​v4.0 "​Hello,​ world"</​code>​ +
- +
-În cadrul configurației curente, plecând de la imaginea de Ubuntu:​latest,​ la build time am instalat pachetul cowsay, am setat variabile de mediu, am specificat maintainer-ul imaginii și am configurat un parametrul implicit, în cazul în care imaginea este rulată fără parametrii adiționali. Complexitatea poate crește, în funcție de acțiunile pe care trebuie să le facem pentru a prepara containerul cu toate dependințele de care are nevoie.  +
- +
-Un aspect important și interesant legat de imagini este reprezentat de construcția pe layere/​straturi. Fiecare modificare adusă imaginii anterioare poate rezulta în construcția unui strat suplimentar. Dintr-o perspectivă simplificată,​ putem spune că fiecare ​instrucțiune din Dockerfile construiește o imagine nouă, intermediară,​ care se diferențiază de cea anterioară prin modificările aduse de instrucțiunea curentă. Plecând de la această premisă, un layer este exact acest delta dintre 2 imagini succesive. Dintr-o perspectivă mai complexă, nu orice instrucțiune rezultă într-un strat nou. Comenzi precum **CMD**, **MAINTAINER**,​ **ENTRYPOINT** nu aduc o modificare substanțială imaginii, ci alterează aspecte legate de metadatele atașate unei imagini.  +
- +
-Să validăm această informație pentru imaginea rlrules/​rlhello:​v4.0:​ +
-<code bash>​student@aldebaran:​~$ docker image inspect rlrules/​rlhello:​v4.0</​code>​ +
-În output-ul comenzii anterioare, căutați secțiunea RootFS. Pentru simplitate puteți rula: +
-<code bash> +
-student@aldebaran:​~$ docker image inspect --format "​{{json .RootFS}}"​ rlrules/​rlhello:​v4.0 +
-</​code>​ +
- +
-<note important>​ +
-Câte layere pot fi numărate? De ce? +
-<​solution>​ +
-<code bash> +
-student@aldebaran:​~$ docker image inspect --format "​{{json .RootFS}}"​ rlrules/​rlhello:​v4.0 | grep -o "​sha256"​ | wc -l +
-</​code>​ +
-</​solution>​ +
-</​note>​ +
- +
-Să vedem care au fost acele instrucțiuni care au dus la construcția celor 5 straturi: +
-<code bash>​student@aldebaran:​~$ docker image history rlrules/​rlhello:​v4.0</​code>​ +
-Toate instrucțiunile care au un ''​SIZE > 0''​ sunt responsabile de crearea unui layer suplimentar în imagine: +
-  * primele nivele sunt moștenite din construcția imaginii de bază Ubuntu cu tag-ul latest (''​**FROM** ubuntu:​latest''​) +
-  * ultimul nivel este adăugat de noi prin instrucțiunea ''​**RUN** apt-get update && apt-get install''​ ce creează noi fișiere în sistemul de fișiere +
- +
-În cazul în care ne dorim să ștergem o imagine de pe sistem, mai întâi trebuie să obținem identificatorul unic al imaginii (''​IMAGE ID''​):​ +
-<code bash>​student@aldebaran:​~$ docker image ls</​code>​ +
- +
-Să încercăm să ștergem imaginea rlrules/​rlhello:​v1.0:​ +
-<code bash>​student@aldebaran:​~$ docker image rm <id imagine rlrules/​rlhello:​v1.0></​code>​ +
-<note important>​De ce returnează eroare? Ce putem face pentru a șterge imaginea?</​note>​+
  
-O soluție a problemei anterioare o reprezintă ștergerea containerului care utilizează imaginea vizată: +<​note ​warning
-<code bash>​student@aldebaran:​~$ docker container ps -a</​code>​ +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.
-<​note ​important+
-Care este containerul care utilizează imaginea vizată+
-<code bash>​student@aldebaran:​~$ docker container rm <id container oprit care utilizeaza imaginea v1.0></​code>​+
 </​note>​ </​note>​
  
-Acum putem efectua ștergerea imaginii+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. 
-<code bash>student@aldebaran:​~docker image rm <id imagine rlrules/​rlhello:​v1.0></code>+În pagina de creare a unui nou VPC trebuie să completăm următoarele detalii
 +  - Numele VPC-ului (doar caractere mici, cifre și cratimă sunt acceptate) și opțional o descriere - **student$X$-vpc-<name>** (e.g. student1-vpc) 
 +  - 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) 
 +  - Regiunea (este important să cream toate subnet-urile din acest laborator în aceeași regiune, preferabil **europe-west1**) 
 +  - Range-ul de adrese IP din subnet - **10.$X$.0.0/24** (unde $X$ e id-ul de student ) 
 +  - 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.
  
-**Voila!** 
  
-Până în acest moment, ne-am familiarizat cu Docker Engine și cu obiectele cele mai importante din lumea Docker. În continuare, în cadrul laboratorului,​ vom începe să punem server-ul nostru de imagini în contextul de rulare cerut. Întrucât aplicația este slab cuplată, un prim pas care trebuie realizat este să stabilim comunicarea între serviciile componente. În acest context ne vom muta atenția asupra conceptelor de Networking din Docker.+{{ :​rl:​labs:​12:​contents:​create-vpc-network.png?500 |}}
rl/labs/11/contents/02.1668336911.txt.gz · Last modified: 2022/11/13 12:55 by vlad.traista
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