Lokální vývoj s Dockerem nebo Vagrantem?

Jaký je rozdíl mezi Vagrantem, Virtualboxem a Dockerem? Proč byste do svých úvah měli přidat i nástroje pro provisioning a jaký dopad mají všechny tyto technologie na vývoj a nasazování do produkčního prostředí?

K sepsání tohoto článku mě inspiroval Martin Svačinka svým Úvodem do Vagrantu. Podle komentářů mi přišlo, že mezi vývojáři stále není jasné, kam která technologie patří a co její nasazení obnáší.

Pokusím se proto tuto mlhu lehce profouknout – krátkým představením jednotlivých komponent a postřehy z praxe.

Manifest

Chceme:

  • Mít pohodlné vývojové prostředí, které bude co nejpodobnější situaci na produkci
  • Umět toto prostředí rozjet v jakémkoliv hostujícím systému, takže např. backend vývoj může probíhat v Linuxu, kdežto frontend pod Windows
  • Snadno přenášet aplikaci do produkce

Důvody jsou jasné, operace na živých pacientech nedopadají vždy nejlépe.

Technologie

K realizaci výše uvedených cílů použijeme Virtualbox, Vagrant a Docker.

Virtualbox & Vagrant

Virtualbox je program, ve kterém si naklikáte virtuální mašinu. Řeknete kolik prostředků z hostujícího notebooku uzme (např. 1 CPU, 1 GB RAM, 500 MB disku), jaký systém v ní má jet, jak bude propojena s okolním světem (sdílené disky, síťování) a během pár minut máte celý zázrak připraven.

Virtualbox většina z nás zná v podobě grafického klikátka, ale VBox disponuje i command-line rozhraním VBoxManage.

Pokud si v něm rozjedete Windowsy, tak na vás vybafne okno s grafickým rozhraním. Do linuxového boxu se ale budete schopni přihlásit i přes terminál z hostujícího systému (kupř. krz katodu)

Vagrant je jednoduchý wrapper kolem CLI rozhraní Virtualboxu. Elegantně nás odstiňuje od asi tak kilometru různých přepínačů utility VBoxManage a definuje jednotky příkazů, s pomocí kterých budete schopni virtuální stroj ovládat.

Pěkně se o tom rozepsal Martin – stačí vám jeden soubor s popisem stroje (Vagrantfile) a tři příkazy (vagrant up pro nastartování mašiny, vagrant ssh pro přihlášení dovnitř, vagrant halt pro zastavení).

Obě zmíněné technologie se starají o definici a spuštění nahé virtuální mašiny. V kontextu tohoto článku reprezentuje kopii (připodobnění) fyzického stroje či instance, která vám běží někde za devatero řekami a devatero horami. Nahé proto, že kromě základního systému toho na ní o moc víc nebude a opravdová práce vás teprve čeká.

Provisioning

Součástí Vagrantfile může být i popis toho, co se má stát po nahození stroje. Klidně nic, ale nás zajímá spíš něco: provisioning.

Provisioningem se nazývá proces, který na cílové mašině provede sadu úkonů, jenž systém dostanou do kýženého stavu. V nejjednodušším případě to může být BASH skript, ideálně spíš popis v nástrojích Puppet, Chef či Ansible (ve hře je totiž idempotence).

Ruku na srdce: pokud má být vaše snaha o vytvoření “identického” prostředí co k čemu, v této fázi vytavíte kopu času. Ze začátku to vypadá jednoduše: “Potřebuju akorát PHPko a webserver…”.
To určitě. Jakmile se do toho ponoříte hlouběji, tak zjistíte, že se musíte postarat o instalaci podpůrných knihoven, kromě aplikace nakonfigurovat i spoustu služeb, propojit vše s okolním světem… A nezapomněli jste na databází?

Stojí to ale rozhodně za to. Výsledné BASH skripty či Ansible playbooky budete schopni aplikovat jak na stroje vevnitř Virtualboxu tak třeba na Amazoním cloudu.

Teprve po tomto procesu můžete prohlásit, že máte běžící stroj s prostředím, který se podobá bratranci v produkci. Ikdyž na těch internetech kolují bajky o 100% shodě mezi lokálem a produkcí, moc se na ně neupínejte. První problém na sebe nenechá dlouho čekat – zatímco na produkční stroje budete zdrojové kódy distribuovat z nějakého vnějšího zdroje (např. GitHub, FTP), na lokále je budete mít nasdílené přes složku dovnitř virtuální mašiny.

Ďábel je schovaný v detailech a u provisioningu to platí dvojnásob trojnásob.

Docker

A tak jsme se dostali k Dockeru. K aparátu, který není pro každého, to si řekněme hned na úvod – pokud je vaším primárním prostředím Linux, patříte k těm šťastnějším. Jen pod Linuxem vyždímete z Dockeru maximum, nativně, bez obezliček. Kámoši z pláže (OSX, Windows) rozjedou Docker taky, ale s kompromisy, které někdy překáží.

Docker se na rozdíl od Virtualboxu nesnaží o virtualizaci stroje. Dockeří kontejnery se podobají spíše linuxovým procesům – rychle najedou (zlomky či jednotky vteřin), jsou méně náročné na prostředky hostujícího systému, ale přitom zevnitř vypadají jako izolovaná linuxová distribuce.

Lehkost Dockeru oproti virtualizaci má své příjemné důsledky:

Fundamentální rozdíl bude asi v tom, že Docker kontejnerů nám může na jedné mašině běžet bez problémů třeba padesát, zatímco padesát virtualizovaných OS už by to neutáhlo.
– Lukáš Havrlant, komentář k článku Úvod do Vagrantu

Abychom se v tom hned ze začátku neztratili, prosfištíme si pár slovíček:

  • Image – obraz systému, ze kterého se dají spouštět kontejnery. Image je výsledkem buildovacího procesu, uložen někde v útrobách vašeho systému.
  • Dockerfile – textový popis sestavení image. Sled kroků, které se postupně během buildu provedou a na jejichž konci bude hotový image.
  • Bázový image – každý Dockerfile začíná konstrukcí FROM, která říká, z jakého základu odvozujete svůj image. Můžete si sestavit vlastní obrazy z Ubuntu, CentOS, Debianu, ale třeba i přímo z některého z populárních jazyků (Python, Java) či služeb (Redis, Nginx).
  • Kontejner – běžící “proces” spuštěný z konkrétního image. Zpravidla se pouští se sadou parametrů, které se zdistribuují do kontejneru a aplikace/služba uvnitř se může podle nich přizpůsobit. Z jednoho image můžete spustit hromady mezi sebou nezávislých kontejnerů.

Pokud bychom se na výše uvedené podívali jako zkušení Vagrantéři (a Docker mlíčnáci), tak Dockerfile připomíná Vagrantfile (především jeho provisioning část), Docker image jsou boxy Virtualboxu a Docker kontejner je běžící instance Virtualboxu. Všechno je ale mnohem lehčí. Tak o tunu.

Vývoj pak může vypadat následovně:

  • Napíšete Dockerfile – chytře zvolíte bázový image, doinstalujete všechny komponenty který váš kód uvnitř bude potřebovat, pootvíráte vrátka dovnitř (porty, adresáře)
  • Zbuildíte image
  • Spustíte kontejner – zdrojové kódy nasdílíte dovnitř z mateřského systému, aplikaci necháte logovat na stdout. Anebo budete hlídat změny v projektu a při každé aktualizaci zdrojových kódů automaticky spustíte sadu testů.

A tak pořád dokola, dokud není finální image hotov. YMMV.

Tak kudy?

Cestu přes Vagrant bych libozvučně označil jako “klasickou” a “servercentrickou”.

Jejím výsledkem bude především sada provisioning skriptů, díky kterým rozjedete stroj(-e) jak v produkčním prostředí, tak i na počítači nového kolegy.

Pokud je vaše aplikace složitější a vyžaduje větší množství mašin, možná budete dotlačeni ke kompromisům (slučovat více produkčních mašin do jedné Vagrant instance, konfigurovat obsah lokálních strojů jinak než na produkci), čímž se ale budete vzdalovat od ideálu mít u sebe na notebooku 100% stejné prostředí jako na produkci.

Připravte se taky na to, že vás čas od času pozlobí Virtualbox (upgrade bývá občas adrenalinovým zážitkem, sdílení adresářů mezi hostem a boxem nepodporuje všechny vymoženosti vašho nativního filesystému, např. symlinky).

Docker si asi vyberou ti z vás, kteří tíhnou k rozbíjení aplikace na sadu mikroservices.

Jakmile u sebe odladíte konkrétní službičku a Dockerfile, můžete ho jediným krokem přetavit na image, vystavit do repozitáře a v nezměněné formě nasadit v produkčním prostředí.

Při vývoji s Dockerem je možné využít podobné mechanismy jako u Vagrantu – sdílení adresářů, síťové rozhraní, pouštění několika nezávislých kontejnerů.

Věci se ale začnou zesložiťovat při orchestraci na produkci – rozdistribuovat image tam, kam patří, propojit je správně mezi sebou a udržovat tu neukázněnou sebranku v lati dá nemálo práce. Daň za příjemnější vývoj (soustředění se na úzký izolovaný problém) je později vyvážen potem devops úderky.

V kontextu Dockeru dává smysl využívat systémy přímo pro něj určené (CoreOS, Kubernetes), protože kromě nativního prostředí pro kontejnery přináší nástroje pro jejich spouštění a škálování přes cluster desítek/stovek strojů. A abyste tohle všechno dokázali odladit u sebe, tak budete potřebovat co? Třeba právě Vagrant s konfigurací několika CoreOS strojů. A kruh se uzavírá…

Samozřejmě existuje i možnost nakombinovat obé do jediného – vybrat klasické linuxové distro s podporou Dockeru. Začít v malém a konzervativnějším režimu, se sadou provisioning skriptů. Pokud se Docker osvědčí, přenášet část logiky do Dockerfiles a postupně měnit prostředí na cluster.

Cest je hodně a žádnou z nich není možné označit za jedinou správnou.

Stříbrné kulky neexistují

Pro některé aplikace dává smysl zůstat konzervativním a řešit vývoj “servercentricky”. U jiných se můžete odvázat a v jednom tahu zdockerizovat a zmikroservicovat vše, co se vám dostane pod ruky.

Ať už se rozhodnote jakkkoliv, vemte v potaz i případná rizika. Nové technologie s sebou přináší nové postupy, neprošlapané cestičky, kde nic není, ani Google neporadí (co Google, ale ani StackOverflow!). Možná že při tvorbě vývojového prostředí dostanete apetit na zásadnější překopání celé aplikace, což vás ale bude stát další čas a zřejmě si to vyžádá i změnu ve složení vašeho týmu (na devops hrátky delegujte minimálně jednoho člověka na fulltime).

Oba přístupy vás ale vycviči v dokumetování build procesu. Buďto vám vznikne kopa provisioning skriptů, nebo Dockerfiles. Nebo obojího (vše samozřejmě pod přísným dohledem gitu či jiného verzovacího systému).

A to je jenom dobře.

Věděli jste, že nám můžete zasílat zprávičky? (Jen pro přihlášené.)

Komentáře: 3

Přehled komentářů

ptica kompromisy, které někdy překáží
Michal Valoušek Re: kompromisy, které někdy překáží
tuttle Super!
Zdroj: https://www.zdrojak.cz/?p=15767