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.
Nálepky:
Text vyšel původně na autorově blogu.
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í 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 🙂
Docker jako virtualizace
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ého 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ů nastartování 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 (i když 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:
- 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. - Veškerá konfigurace aplikace by se měla dělat přes environment proměnné.
- 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, proč nepoužívat Docker? 🙂
Docker používáme, v produkci nám na něm jede téměř všechno, ale autorovo nadšení pro použití pří vývoji bych nesdílel. Pokusili jsme se přesunout vývojové prostředí komplet do Dockeru, ale skončilo to tak, že část týmu se vrátila k nativnímu řešení. Problémy, na které jsme narazili:
Plus je to změna, které nabourává různé workflow, který si člověk vytvořil z doby před dockerem:
Celkově bych řekl, že Docker je dost užitečný, ale přestože většina článků, kterými jsme s ním cca před 2 lety seznamoval, mluvila o použití ve výjovém prostředí, u nás se výhody ukazují hlavně na produkci a při vývoji je to tak půl na půl výhody vs. způsobené problémy.
https://www.youtube.com/watch?v=PivpCKEiQOQ – je to parodia, avsak kto pouziva docker tak vie o spomenutych problemoch svoje
Developerov by som netlacil nasilu do Dockeru. Pokial su zvyknuti na svoj localhost, tak nech si ho pouzivaju. Co by som vsak od nich vyzadoval:
Este by som doplnil pre produkciu
https://www.linkedin.com/pulse/docker-unnecessary-fear-using-dr-amir-alsbih
Pan Docker ma jednu neprilis casto sklonovanou nevyhodu – pro me dost zasadni! V linuxu jede na JINEM JADRU – ktere nepodporuje NVidia ovladace – pro vsechny ochotne rozbit svou distribuci „skvelym“ dockerem ;)
Jaký jiný kernel?
„Version 3.10 or higher of the Linux kernel. The latest version of the kernel available for you platform is recommended.“
Plus je třeba mít příslušný storage driver, takže třeba na Ubuntu doinstalovat -extra, který přidá aufs.
Princip dockeru je, že sdílí jádro s hostitelem. Proto tak dlouho trvalo než byl Docker dostupný jinde než v Linuxu.
„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“
Od toho tu máme přeci docker-compose…