Proč používat Docker

Docker používáme přes dva roky, takže máme celkem jasno, k čemu ho použít a k čemu určitě ne. Když se ale bavím s lidmi mimo náš tým, tak mě často zaskočí nízké obecné povědomí o možnostech Dockeru, které možná pramení z toho, že je to něco, o čem se hodně mluví, ale reálně si ho dost lidí ani lokálně nezkusilo. Přitom ekosystém Dockeru je extrémně přívětivý pro programátory (vlastně to považuji za hlavní přínos Dockeru) a dokázala ho v pohodě ovládnout i taková Windows lamka jako já, jejíž znalost Linuxu se omezovala na příkazy ls, cd, cp, rm a cat 🙂 Proto bych chtěl tímhle článkem ostatním dodat odvahu ten bájný Docker také zkusit a začít využívat jeho výhody.

K sepsání tohoto článku mě také inspirovala jedna příhoda z práce: Nedávno jsme řešili migraci dat mezi dvěma systémy, což se vyřešilo jednoduchou aplikací. Původně jsem myslel, že poběží řádově desítky minut a že tak bude nejjednodušší pustit ji u sebe na počítači – nakonec se ale ukázalo, že poběží spíš v řádu týdnů. Takže jsem udělal Dockerfile, vybuildil image a nasadil ji do našeho Marathon cloudu. Když jsem se o tom zmínil na standupu, tak se pak nový kolega podivil, že jestli by nebylo jednodušší pustit tu aplikaci na nějakém serveru než věnovat tolik úsilí na zdokerizování aplikace. Vtip je v tom, že celá akce mi nezabrala více než deset minut 🙂

Teď už ale k věci. Nejtěžší je ze začátku Docker nějak správně myšlenkově uchopit. Technicky nejpřesnější je mluvit o Dockeru, resp. kontejnerech, jako o izolaci procesů, což ale většině lidí moc nepomůže. S nějakou formou virtualizace se už ale setkal každý. Proto se mi nejvíc osvědčilo přemýšlet o Dockeru jako o virtualizaci, která ale nemá žádný overhead. To znamená start kontejneru (~virtuálního stroje) je okamžitý, neukrojí vám RAMku další operační systém (kernel se sdílí) a ani nedochází k žádnému zpomalení při vlastním běhu programu.

Docker se tak hodí použít všude, kde byste použili virtualizaci, ale možná vás to ani nenapadlo kvůli těžkopádnosti virtualizace.

Pokud jste Dockerem opravdu úplně nepolíbení, tak vězte, ze Dockerfile je jednoduchý textový soubor, který popisuje, jak má vypadat výsledná image. Tzn. typicky používáte instrukce na spuštění nějakého příkazu typu “apt-get install zavislost” nebo kopírování vaší aplikace dovnitř kontejneru.
Tzv. zbuilděním Dockerfile vznikne image:
docker build -t jmeno-image cesta_k_dockerfile
Tato image se pak dá pomocí docker push nahrát do Docker Registry, což je repozitář na Docker images. Hlavní veřejnou Docker Registry najdete na hub.docker.com.
Když pak pomocí docker run spustíte nějakou image, tak vznikne kontejner. Zde je zásadní rozdíl mezi virtualizací a Dockerem. Ve virtualizaci je vztah mezi image a virtuálním strojem typicky 1:1. V Dockeru ale můžete spustit z jedné image kontejnerů kolik chcete.

Instalace

Běžte na stránku Dockeru, klikněte na “Get Docker”, a postupujte podle instrukcí pro vaši platformu. Pokud se budeme bavit o klasických Linuxových kontejnerech, tak na Windows i Macu dojde k tomu, že se vám nainstaluje virtuál s Linuxem, a Docker běží uvnitř tohoto virtuálu. Docker tooling se vám ale nainstaluje lokálně, takže můžete pouštět docker příkazy z vašeho nativního prostředí. Nikdy jsem neměl potřebu řešit to, že je na pozadí nějaký virtuál, natož se do něj koukat. Instalátory zajistí, že váš lokální docker příkaz volá Docker daemona, který běží uvnitř virtuálu. Tzn. i všechny spouštěné kontejnery běží uvnitř toho jediné virtuálu. A to pro běžný vývoj v pohodě stačí.

Pozn.: Vedle klasických Linuxových kontejnerů, kterými to vše začalo, nyní už existují i Windows Containers, což je nativní řešení kontejnerů pod Windows, které je dostupné v posledních verzích Windows (Windows 10 Anniversary Update a Windows Server 2016). Pokud jste na Windows, tak si pomocí ikonky vedle hodin můžete přepínat, jestli má být Docker tooling napojený na Linuxové nebo Windowsí kontejnery. Prakticky vše, co bude psát níže, platí i Windows Containers.

První pravidlo

Do jednoho kontejneru patří jen jedna věc. Tzn. nikdy nedávejte do jednoho kontejneru více aplikací, příp. aplikaci i databázi. Když máte totiž v jednom kontejneru jen jednu věc, tak vám nikdy nevznikne problém s tím, že by dvě aplikace měly konfliktní závislosti. Docker image tak představuje balíček, ve kterém je aplikace včetně všech závislostí, a je to tudíž ideální forma, jak distribuovat svou aplikaci.
Jediné, kdy si dovedu představit mít nějakou über-image, je mít demo-image vaší aplikace, který se dá jednoduše pustit a potenciální zájemce si tak může po spuštění jediné příkazu začít proklikávat vaše krásné guičko 🙂

Příklad užití 1 – testování

Kde můžete s Dockerem začít ihned, je v rámci testování. Např. když máte nějaký integrační test proti databázi, kde nyní ta databáze běží? Někdo ji má lokálně nainstalovanou, někdo používá nějakou sdílenou instanci (fuj!). Díky rychlosti Dockeru můžete ale pro každý test (nebo skupinu testů) pustit novou instanci databáze, která bude v přesně definovaném stavu (takže není ani třeba řešit úklid). Pokud si nejste jisti, jak bude vaše aplikace pracovat s novou verzí databáze, stačí změnit verzi používané image, pustit testy a hned víte.
Jediné, co tedy musíte při použití Dockeru v testech udělat, je zajistit před spuštěním testů nastartovaní kontejneru s databází a testy nasměrovat na tuto databázi.
Konkrétně třeba pro použití Postgresu stačí pustit tento příkaz:
docker run --rm -p 1000:5432 postgres:9.6.2
A v okamžiku máte na portu 1000 dostupnou čistou instanci Postgresu ve verzi 9.6.2! Samozřejmě používat takto naivně nějaký pevný port není dobrý nápad (ale začít tak je úplně OK), ale snadné přečtení nějakého dynamicky přiřazeného portu vám zajistí tooling pro váš testovací framework, který jistě už má podporu pro Docker – např. prostřednictvím TestContainers nebo Gradle pluginu.

Samozřejmě se nemusíte omezovat jen na databáze, ale můžete si takhle jednoduše pro testy připravit třeba RabbitMQ nebo Kafku. Nejen pokud mají vaše testy více závislostí na externích službách, vyplatí se podívat na příkaz docker-compose, který umožňuje spouštění a prodrátování více kontejnerů naráz. Kontejnery a jejich vazby popíšete v triviálním YAMLu (viz proklik v předchozí větě).

Příklad užití 2 – command-line aplikace

Příklad užití, o kterém jsem snad nikde nikdy nečetl, ale my ho používáme a je extrémně užitečný – zabalit do Docker image command-line aplikaci. Vtip je v tom, že když se tu aplikaci někde rozhodnete použít, tak nemusíte řešit její instalaci/distribuci (je to Docker image pushnutá v nějaké Docker Registry) a nemusíte řešit její závislosti. Tzn. nemusíte si instalovat Perl nebo řešit nekompatibilitu různých verzí Pythonu.

Máme tímhle způsobem např. distribuovaný tool, který slouží k nasazení do Marathon cloudu. Když vynechám předání specifických parametrů do prográmku jako takového, tak kdekoliv stačí pustit tenhle příkaz (třeba i na vašem stroji):
docker run avastsoftware/marathon-deployer
No není to skvělé? 🙂

Příklad užití 3 – bezstavové aplikace

Další oblast, ve které Docker září, jsou bezstavové aplikace. Dokonce bych řekl, že je to jeho hlavní produkční nasazení. Jednoduše jde o to, že vaši aplikaci, která je Twelve-Factor App, distribuujete a nasazujete jako Docker image. Z oněch 12 pravidel bych vypíchnul tyto, resp. je i trošku poupravil do Dockeřího světa:

  1. Dockerfile musí popisovat opravdu všechny závislosti vaší aplikace, takže výsledná image je schopná běhu bez dalších zásahů. Typicky to není nic složitého, stačí začít z nějaké vhodně zvolené bázové image, např. openjdk:8-jre pro Javu/Scalu.
  2. Veškerá konfigurace aplikace by se měla dělat přes environment proměnné.
  3. Aplikace musí být napsaná tak, aby bylo možné ji neomezeně škálovat. Tj. pokud nestíhá, pustí se ve více instancích.

Jak provozovat takové aplikace je téma na celou knihu, takže jen ve zkratce. Mohli byste začít nějakým jednoduchým řešením, které prostě na nějakém volném serveru pustí Docker image, jakou potřebujete. Takovou cestou se třeba před lety vydalo Spotify. Nyní už ale existují systémy, které tzv. orchestraci vyřeší elegantně za vás. Nejpoužívanější jsou Kubernetes, Mesos/Marathon a Docker Swarm.
Pokud si chcete nějaké takové řešení rozjet, může se vám hodit Rancher, který zajistí instalaci za vás. Pokud jste v Azure, můžete zkusit Azure Container Service, které vám také umožní jednoduše rozjet jednu ze tří orchestračních platforem.

Příklad neužití – stavové aplikace

To, k čemu zatím Docker nepoužíváme a zatím se ani nechystáme, je uzavírat do něj stavové aplikace. Takže databáze nebo messagingové systémy máme v produkčním prostředí stále vedle. V oblasti stavových aplikací se stále děje něco nového, ale pořád to IMHO není ve stavu, aby se to dalo produkčně použít. I když to na papíře může vypadat růžově, stále někde čtu horror-stories, jak to nefunguje.
Mimochodem, tento bod nekoliduje s použitím databází při testování. Tam totiž nejde o trvalé uložení dat, ale jen o jednorázové použití kontejneru pro test a následné zahození.
Taktéž by mělo být v pohodě použít Docker s databází v necloudovém nasazení – tj. aplikace je sice zabalená v Dockeru, ale běží stále na jednom stroji a má lokálně přimountovaná ta samá data.

Použít či nepoužít

Uznávám, že začít rovnou psát bezstavové aplikace zabalené v Dockeru a pouštěné v nějakém privátním cloudu, může být velký skok, který není radno dělat jako první věc na seznámení s Dockerem. Začít ale Docker využívat pro testování je velmi snadné, užitečné a nenese žádné riziko.

Jaká je nyní vaše výmluva proc nepoužívat Docker? 🙂

Příspěvek byl publikován v rubrice Programování a jeho autorem je Augi. Můžete si jeho odkaz uložit mezi své oblíbené záložky nebo ho sdílet s přáteli.

9 komentářů u „Proč používat Docker

  1. Dobře, takže jestli to teď chápu správně a chtěl bych použít docker pro development, tak budu mít jeden image pro samotnou aplikaci (třeba ruby on rails, v image, tudíž nemusím mít ruby on rails nainstalováno lokálně vůbec) a databázi zatím pořád lokálně (protože zatím to není ještě ready)?

  2. Díky za dotaz! Produkční použití stavových aplikací (tj. hlavně databází) bych opravdu nedoporučil. V případě testů nevnímám ale databáze jako stavové aplikace, protože tam kontejner s databází vytvořím, použiji pro test a zahodím. Doplnil jsem to do článku.

    Co se týče developmentu, tak při integračních testech jedné servisy mám databázi rozjetou v kontejneru a ta servisa mi většinou běží lokálně. Měl jsem ale i příklad aplikace, která se skládala ze dvou servis, jedné databáze a jednoho RabbitMQ – pak jediné, co běželo lokálně, byly testy (pouštěné přes Gradle). Tj. obě servisy, databáze i RabbitMQ byly v kontejnerech. To byly takové end-to-end testy.

  3. Moc pěkný článek. Jen mě napadla malá drobnost ad pravidlo jeden container = jedna aplikace. To není úplně přesné. V dockeru se spíše jedná o procesy. Takže jeden cotainer = jeden proces. Ale občas je právě nutné aby v containeru běželo několik procesů, které tvoří jednu aplikaci. Naštěstí má tohle docker pořešené pomocí supervisord https://docs.docker.com/engine/admin/using_supervisord/ ale samozřejmě pokud to jde, je lepší se tomu vyhnout a držet pravidlo jednoho procesu na container.

  4. Aleši, to je určitě čistší cesta, ale viděl jsem párkrát použitý i jediný kontejner a docela to dává smysl. Nemusíš si stahovat žádný soubor, jen si zkopíruješ jeden docker run, takže ta bariéra si to zkusit je o kousínek nižší.

  5. Super článek, jen dodávám, že “Nikdy jsem neměl potřebu řešit to, že je na pozadí nějaký virtuál, natož se do něj koukat.” nemusí pro řadu uživatelů vůbec platit. Já jsem před rokem s Dockerem na Windows bojoval a byl to pain, viz http://tomaszalusky.blogspot.cz/2016/03/poznamky-z-instalace-docker-toolbox-na.html . Od té doby se hodně věcí vylepšilo, ale např. pro Docker for Windows je kvůli HyperV stále třeba mít Windows 10 Professional, Home nestačí.

  6. Moje výmluva byla, že jsem potřeboval Windows kontejner s MS SQL, což bylo komplikované až nemožné, navíc image měl spoustu GB, takže jsem tehdy stejně skončil u virtualizace. Naštěstí už Windows image nepotřebuju, ale jaký je stav dnes?

Napsat komentář

Vaše emailová adresa nebude zveřejněna.