Što je Docker: kratki izlet u povijest i osnovne apstrakcije

Počelo je 10. kolovoza u Slurmu Docker video tečaj, u kojem ga analiziramo u potpunosti - od osnovnih apstrakcija do mrežnih parametara.

U ovom ćemo članku govoriti o povijesti Dockera i njegovim glavnim apstrakcijama: Image, Cli, Dockerfile. Predavanje je namijenjeno početnicima, tako da je malo vjerojatno da će biti zanimljivo iskusnim korisnicima. Neće biti krvi, slijepog crijeva ili dubokog urona. Same osnove.

Što je Docker: kratki izlet u povijest i osnovne apstrakcije

Što je Docker

Pogledajmo definiciju Dockera iz Wikipedije.

Docker je softver za automatizaciju postavljanja i upravljanja aplikacijama u kontejnerskim okruženjima.

Iz ove definicije ništa nije jasno. Posebno je nejasno što znači "u okruženjima koja podržavaju kontejnerizaciju". Da bismo to saznali, vratimo se u prošlost. Počnimo s erom koju konvencionalno nazivam "Monolitna era".

Monolitno doba

Monolitno doba su rane 2000-e, kada su sve aplikacije bile monolitne, s hrpom ovisnosti. Razvoj je dugo trajao. U isto vrijeme nije bilo puno servera, svi smo ih znali po imenu i nadzirali. Postoji tako smiješna usporedba:

Kućni ljubimci su domaće životinje. U monolitnoj eri postupali smo prema našim poslužiteljima kao prema kućnim ljubimcima, njegovanim i njegovanim, otpuhivanjem mrvica prašine. A za bolje upravljanje resursima koristili smo virtualizaciju: uzeli smo poslužitelj i izrezali ga na nekoliko virtualnih strojeva, čime smo osigurali izolaciju okoline.

Virtualizacijski sustavi temeljeni na hipervizoru

Vjerojatno je svatko čuo za virtualizacijske sustave: VMware, VirtualBox, Hyper-V, Qemu KVM, itd. Omogućuju izolaciju aplikacija i upravljanje resursima, ali imaju i nedostatke. Za virtualizaciju vam je potreban hipervizor. A hipervizor je dodatni resurs. A sam virtualni stroj obično je cijeli kolos - teška slika koja sadrži operativni sustav, Nginx, Apache i možda MySQL. Slika je velika i virtualni stroj je nezgodan za rukovanje. Zbog toga rad s virtualnim strojevima može biti spor. Kako bi se riješio ovaj problem, stvoreni su virtualizacijski sustavi na razini kernela.

Sustavi virtualizacije na razini jezgre

Virtualizaciju na razini jezgre podržavaju OpenVZ, Systemd-nspawn, LXC sustavi. Upečatljiv primjer takve virtualizacije je LXC (Linux Containers).

LXC je virtualizacijski sustav na razini operativnog sustava za pokretanje više izoliranih instanci operativnog sustava Linux na jednom čvoru. LXC ne koristi virtualne strojeve, već stvara virtualno okruženje s vlastitim procesnim prostorom i mrežnim stogom.

U biti LXC stvara spremnike. Koja je razlika između virtualnih strojeva i spremnika?

Što je Docker: kratki izlet u povijest i osnovne apstrakcije

Spremnik nije prikladan za izolaciju procesa: ranjivosti se nalaze u virtualizacijskim sustavima na razini kernela koje im omogućuju bijeg iz spremnika na glavno računalo. Stoga, ako trebate nešto izolirati, bolje je koristiti virtualni stroj.

Razlike između virtualizacije i kontejnerizacije mogu se vidjeti na dijagramu.
Postoje hardverski hipervizori, hipervizori na vrhu OS-a i spremnici.

Što je Docker: kratki izlet u povijest i osnovne apstrakcije

Hardverski hipervizori su super ako stvarno želite nešto izolirati. Budući da je moguće izolirati na razini memorijskih stranica i procesora.

Postoje hipervizori kao program, a postoje i spremnici, ao njima ćemo dalje. Sustavi za kontejnerizaciju nemaju hipervizor, ali postoji Container Engine koji kreira i upravlja kontejnerima. Ova stvar je laganija, tako da zbog rada s jezgrom ima manje troškova ili ih uopće nema.

Što se koristi za kontejnerizaciju na razini kernela

Glavne tehnologije koje vam omogućuju stvaranje spremnika izoliranog od drugih procesa su prostori imena i kontrolne grupe.

Prostori imena: PID, umrežavanje, montiranje i korisnik. Ima ih još, ali radi lakšeg razumijevanja usredotočit ćemo se na njih.

PID Namespace ograničava procese. Kada, na primjer, stvorimo PID Namespace i tamo smjestimo proces, on postaje s PID-om 1. Obično je u sustavima PID 1 systemd ili init. Sukladno tome, kada proces smjestimo u novi imenski prostor, on također prima PID 1.

Networking Namespace vam omogućuje da ograničite/izolirate mrežu i postavite svoja sučelja unutra. Montiranje je ograničenje datotečnog sustava. Korisnik—ograničenje za korisnike.

Kontrolne grupe: Memorija, CPU, IOPS, Mreža - ukupno oko 12 postavki. Inače se nazivaju i C-grupe (“C-grupe”).

Kontrolne grupe upravljaju resursima za spremnik. Kroz kontrolne grupe možemo reći da spremnik ne bi trebao trošiti više od određene količine resursa.

Da bi kontejnerizacija radila u potpunosti, koriste se dodatne tehnologije: Capabilities, Copy-on-write i druge.

Sposobnosti su kada procesu kažemo što može, a što ne može učiniti. Na razini jezgre, to su jednostavno bitmape s mnogo parametara. Na primjer, root korisnik ima pune privilegije i može sve. Poslužitelj vremena može promijeniti vrijeme sustava: ima mogućnosti na Time Capsule, i to je to. Koristeći privilegije, možete fleksibilno konfigurirati ograničenja za procese i time se zaštititi.

Sustav Copy-on-write omogućuje nam rad s Docker slikama i njihovo učinkovitije korištenje.

Docker trenutačno ima problema s kompatibilnošću s Cgroups v2, pa se ovaj članak fokusira posebno na Cgroups v1.

No, vratimo se povijesti.

Kada su se virtualizacijski sustavi pojavili na razini jezgre, počeli su se aktivno koristiti. Zaglavlje na hipervizoru je nestalo, ali su neki problemi ostali:

  • velike slike: u isti OpenVZ guraju operativni sustav, biblioteke, hrpu različitog softvera, a slika na kraju ipak ispadne prilično velika;
  • Nema normalnog standarda za pakiranje i dostavu, tako da ostaje problem ovisnosti. Postoje situacije kada dva dijela koda koriste istu biblioteku, ali s različitim verzijama. Među njima može doći do sukoba.

Za rješavanje svih ovih problema došlo je sljedeće doba.

Era kontejnera

Kada je stigla era kontejnera, promijenila se filozofija rada s njima:

  • Jedan proces - jedan spremnik.
  • Isporučujemo sve ovisnosti koje proces treba u njegov spremnik. To zahtijeva rezanje monolita u mikroservise.
  • Što je manja slika, to bolje - ima manje mogućih ranjivosti, brže se pojavljuje i tako dalje.
  • Slučajevi postaju efemerni.

Sjećate se što sam rekao o kućnim ljubimcima protiv stoke? Prije su primjerci bili poput domaćih životinja, ali sada su postali poput stoke. Prije je postojao monolit - jedna aplikacija. Sada je to 100 mikroservisa, 100 spremnika. Neki spremnici mogu imati 2-3 replike. Postaje nam manje važno kontrolirati svaki kontejner. Ono što nam je važnije je dostupnost same usluge: što ovaj skup spremnika radi. To mijenja pristupe praćenju.

U 2014-2015, Docker je procvjetao - tehnologija o kojoj ćemo sada govoriti.

Docker je promijenio filozofiju i standardizirao pakiranje aplikacije. Koristeći Docker, možemo zapakirati aplikaciju, poslati je u repozitorij, preuzeti je odande i implementirati.

Sve što nam treba stavljamo u Docker spremnik, tako da je problem ovisnosti riješen. Docker jamči ponovljivost. Mislim da su se mnogi ljudi susreli s neponovljivošću: sve vam radi, gurnete u proizvodnju, a tamo prestane raditi. S Dockerom ovaj problem nestaje. Ako se vaš Docker spremnik pokrene i radi ono što treba, tada će se s velikim stupnjem vjerojatnosti pokrenuti u proizvodnji i tamo učiniti isto.

Digresija o režijskim troškovima

Oko režija uvijek postoje sporovi. Neki ljudi vjeruju da Docker ne nosi dodatno opterećenje, budući da koristi Linux kernel i sve njegove procese potrebne za kontejnerizaciju. Kao, "ako kažete da je Docker prevelik, onda je Linux kernel prevelik."

S druge strane, ako uđete dublje, doista postoji nekoliko stvari u Dockeru za koje se, uz natezanje, može reći da su prevelike.

Prvi je PID imenski prostor. Kada proces smjestimo u imenski prostor, dodjeljuje mu se PID 1. U isto vrijeme, ovaj proces ima još jedan PID, koji se nalazi na glavnom imenskom prostoru, izvan spremnika. Na primjer, pokrenuli smo Nginx u spremniku, postao je PID 1 (glavni proces). A na hostu ima PID 12623. I teško je reći koliki je to režijski trošak.

Druga stvar su C grupe. Uzmimo Cgroups po memoriji, odnosno mogućnosti ograničavanja memorije spremnika. Kada je omogućeno, aktiviraju se brojači i obračun memorije: kernel treba razumjeti koliko je stranica dodijeljeno i koliko ih je još slobodno za ovaj spremnik. To je možda dodatni trošak, ali nisam vidio nikakve precizne studije o tome kako to utječe na performanse. I osobno nisam primijetio da je aplikacija pokrenuta u Dockeru odjednom doživjela nagli gubitak performansi.

I još jedna napomena o performansama. Neki parametri kernela prosljeđuju se s glavnog računala na spremnik. Konkretno, neki mrežni parametri. Stoga, ako želite pokrenuti nešto visokih performansi u Dockeru, na primjer, nešto što će aktivno koristiti mrežu, tada morate barem prilagoditi ove parametre. Neki nf_conntrack, na primjer.

O Docker konceptu

Docker se sastoji od nekoliko komponenti:

  1. Docker Daemon je isti Container Engine; lansira kontejnere.
  2. Docker CII je uslužni program za upravljanje Dockerom.
  3. Dockerfile - upute za izradu slike.
  4. Slika — slika iz koje se kotrlja spremnik.
  5. Spremnik.
  6. Docker registar je spremište slika.

Shematski to izgleda otprilike ovako:

Što je Docker: kratki izlet u povijest i osnovne apstrakcije

Docker demon radi na Docker_hostu i pokreće spremnike. Postoji klijent koji šalje naredbe: izgraditi sliku, preuzeti sliku, pokrenuti spremnik. Docker demon odlazi u registar i izvršava ih. Docker klijent može pristupiti i lokalno (na Unix utičnicu) i putem TCP-a s udaljenog glavnog računala.

Prođimo kroz svaku komponentu.

Docker demon - ovo je poslužiteljski dio, radi na glavnom računalu: preuzima slike i pokreće spremnike iz njih, stvara mrežu između spremnika, prikuplja zapise. Kad kažemo "stvori sliku", demon to također radi.

Docker CLI — Docker klijentski dio, konzolni uslužni program za rad s demonom. Ponavljam, može raditi ne samo lokalno, već i preko mreže.

Osnovne naredbe:

docker ps - prikaži spremnike koji se trenutno izvode na Docker hostu.
docker slike - prikaži slike preuzete lokalno.
docker search <> - traženje slike u registru.
docker pull <> - preuzmite sliku iz registra na stroj.
docker build < > - prikupi sliku.
docker run <> - pokretanje spremnika.
docker rm <> - uklonite spremnik.
docker dnevnici <> - dnevnici kontejnera
docker start/stop/restart <> - rad sa spremnikom

Ako svladate ove naredbe i sigurni ste u njihovom korištenju, smatrajte se 70% vještim u Dockeru na korisničkoj razini.

dockerfile - upute za izradu slike. Gotovo svaka naredba s uputama je novi sloj. Pogledajmo primjer.

Što je Docker: kratki izlet u povijest i osnovne apstrakcije

Ovako izgleda Dockerfile: naredbe lijevo, argumenti desno. Svaka naredba koja je ovdje (i općenito napisana u Dockerfileu) stvara novi sloj u Image.

Čak i gledajući lijevu stranu, možete otprilike shvatiti što se događa. Kažemo: "napravite mapu za nas" - ovo je jedan sloj. "Učini mapu radnom" je drugi sloj, i tako dalje. Torta u slojevima olakšava život. Ako kreiram drugu Dockerfile i promijenim nešto u zadnjem retku - pokrenem nešto osim "python" "main.py" ili instaliram ovisnosti iz druge datoteke - tada će se prethodni slojevi ponovno koristiti kao predmemorija.

Slika - ovo je kontejnerska ambalaža; kontejneri se lansiraju sa slike. Ako pogledamo Docker sa stajališta upravitelja paketima (kao da radimo s deb ili rpm paketima), tada je image u biti rpm paket. Kroz yum install možemo instalirati aplikaciju, izbrisati je, pronaći u repozitoriju i preuzeti. Ovdje je otprilike isto: spremnici se pokreću iz slike, pohranjuju se u Docker registar (slično yum-u, u repozitoriju), a svaka slika ima SHA-256 hash, ime i oznaku.

Slika je izgrađena prema uputama iz Dockerfilea. Svaka instrukcija iz Dockerfilea stvara novi sloj. Slojevi se mogu ponovno koristiti.

Docker registar je Docker spremište slika. Slično OS-u, Docker ima javni standardni registar - dockerhub. Ali možete izgraditi vlastito spremište, vlastiti Docker registar.

Kontejner - što se pokreće sa slike. Napravili smo sliku prema uputama iz Dockerfilea, a zatim je pokrećemo iz ove slike. Ovaj spremnik je izoliran od ostalih spremnika i mora sadržavati sve što je potrebno za rad aplikacije. U ovom slučaju, jedan spremnik - jedan proces. Dogodi se da morate napraviti dva procesa, ali to je donekle suprotno Docker ideologiji.

Zahtjev "jedan spremnik, jedan proces" povezan je s PID imenskim prostorom. Kada se proces s PID-om 1 pokrene u prostoru imena, ako iznenada umre, umire i cijeli spremnik. Ako se tamo izvode dva procesa: jedan je živ, a drugi mrtav, spremnik će i dalje živjeti. Ali ovo je pitanje najboljih praksi, o njima ćemo govoriti u drugim materijalima.

Da biste detaljnije proučili značajke i cijeli program tečaja, slijedite poveznicu: “Docker video tečaj".

Autor: Marcel Ibraev, certificirani Kubernetes administrator, inženjer u praksi u Southbridgeu, govornik i programer Slurm tečajeva.

Izvor: www.habr.com

Dodajte komentar