Uvod za kontejnere, VM-ove i Docker-u prilagođen početnicima

Ako ste programer ili tehničar, velika je vjerojatnost da ste barem čuli za Docker: koristan alat za pakiranje, otpremu i pokretanje aplikacija u "spremnicima". Bilo bi teško ne, uz svu pažnju koju danas dobivaju - od strane programera i administratora sustava. Čak i veliki psi poput Googlea, VMware-a i Amazona grade usluge koje ga podržavaju.

Bez obzira na to imate li na umu trenutni slučaj upotrebe Dockera, i dalje mislim da je važno razumjeti neke temeljne koncepte oko toga što je "spremnik" i kako se uspoređuje s virtualnim strojem (VM). Iako je Internet prepun izvrsnih vodiča za uporabu Dockera, nisam uspio pronaći mnogo konceptualnih vodiča prilagođenih početnicima, posebno o tome od čega se sastoji spremnik. Dakle, nadam se da će ovaj post riješiti taj problem :)

Počnimo s razumijevanjem što su uopće VM-ovi i spremnici.

Što su "spremnici" i "VM-ovi"?

Spremnici i VM slični su u svojim ciljevima: izolirati aplikaciju i njezine ovisnosti u samostalnu jedinicu koja se može izvoditi bilo gdje.

Štoviše, spremnici i VM-ovi uklanjaju potrebu za fizičkim hardverom, omogućavajući učinkovitiju upotrebu računalnih resursa, kako u pogledu potrošnje energije tako i isplativosti.

Glavna razlika između spremnika i VM-a je u njihovom arhitektonskom pristupu. Pogledajmo izbliza.

Virtualni strojevi

VM je u osnovi emulacija stvarnog računala koje izvršava programe poput stvarnog računala. VM-ovi se izvode na vrhu fizičkog stroja pomoću "hipervizora" . Hipervizor, pak, radi ili na glavnom računalu ili na "golom metalu" .

Otpakirajmo žargon:

Hipervizoru je komad softvera, firmware, ili hardvera koji virtualna izvoditi na vrhu. Sami hipervizori rade na fizičkim računalima, koji se nazivaju "glavnim računalom" . Stroj domaćin pruža VM-ima resurse, uključujući RAM i CPU. Ti se resursi dijele između VM-ova i mogu se distribuirati kako smatrate potrebnim. Dakle, ako jedan VM izvodi zahtjevniju aplikaciju, možda ćete njemu dodijeliti više resursa od ostalih VM-a koji se izvode na istom računalu.

VM koji se izvodi na glavnom računalu (opet, koristeći hipervizor) također se često naziva "gostinjski stroj". Ovaj stroj za goste sadrži i aplikaciju i sve što je potrebno za pokretanje te aplikacije (npr. Sistemske binarne datoteke i knjižnice). Također sadrži cijeli vlastiti virtualizirani hardverski stog, uključujući virtualizirane mrežne adaptere, pohranu i CPU - što znači da ima i svoj punopravni gostujući operativni sustav. Iznutra se gost mašina ponaša kao vlastita jedinica s vlastitim namjenskim resursima. Izvana znamo da se radi o resursima za razmjenu VM-a koje pruža host stroj.

Kao što je gore spomenuto, gost mašina može raditi na hostiranom hipervizoru ili hipervizoru bez gola metala . Između njih postoje neke važne razlike.

Prvo, hostirani hipervizor za virtualizaciju radi na operativnom sustavu glavnog računala. Na primjer, računalo sa OSX-om može imati VM (npr. VirtualBox ili VMware Workstation 8) instaliran na vrhu tog OS-a. VM nema izravan pristup hardveru, pa mora proći kroz operativni sustav domaćina (u našem slučaju, Macov OSX).

Prednost hostiranog hipervizora je u tome što je temeljni hardver manje važan. Operativni sustav hosta odgovoran je za upravljačke programe hardvera umjesto samog hipervizora i stoga se smatra da ima više "hardverske kompatibilnosti". S druge strane, ovaj dodatni sloj između hardvera i hipervizora stvara više dodatnih resursa, što smanjuje performanse VM-a.

Okruženje hipervizora bez metala rješava problem performansi instaliranjem i pokretanjem hardvera glavnog računala. Budući da se izravno sučeljava s osnovnim hardverom, ne treba mu operativni sustav domaćin za pokretanje. U ovom slučaju, prva stvar instalirana na poslužitelju računala glavnog računala kao operativni sustav bit će hipervizor. Za razliku od hostiranog hipervizora, goli metalni hipervizor ima vlastite upravljačke programe i izravno komunicira sa svakom komponentom za bilo koji I / O, obradu ili zadatke specifične za OS. To rezultira boljim performansama, skalabilnošću i stabilnošću. Kompromis je ovdje što je hardverska kompatibilnost ograničena jer hipervizor može imati ugrađeno samo toliko upravljačkih programa uređaja.

Nakon svih ovih razgovora o hipervizorima, možda se pitate zašto nam uopće treba ovaj dodatni sloj "hipervizora" između VM-a i računala domaćina.

Pa, budući da VM ima vlastiti virtualni operativni sustav, hipervizor igra ključnu ulogu u pružanju VM-ovima platforme za upravljanje i izvršavanje ovog gostujućeg operativnog sustava. Omogućuje računalima domaćinima da podijele svoje resurse među virtualnim strojevima koji se izvode kao gosti na njima.

Kao što možete vidjeti na dijagramu, VM-ovi pakiraju virtualni hardver, jezgru (tj. OS) i korisnički prostor za svaki novi VM.

Spremnik

Za razliku od VM-a koji pruža hardversku virtualizaciju, spremnik pruža virtualizaciju na razini operativnog sustava apstrahirajući "korisnički prostor". Vidjet ćete na što mislim kad raspakiramo pojam spremnik .

Za sve namjere i svrhe, spremnici izgledaju poput VM-a. Na primjer, imaju privatni prostor za obradu, mogu izvršavati naredbe kao root, imaju privatno mrežno sučelje i IP adresu, dopuštaju prilagođene rute i iptable pravila, mogu montirati datotečne sustave itd.

Jedna velika razlika između spremnika i VM-a je ta što spremnici * dijele * jezgru host sustava s ostalim spremnicima.

Ovaj dijagram pokazuje da spremnici spakiraju samo korisnički prostor, a ne jezgru ili virtualni hardver kao što to čini VM. Svaki spremnik dobiva svoj izolirani korisnički prostor kako bi omogućio rad više spremnika na jednom računalu s računalom. Vidimo da se sva arhitektura na razini operativnog sustava dijeli između spremnika. Jedini dijelovi koji su stvoreni od nule su kante i pregrade. To je ono što čini spremnike tako laganima.

Gdje dolazi Docker?

Docker je projekt otvorenog koda zasnovan na Linux spremnicima. Koristi značajke Linux kernela poput prostora imena i kontrolnih grupa za stvaranje spremnika na vrhu operativnog sustava.

Kontejneri su daleko od novih; Google već godinama koristi vlastitu tehnologiju kontejnera. Druge tehnologije kontejnera za Linux uključuju Solaris Zones, BSD zatvor i LXC, koji postoje već dugi niz godina.

Pa zašto Docker odjednom dobiva naglo?

1. Jednostavnost upotrebe: Docker je mnogo olakšao svima - programerima, administratorima sustava, arhitektima i drugima - da iskoriste kontejnere kako bi brzo izradili i testirali prijenosne aplikacije. Omogućuje svima da zapakiraju aplikaciju na svoj laptop, koja zauzvrat može raditi nepromijenjena na bilo kojem javnom oblaku, privatnom oblaku ili čak golom metalu. Mantra glasi: "jednom izgradi, trči bilo gdje."

2. Brzina: Docker spremnici vrlo su lagani i brzi. Budući da su spremnici samo zaštićena okruženja koja rade na jezgri, oni zauzimaju manje resursa. Možete stvoriti i pokrenuti Docker spremnik za nekoliko sekundi, u usporedbi s VM-ovima koji bi mogli potrajati duže jer svaki put moraju pokrenuti puni virtualni operativni sustav.

3. Docker Hub: Korisnici Dockera također imaju koristi od sve bogatijeg ekosustava Docker Hub-a, za koji možete smatrati da je „trgovina aplikacija za Dockerove slike“. Docker Hub ima desetke tisuća javnih slika koje je stvorila zajednica i koje su lako dostupne za upotrebu. Nevjerojatno je jednostavno tražiti slike koje odgovaraju vašim potrebama, spremne za povlačenje i upotrebu s malo ili nimalo modifikacija.

4. Modularnost i skalabilnost: Docker olakšava razbijanje funkcionalnosti vaše aplikacije u pojedinačne spremnike. Na primjer, baza podataka Postgres možda se izvodi u jednom spremniku, a poslužitelj Redis u drugom, dok je aplikacija Node.js u drugom. Uz Docker postalo je lakše povezati ove spremnike kako biste stvorili svoju aplikaciju, što olakšava skaliranje ili samostalno ažuriranje komponenata u budućnosti.

I posljednje, ali ne najmanje važno, tko ne voli kita Dockera? ;)

Temeljni koncepti Dockera

Sad kad smo dobili veliku sliku, prođimo temeljne dijelove Dockera dio po dio:

Docker motor

Docker engine je sloj na kojem radi Docker. To je lagano vrijeme izvođenja i alat koji upravlja spremnicima, slikama, gradnjama i mnogim drugim. Izvorno radi na Linux sustavima i čine ga:

1. Docker Daemon koji se pokreće u glavnom računalu.

2. Klijent Dockera koji zatim komunicira s Docker demonom za izvršavanje naredbi.

3. REST API za daljinsku interakciju s Docker Daemonom.

Docker klijent

Docker klijent je ono s čime vi, kao krajnji korisnik Dockera, komunicirate. Shvatite to kao korisničko sučelje za Docker. Na primjer, kad to učinite ...

komunicirate s klijentom Dockera, koji zatim vaše upute prenosi Docker Daemonu.

Docker Daemon

Docker demon je ono što zapravo izvršava naredbe poslane klijentu Docker - poput izrade, pokretanja i distribucije vaših spremnika. Docker Daemon radi na glavnom računalu, ali kao korisnik nikada ne komunicirate izravno s Daemonom. Klijent Dockera može se izvoditi i na glavnom računalu, ali to nije potrebno. Može se pokretati na drugom stroju i komunicirati s Docker Daemonom koji se izvodi na glavnom računalu.

Dockerfile

Dockerfile je mjesto na kojem pišete upute za izgradnju Dockerove slike. Ove upute mogu biti:

  • POKRENI apt-get y install some-package : za instaliranje softverskog paketa
  • EXPOSE 8000: za izlaganje luke
  • ENV ANT_HOME / usr / local / apache-ant za prosljeđivanje varijable okruženja

i tako dalje. Nakon što ste dobili svoj Dockerfile postaviti, možete koristiti lučki radnik graditi naredbu izgraditi sliku od njega. Evo primjera datoteke Docker:

Docker slika

Slike su predlošci samo za čitanje koje izrađujete iz niza uputa napisanih u vašem Dockerfileu. Slike definiraju kako želite da vaša zapakirana aplikacija izgleda i ovisnosti * i * koji će se procesi pokretati kad se pokrene.

Slika Dockera izrađuje se pomoću Docker datoteke. Svaka uputa u Dockerfileu dodaje novi "sloj" na sliku, s slojevima koji predstavljaju dio datotečnog sustava slika koji dodaje ili zamjenjuje sloj ispod njega. Slojevi su ključni za Dockerovu laganu, ali snažnu strukturu. Docker koristi Union File System da bi to postigao:

Union datotečni sustavi

Docker koristi Union File Systems za izgradnju slike. O datotečnom sustavu Union možete razmišljati kao o datotečnom sustavu koji se može složiti, što znači da se datoteke i direktorije zasebnih datotečnih sustava (poznatih kao grane) mogu transparentno preklopiti u jedan datotečni sustav.

Sadržaj direktorija koji imaju isti put unutar prekrivenih grana vidi se kao jedan spojeni direktorij, što izbjegava potrebu za stvaranjem zasebnih kopija svakog sloja. Umjesto toga, svi oni mogu dobiti pokazivače na isti resurs; kada je potrebno izmijeniti određene slojeve, stvorit će kopiju i izmijeniti lokalnu kopiju, a izvornik će ostati nepromijenjen. Tako se sustavi datoteka mogu * činiti * zapisivima, a da zapravo ne dopuštaju upisivanje. (Drugim riječima, sustav "copy-on-write".)

Slojeviti sustavi nude dvije glavne prednosti:

1. Bez umnožavanja: slojevi pomažu u izbjegavanju dupliciranja cijelog skupa datoteka svaki put kada koristite sliku za izradu i pokretanje novog spremnika, čineći instanciju spremnika dockera vrlo brzim i jeftinim.

2. Razdvajanje slojeva: Izmjena je mnogo brža - kada promijenite sliku, Docker širi ažuriranja samo na sloj koji je promijenjen.

Svezaka

Volumeni su dio podataka spremnika koji se pokreće prilikom stvaranja spremnika. Svesci vam omogućuju postojanje i dijeljenje podataka spremnika. Količine podataka odvojene su od zadanog datotečnog sustava Union i postoje kao uobičajeni direktoriji i datoteke na datotečnom sustavu hosta. Dakle, čak i ako uništite, ažurirate ili obnovite svoj spremnik, količine podataka ostat će netaknute. Kada želite ažurirati volumen, izravno ga mijenjate. (Kao dodatni bonus, količine podataka mogu se dijeliti i ponovno koristiti među više spremnika, što je prilično uredno.)

Docker kontejneri

Docker spremnik, kao što je gore spomenuto, omotava program aplikacije u nevidljivi okvir sa svime što aplikacija treba za pokretanje. To uključuje operativni sustav, aplikacijski kôd, vrijeme izvođenja, sistemske alate, sistemske knjižnice itd. Dockerovi spremnici izgrađeni su od Dockerovih slika. Budući da su slike samo za čitanje, Docker dodaje datotečni sustav za čitanje i pisanje preko datotečnog sustava samo za čitanje slike da bi stvorio spremnik.

Štoviše, tada, stvarajući spremnik, Docker stvara mrežno sučelje tako da spremnik može razgovarati s lokalnim domaćinom, priložiti dostupnu IP adresu spremniku i izvršiti postupak koji ste naveli za pokretanje vaše aplikacije prilikom definiranja slike.

Nakon što uspješno izradite spremnik, možete ga pokrenuti u bilo kojem okruženju bez potrebe za promjenama.

Dvoklik na "spremnike"

Fuj! To je puno pokretnih dijelova. Mene je uvijek zanimalo kako se kontejner zapravo implementira, pogotovo jer oko kontejnera ne postoji nikakva apstraktna granica infrastrukture. Nakon puno čitanja, sve to ima smisla, pa evo i mog pokušaja da vam to objasnim! :)

Pojam "spremnik" zapravo je samo apstraktni koncept koji opisuje kako nekoliko različitih značajki djeluje zajedno kako bi se vizualiziralo "spremnik". Krenimo kroz njih vrlo brzo:

1) Prostori imena

Prostori imena pružaju spremnicima vlastiti pogled na osnovni Linux sustav, ograničavajući ono što spremnik može vidjeti i pristupiti. Kada pokrenete spremnik, Docker stvara prostore imena koje će koristiti određeni spremnik.

Postoji nekoliko različitih vrsta prostora imena u jezgri koje Docker koristi, na primjer:

a. NET: Pruža spremnik s vlastitim prikazom mrežnog snopa sustava (npr. Vlastite mrežne uređaje, IP adrese, IP tablice usmjeravanja, / proc / net direktorij, brojevi priključaka itd.).

b. PID: PID je skraćenica za ID procesa. Ako ste ikada pokrenuli ps aux u naredbenom retku kako biste provjerili koji se procesi izvode na vašem sustavu, vidjet ćete stupac s nazivom "PID". Prostor imena PID kontejnerima daje vlastiti opsežni prikaz procesa koje mogu pregledavati i s kojima mogu komunicirati, uključujući neovisnu init (PID 1), koja je "predak svih procesa".

c. MNT: Spremniku daje vlastiti prikaz "nosača" na sustavu. Dakle, procesi u različitim imenskim prostorima montiranja imaju različite poglede na hijerarhiju datotečnog sustava.

d. UTS: UTS je skraćenica od UNIX Timesharing System. Omogućuje procesu identificiranje identifikatora sustava (tj. Ime hosta, ime domene itd.). UTS omogućuje spremnicima da imaju vlastito ime hosta i ime NIS domene koje je neovisno o drugim spremnicima i sustavu domaćina.

e. IPC: IPC je kratica za InterProcess Communication. IPC prostor imena odgovoran je za izolaciju IPC resursa između procesa koji se izvode u svakom spremniku.

f. KORISNIK: Ovaj prostor imena koristi se za izoliranje korisnika unutar svakog spremnika. Funkcionira dopuštajući spremnicima da imaju drugačiji prikaz raspona uid (korisnički ID) i gid (ID grupe) u usporedbi s glavnim sustavom. Kao rezultat toga, uid i gid procesa mogu se razlikovati unutar i izvan korisničkog prostora imena, što također omogućuje da proces ima neprivilegiranog korisnika izvan spremnika bez žrtvovanja root privilegija unutar spremnika.

Docker koristi ove prostore imena zajedno kako bi izolirao i započeo stvaranje kontejnera. Sljedeća značajka naziva se kontrolne skupine.

2) Kontrolne skupine

Kontrolne grupe (također nazvane cgroups) je značajka Linux jezgre koja izolira, određuje prioritete i obračunava upotrebu resursa (CPU, memorija, I / O diska, mreža itd.) Skupa procesa. U tom smislu, cgroup osigurava da Docker-ovi spremnici koriste samo resurse koji su im potrebni - i, ako je potrebno, postavljaju ograničenja koja resursi * spremnik * može koristiti. Skupine također osiguravaju da jedan spremnik ne iscrpi jedan od tih resursa i ne sruši cijeli sustav.

Na kraju, unija datotečnih sustava je još jedna značajka koju Docker koristi:

3) Izolirani datotečni sustav Unije:

Opisana gore u odjeljku Docker Images :)

To je doista sve što postoji u Dockerovom spremniku (naravno, vrag je u detaljima implementacije - poput načina upravljanja interakcijama između različitih komponenata).

Budućnost Dockera: Docker i VM-ovi će postojati istovremeno

Iako Docker zasigurno dobiva puno para, ne vjerujem da će to postati stvarna prijetnja VM-ovima. Spremnici će i dalje dobivati ​​na terenu, ali postoje mnogi slučajevi upotrebe u kojima su VM-ovi još uvijek prikladniji.

Na primjer, ako trebate pokrenuti više aplikacija na više poslužitelja, vjerojatno ima smisla koristiti VM-ove. S druge strane, ako trebate pokrenuti mnogo * kopija * jedne aplikacije, Docker nudi neke uvjerljive prednosti.

Štoviše, iako vam spremnici omogućuju da svoju aplikaciju razbijete na funkcionalnije diskretne dijelove kako biste stvorili razdvajanje problema, to također znači da postoji sve veći broj dijelova kojima se može upravljati, a koji mogu postati nezgrapni.

Sigurnost je također zabrinuta za Dockerove spremnike - budući da spremnici dijele isto jezgro, prepreka između spremnika je tanja. Iako puni VM može upućivati ​​hiperpozive samo hipervizoru domaćina, Docker spremnik može vršiti syscallove jezgru domaćina, što stvara veću površinu za napad. Kada je sigurnost posebno važna, programeri će vjerojatno odabrati VM-ove koji su izolirani apstrahiranim hardverom - što otežava međusobno ometanje.

Naravno, pitanja poput sigurnosti i upravljanja sigurno će se razvijati kako spremnici postaju sve izloženiji u proizvodnji i daljnji nadzor korisnika. Za sada je debata o kontejnerima protiv VM-a zaista najbolja za one koji svakodnevno žive i dišu ih!

Zaključak

Nadam se da ste sada opremljeni znanjem koje vam treba da biste saznali više o Dockeru i možda ga čak jednog dana iskoristili u projektu.

Kao i uvijek, javite mi redak u komentarima ako sam pogriješio ili vam u svakom slučaju mogu biti od pomoći! :)