Co je Docker: stručný exkurz do historie a základní abstrakce

Začalo 10. srpna ve Slurmu Docker video kurz, ve kterém jej kompletně rozebereme – od základních abstrakcí až po síťové parametry.

V tomto článku budeme hovořit o historii Dockeru a jeho hlavních abstrakcích: Image, Cli, Dockerfile. Přednáška je určena pro začátečníky, takže zkušené uživatele pravděpodobně nebude zajímat. Nebude tam žádná krev, slepé střevo ani hluboké ponoření. Úplně základy.

Co je Docker: stručný exkurz do historie a základní abstrakce

Co je Docker

Podívejme se na definici Dockeru z Wikipedie.

Docker je software pro automatizaci nasazení a správy aplikací v kontejnerových prostředích.

Z této definice není nic jasné. Zvláště není jasné, co znamená „v prostředích, která podporují kontejnerizaci“. Abychom to zjistili, vraťme se v čase. Začněme érou, kterou běžně nazývám „monolitická éra“.

Monolitická éra

Monolitická éra je počátek 2000. století, kdy byly všechny aplikace monolitické s hromadou závislostí. Vývoj trval dlouho. Přitom serverů nebylo mnoho, všichni jsme je znali jménem a sledovali je. Existuje takové vtipné srovnání:

Domácí mazlíčci jsou domácí zvířata. V době monolitu jsme se k našim serverům chovali jako k domácím mazlíčkům, udržovali je a hýčkali a odfukovali smínka prachu. A pro lepší správu zdrojů jsme použili virtualizaci: vzali jsme server a rozřezali ho na několik virtuálních strojů, čímž jsme zajistili izolaci prostředí.

Virtualizační systémy založené na hypervizoru

Každý asi slyšel o virtualizačních systémech: VMware, VirtualBox, Hyper-V, Qemu KVM atd. Poskytují izolaci aplikací a správu zdrojů, ale mají i nevýhody. K virtualizaci potřebujete hypervizor. A hypervizor je režie zdrojů. A samotný virtuální stroj je většinou celý kolos – těžký obraz obsahující operační systém, Nginx, Apache a možná i MySQL. Obraz je velký a provoz virtuálního stroje je nepohodlný. V důsledku toho může být práce s virtuálními stroji pomalá. K vyřešení tohoto problému byly na úrovni jádra vytvořeny virtualizační systémy.

Virtualizační systémy na úrovni jádra

Virtualizace na úrovni jádra je podporována systémy OpenVZ, Systemd-nspawn, LXC. Pozoruhodným příkladem takové virtualizace je LXC (Linux Containers).

LXC je virtualizační systém na úrovni operačního systému pro spouštění více izolovaných instancí operačního systému Linux na jednom uzlu. LXC nepoužívá virtuální stroje, ale vytváří virtuální prostředí s vlastním procesním prostorem a síťovým zásobníkem.

LXC v podstatě vytváří kontejnery. Jaký je rozdíl mezi virtuálními stroji a kontejnery?

Co je Docker: stručný exkurz do historie a základní abstrakce

Kontejner není vhodný pro izolaci procesů: ve virtualizačních systémech na úrovni jádra se nacházejí zranitelnosti, které jim umožňují uniknout z kontejneru k hostiteli. Pokud tedy potřebujete něco izolovat, je lepší použít virtuální stroj.

Rozdíly mezi virtualizací a kontejnerizací jsou vidět na diagramu.
Existují hardwarové hypervizory, hypervizory nad operačním systémem a kontejnery.

Co je Docker: stručný exkurz do historie a základní abstrakce

Hardwarové hypervizory jsou skvělé, pokud opravdu chcete něco izolovat. Protože je možné izolovat na úrovni paměťových stránek a procesorů.

Existují hypervizory jako program a existují kontejnery a o nich budeme hovořit dále. Kontejnerizační systémy nemají hypervizor, ale existuje kontejnerový engine, který vytváří a spravuje kontejnery. Tato věc je lehčí, takže díky práci s jádrem je méně režie nebo vůbec žádná.

Co se používá pro kontejnerizaci na úrovni jádra

Hlavní technologie, které umožňují vytvořit kontejner izolovaný od ostatních procesů, jsou jmenné prostory a řídicí skupiny.

Jmenné prostory: PID, Networking, Mount a User. Je jich více, ale pro snazší pochopení se zaměříme na tyto.

PID Namespace omezuje procesy. Když například vytvoříme jmenný prostor PID a umístíme tam proces, stane se s PID 1. Obvykle je v systémech PID 1 systemd nebo init. V souladu s tím, když umístíme proces do nového jmenného prostoru, obdrží také PID 1.

Networking Namespace vám umožňuje omezit/izolovat síť a umístit do ní svá vlastní rozhraní. Připojení je omezení systému souborů. Uživatel – omezení pro uživatele.

Kontrolní skupiny: Paměť, CPU, IOPS, Síť – celkem asi 12 nastavení. Jinak se také nazývají Cskupiny (“C-skupiny”).

Řídicí skupiny spravují prostředky pro kontejner. Prostřednictvím Control Groups můžeme říci, že kontejner by neměl spotřebovávat více než určité množství zdrojů.

Aby kontejnerizace fungovala naplno, používají se další technologie: Capabilities, Copy-on-write a další.

Schopnosti jsou, když říkáme procesu, co může a co nemůže dělat. Na úrovni jádra jsou to jednoduše bitmapy s mnoha parametry. Například uživatel root má plná oprávnění a může dělat vše. Časový server může změnit systémový čas: má funkce na Time Capsule, a to je vše. Pomocí oprávnění můžete flexibilně konfigurovat omezení pro procesy, a tím se chránit.

Systém Copy-on-write nám umožňuje pracovat s obrazy Dockeru a využívat je efektivněji.

Docker má v současnosti problémy s kompatibilitou s Cgroups v2, takže tento článek se zaměřuje konkrétně na Cgroups v1.

Ale vraťme se do historie.

Když se virtualizační systémy objevily na úrovni jádra, začaly se aktivně používat. Režie hypervizoru zmizela, ale některé problémy zůstaly:

  • velké obrázky: do stejného OpenVZ natlačí operační systém, knihovny, hromadu různého softwaru a nakonec se obrázek stejně ukáže jako docela velký;
  • Neexistuje žádný normální standard pro balení a doručení, takže problém závislostí zůstává. Existují situace, kdy dva kusy kódu používají stejnou knihovnu, ale s různými verzemi. Může mezi nimi dojít ke konfliktu.

K vyřešení všech těchto problémů nastala další éra.

Kontejnerová éra

Když přišla éra kontejnerů, změnila se filozofie práce s nimi:

  • Jeden proces – jeden kontejner.
  • Všechny závislosti, které proces potřebuje, dodáváme do svého kontejneru. To vyžaduje řezání monolitů na mikroslužby.
  • Čím menší obrázek, tím lépe – je zde méně možných zranitelností, rychleji se rozbaluje a podobně.
  • Případy se stávají pomíjivými.

Pamatujete si, co jsem řekl o domácích zvířatech vs. Dříve byly případy jako domácí zvířata, ale nyní se staly jako dobytek. Dříve existoval monolit - jedna aplikace. Nyní je to 100 mikroslužeb, 100 kontejnerů. Některé kontejnery mohou mít 2-3 repliky. Stává se pro nás méně důležité kontrolovat každý kontejner. Důležitější je pro nás dostupnost samotné služby: co tato sada kontejnerů dělá. To mění přístupy k monitorování.

V letech 2014-2015 Docker vzkvétal – technologie, o které si nyní povíme.

Docker změnil filozofii a standardizoval balení aplikací. Pomocí Dockeru můžeme zabalit aplikaci, odeslat ji do úložiště, odtud stáhnout a nasadit.

Vše, co potřebujeme, vložíme do kontejneru Docker, takže problém se závislostí je vyřešen. Docker zaručuje reprodukovatelnost. Myslím, že mnoho lidí se setkalo s nereprodukovatelností: všechno vám funguje, dotlačíte to do výroby a tam to přestane fungovat. S Dockerem tento problém zmizí. Pokud se váš kontejner Docker spustí a udělá to, co potřebuje, pak s vysokou mírou pravděpodobnosti začne ve výrobě a tam udělá to samé.

Odbočka o režii

O režijních nákladech se neustále diskutuje. Někteří lidé se domnívají, že Docker nenese žádnou další zátěž, protože používá jádro Linuxu a všechny jeho procesy nezbytné pro kontejnerizaci. Například: "Pokud říkáte, že Docker je nad hlavou, pak je nad hlavou linuxové jádro."

Na druhou stranu, pokud půjdete hlouběji, v Dockeru je skutečně několik věcí, o kterých se dá říci, že jsou nad hlavou.

První je jmenný prostor PID. Když umístíme proces do jmenného prostoru, je mu přiřazeno PID 1. Zároveň má tento proces další PID, který se nachází na jmenném prostoru hostitele, mimo kontejner. Například jsme spustili Nginx v kontejneru, stal se z něj PID 1 (hlavní proces). A na hostiteli má PID 12623. A těžko říct, jak moc je to režie.

Druhá věc jsou Cgroups. Vezměme Cgroups podle paměti, tedy schopnosti omezit paměť kontejneru. Když je povolena, aktivují se čítače a účtování paměti: jádro musí pochopit, kolik stránek bylo alokováno a kolik je ještě volných pro tento kontejner. To je možná režie, ale neviděl jsem žádné přesné studie o tom, jak to ovlivňuje výkon. A sám jsem si nevšiml, že by aplikace běžící v Dockeru najednou zaznamenala prudký pokles výkonu.

A ještě jedna poznámka k výkonu. Některé parametry jádra jsou předány z hostitele do kontejneru. Zejména některé síťové parametry. Pokud tedy chcete v Dockeru provozovat něco výkonného, ​​například něco, co bude aktivně využívat síť, tak je potřeba alespoň upravit tyto parametry. Například nějaký nf_conntrack.

O konceptu Docker

Docker se skládá z několika komponent:

  1. Docker Daemon je stejný kontejnerový engine; spouští kontejnery.
  2. Docker CII je nástroj pro správu Dockeru.
  3. Dockerfile - návod, jak vytvořit image.
  4. Obrázek — obrázek, ze kterého je kontejner vyrolován.
  5. Kontejner.
  6. Registr Docker je úložiště obrázků.

Schematicky to vypadá asi takto:

Co je Docker: stručný exkurz do historie a základní abstrakce

Démon Docker běží na Docker_host a spouští kontejnery. Existuje Klient, který posílá příkazy: sestavení obrazu, stažení obrazu, spuštění kontejneru. Démon Docker přejde do registru a provede je. Klient Docker může přistupovat jak lokálně (k soketu Unix), tak prostřednictvím TCP ze vzdáleného hostitele.

Pojďme si projít jednotlivé komponenty.

Démon Docker - toto je serverová část, funguje na hostitelském počítači: stahuje obrázky a spouští z nich kontejnery, vytváří síť mezi kontejnery, shromažďuje protokoly. Když říkáme „vytvořit obraz“, démon to také dělá.

Docker CLI — Docker klientská část, konzolový nástroj pro práci s démonem. Opakuji, může fungovat nejen lokálně, ale i po síti.

Základní příkazy:

docker ps – zobrazí kontejnery, které aktuálně běží na hostiteli Docker.
obrázky dockeru – zobrazí obrázky stažené lokálně.
docker search <> - vyhledání obrázku v registru.
docker pull <> - stažení bitové kopie z registru do počítače.
sestavení dockeru < > - shromáždit obrázek.
docker run <> - spuštění kontejneru.
docker rm <> - vyjměte kontejner.
docker logs <> - protokoly kontejneru
docker start/stop/restart <> - práce s kontejnerem

Pokud ovládáte tyto příkazy a jste si jisti jejich používáním, považujte se za 70% zběhlého v Dockeru na uživatelské úrovni.

dockerfile - návod na vytvoření obrázku. Téměř každý příkaz instrukce je nová vrstva. Podívejme se na příklad.

Co je Docker: stručný exkurz do historie a základní abstrakce

Takto vypadá Dockerfile: příkazy vlevo, argumenty vpravo. Každý příkaz, který je zde (a obecně zapsaný v Dockerfile), vytvoří novou vrstvu v Image.

I při pohledu na levou stranu můžete zhruba pochopit, co se děje. Říkáme: „vytvořte pro nás složku“ - to je jedna vrstva. „Zprovoznění složky“ je další vrstva a tak dále. Vrstvený dort usnadňuje život. Pokud vytvořím další Dockerfile a změním něco na posledním řádku – spustím něco jiného než „python“ „main.py“ nebo nainstaluji závislosti z jiného souboru – pak budou předchozí vrstvy znovu použity jako mezipaměť.

Obraz - toto je balení kontejnerů, kontejnery se spouštějí z obrázku. Pokud se na Docker podíváme z pohledu správce balíčků (jako bychom pracovali s balíčky deb nebo rpm), pak image je v podstatě balíček rpm. Prostřednictvím yum install můžeme aplikaci nainstalovat, smazat, najít v úložišti a stáhnout. Zde je to přibližně stejné: kontejnery se spouštějí z obrázku, jsou uloženy v registru Docker (podobně jako yum v úložišti) a každý obrázek má hash SHA-256, název a značku.

Obrázek je vytvořen podle pokynů z Dockerfile. Každá instrukce z Dockerfile vytvoří novou vrstvu. Vrstvy lze znovu použít.

Registr Docker je úložiště obrázků Docker. Podobně jako OS má Docker veřejný standardní registr - dockerhub. Ale můžete si vytvořit své vlastní úložiště, svůj vlastní registr Docker.

Kontejner - co se spouští z obrázku. Vytvořili jsme obrázek podle pokynů z Dockerfile, poté jej spustíme z tohoto obrázku. Tento kontejner je izolován od ostatních kontejnerů a musí obsahovat vše potřebné pro fungování aplikace. V tomto případě jeden kontejner - jeden proces. Stává se, že musíte udělat dva procesy, ale to je poněkud v rozporu s ideologií Docker.

Požadavek „jeden kontejner, jeden proces“ souvisí s jmenným prostorem PID. Když proces s PID 1 začíná ve jmenném prostoru, pokud náhle zemře, zemře i celý kontejner. Pokud tam běží dva procesy: jeden je živý a druhý mrtvý, kontejner bude stále žít. To je ale otázka Best Practices, o těch si povíme v dalších materiálech.

Chcete-li podrobněji prostudovat funkce a celý program kurzu, klikněte na odkaz: “Docker video kurz".

Autor: Marcel Ibraev, certifikovaný správce Kubernetes, praktický inženýr v Southbridge, řečník a vývojář kurzů Slurm.

Zdroj: www.habr.com

Přidat komentář