Článek pro konferenci EurOpen.
Myslíte, že je čas podívat se kontejnerům na ozubená kolečka a nasadit vaši první aplikaci v kontejnerovém clusteru? Zkuste to v cloudu, je to nejrychlejší a nejpohodlnější cesta k tomu získat reálné zkušenosti z vývoje, deploymentu a provozu vaší aplikace v kontejnerech. V Azure můžete na kliknutí rozjet Kubernetes, Docker Swarm i Mesosphere DC/OS. Zkuste to.
Než se pustíme do kontejnerů a jejich orchestrátorů, pojďme se krátce zaměřit na situace, které nás dovedly až k potřebě na něčem takovém zapracovat.
Jednou z velmi častých příčin selhání v nasazování aplikací do produkce je nekonzistence vývojových, testovacích a produkčních prostředí. To je obvykle dáno tím, že se tato prostředí spravují z velké části ručně. Díky tomu se drží dlouhou dobu a „oprašují“, tedy do hotové VM se postupně upgradují různé moduly a knihovny a spouštějí různé testovací sady. Postupně v takové VM vniká dost nepřehledná situace a nikdo vlastně přesně neví, co tam je za konkrétní verze různých součástek nebo zbytků po předchozích verzích, natož, aby se to vědělo přes všechna prostředí od vývojového přes testovací, předprodukční až po produkci.
Má to řešení? Dobrou odpovědí je plně automatizovat a použít strategii phoenix serverů. Ta spočívá v tom, že stav VM není určování klikáním, ale je součástí spustitelné dokumentace, tedy předpisu pro nějaký desired state nástroj jako je Chef, Puppet, Ansible, SaltStack nebo PowerShell DCS. Samotná infrastruktura je řešena jako kód a výsledná kombinace umožní při každé změně zlikvidovat původní infrastrukturu a vytvořit novou (proto název strategie phoenix servery). To může vést až na immutable servery, tedy situaci, kdy do samotné VM není žádný manuální zásah ani možný a po spuštění se nikdy nemění (jakákoli změna nebo instalace nové verze aplikace = nová infrastruktura). Nicméně to má i nepříjemné stránky a o tom je můj další bod.
Situaci umíme velmi dobře řešit, ale celé je to trochu těžkopádné. Obrazy OS jsou dost velké a špatně se s nimi manipuluje. Trvá jim, než nastartují a celkem vzato potřebujeme poměrně dost nástrojů pro rozhýbání toho všeho na úrovni softwarově definované infrastruktury, configuration management systémů a tak podobně.
Řešením by možná bylo něco, co bude menší, pružnější a bude od začátku navrženo pro plnou automatizaci.
Co je „ta věc“, kterou nasazujeme do produkce? Co je jednotkou nasazení? Je to nějaká instalačka? Balíček v rámci OS nástroje pro package management? Archiv souborů (zip, tarbal)? Tyto klasické metody mohou mít trochu problém, když výchozí stav neodpovídá původním předpokladům (tedy je jednoduché to řešit „do čistého“, ale složitější do prostředí, které není plně pod kontrolou). Jde to, ale kolikrát se vám stalo, že to, co Dev dodal, nebylo Ops schopno rozumně rozchodit bez nutnosti to „poštelovat“? Jinak řečeno tento způsob řízení všech dependencies a podobných souvislostí není vždy stoprocentní.
Dobře, tak co použít hotové VM jako virtuální appliance, která se v Dev připraví a pak cestuje až do produkce? Tady narážíme na už zmíněné potíže s velikostí, těžkopádností a složitější automatizací (např. jak aplikaci sdělíte potřebné parametry jako je connection string do databáze – VM obvykle nemají žádný zabudovaný mechanismus, takže musíte řešení přidat extra, třeba cloud-init nebo napojovat aplikaci jako první krok do Etcd či Consul, což ale znamená aplikaci upravit).
Existují i moderní velmi příjemné postupy, třeba Habitat (by Chef), ale jde to řešit elegantně i předmětem tohoto článku, tedy kontejnery – ale nepředbíhejme.
Zažil jsem pár schůzek s lidmi z provozu (Ops) a v podstatě chtěli dělat DevOps, ale tak, aby u toho nemusel být Dev. Současně někdy vývojáři chtějí dělat DevOps bez Ops, hlavně aby o tom v provozu nevěděli, jinak to zablokují. To není udržitelné. Cesta od byznys nápadu přes jeho vývoj až po nasazení do produkce by měla být jedna trubka, jeden vývojovod, jeden proces, kde každý tahá stejným směrem a neustále se vrací častá a včasná zpětná vazba do Dev i k byznysu. O tom je DevOps a stávající Dev a Ops nástroje ke spolupráci možná neinspirují dostatečně.
V tomto článku se nechci věnovat podrobnostem konceptu mikroslužeb, ale rozhodně s tématem souvisí. Řeknu jen, že mikroslužby přináší velké výhody, ale ne zadarmo – vedou nás do světa distribuovaných aplikací, kde nás čekají nové efekty k řešení, odpadání součástek aplikace (místo „žuchnutí“ celého procesu se vším), nedostávání odpovědí na volání nebo latence a chybovost, problém stavu a jeho konzistence (v rámci CAP už nemůžeme ignorovat „P“, takže pokud chceme konzistenci, musíme se začít zabývat volbou lídra a tak podobně). Nicméně ty výhody možná stojí za to (ale ne vždy, byl bych tady poměrně pragmatický) a pak je tu jedna potíž. Mikroslužba nepotřebuje mnoho zdrojů, a tak bychom jich mohli do jednoho „prostoru“ dát hodně, nicméně v případě VM nám u každé mikroslužby bude sedět operační systém, který bude ukusovat CPU, paměť i disk. Potřebovali bychom něco jako deduplikaci paměti, ale to k dispozici úplně není.
Nebyla by nějaká možnost provozovat mikroslužby jako oddělené jednotky, ale nemít u každé jejich vlastní OS stack? Jasně, že byla.
Jak bylo asi zřejmé, kontejnery jsou zajímavou odpovědí na některé z naznačených problémů. Kontejnerová technologie existuje už mnoho let. Jde o vlastnosti na úrovni operačního systému, které dokáží například vytvořit izolovaný strom procesů, síťový namespace (například možnost nevidět skutečnou síťovku) a Linux bridge či OVS, schopnost řídit přidělování CPU a RAM zdrojů nebo izoloce na úrovni souborového systému a vrstvený file system. Nic z toho není úplně nové, ale Docker to dokázal zapřáhnout všechno dohromady a dát nad to krásné a jednoduché API. Docker nevymyslel kontejnerové technologie, ale podnítil jejich masovou použitelnost. Dokonce do takové míry, že Microsoft ve Windows 2016 uvedl svoje kontejnerové technologie, které jsou pochopitelně z hlediska implementace jiné než prostředky používané v Linuxu, ale která nahoru má ono stejné populární Docker API.
Dnes tedy Windows kontejnery můžete spouštět ve Windows, Linux kontejnery v Linux a to všechno řídit z jednotného Docker API a výhledově zařadit obě platformy pod jeden orchestrátor kontejnerů. Navíc se objevují implementace, které vám umožní chovat se ke kontejnerů „kontejnerově“, ale přitom to spouštět v plně hardwarově asistované izolaci čili tak, jak to dělá hypervisor s VM (příkladem jsou Hyper-V kontejnery ve Windows 2016). V tomto kontextu tedy dokonce kontejnery nastavují normu moderního ovládání, kterou můžeme aplikovat i na svět VM. Zdá se tedy, že kontejnerové hnutí opravdu obohatilo IT velmi výrazně.
Uvnitř kontejneru je jen to, co je specifické pro aplikaci, kterou hostuje. Vše ostatní si bere ze svého hostitele, tedy především OS kernel. Proto je malinkatý, startuje velmi rychle, dobře se s ním pracuje. Přestože stejně jako v případě VM můžete kontejner spustit, ručně tam něco nainstalovat a pak z něj vytvořit image, nástroje vás k tomu neinspirují. Jde to, ale na rozdíl od světa VM je tady normou kontejner „plnit“ zcela automaticky (např. Dockerfile nebo jiné prostředky jako jsou Cloud Foundry či Heroku buildpacky apod.). Kontejnery jsou zrozené pro automatizaci.
Původní stav kontejnerů byl takový, že v runtime nic není perzistentní. Nemá smysl si psát něco do lokálního souboru, všechno je stateless. Nemá smysl si poznamenat IP adresu uvnitř kontejneru, nehraje roli. Od té doby se mnoho změnilo (třeba skutečně perzistentní „volume“), ale základní koncept zůstává – kontejner je by design immutable. Předpokládá se, že vytvoříte kompletní image a ten spustíte tolikrát, kolik chcete, ale nepolezete do něj. Pokud kontejner po startu potřebuje získat nějaké informace (connection stringy, přístup do jiných API, service discovery) tak mu to řeknete přes Docker vstříknutím proměnné prostředí nebo se kontejner bude napojovat na nějakou service discovery službu s metadaty (v rámci orchestrátoru nebo vaší instanci Etcd, Consul apod.).
Nemáte tedy různé kontejnery pro dev, test a produkci. Je to stále totéž, stejný vnitřek co do verzí knihoven i aplikace, mění se maximálně jen vstříknuté informace (connection string apod.). Máte jeden kontejner co do jeho obsahu a z něj máte jeho instance běžící v různých prostředích. Co jste otestovali v test prostředí je tedy úplně totéž jako to, co pak poběží v produkci.
V předchozím bodu jsem popsal to, co současně dělá z kontejneru jednotku deploymentu. Ta „věc“, která nás dostává z kódu do jeho nasazení může být kontejner. Je to jednotka, do které se automatizovaně dostane aplikace a všechno co pro svůj běh potřebuje (pokud vás teď napadlo jak, vydržte, to je přesně něco, co se dá lépe řešit na úrovni platformy nad orchestrátorem, třeba v OpenShift, Cloud Foundry, Deis Workflow). Tuto jednotku pak testujeme a nasazujeme. Mnoho výrobců dnes nabízí své nástroje či aplikace jako hotové kontejnery minimálně pro možnost si rychle řešení vyzkoušet. Například než řešit, jak nainstalovat, můžete si spustit Azure CLI, SQL Server pro Linux nebo .NET Core pro Linux jako kontejner. Pro Microsoft je to cesta jak vám rychle, bezbolestně a spolehlivě doručit funkční systém třeba na rychlé vyzkoušení.
Na notebooku vývojáře to všechno vypadá nádherně, ale víte, jaký problém spuštění na větší infrastruktuře bude myslím největší ranou pro provoz? Networking. To, jak Docker začal, bylo vytvoření lokální sítě v rámci hostitele a veškerá externí komunikace se řešila jako překlad adres a portů na IP adresu hostitele. To je peklo. Služby běžící na nestandardních portech a s tím spojené problematické discovery (tradiční pojetí je najít si A záznam v DNS a to nestačí, buď musím koukat i na SRV nebo nasadit jiný discovery mechanismus jako je Etcd či Consul). Závislost na lokálním prostředí a „leaky abstractions“ s tím související (tedy žijete si v abstrahovaném světě, kde jednoduše aplikaci přiřadíte port a ono se to možná nepovede v závislosti na tom, na kterém hostiteli běžíte, protože už má ten port obsazený).
Fajn, řeknete si. Tohle je případ pro SDN overlay. Máte pravdu, ale kontejnery obvykle nasazujete do VM (přeci jen v rámci regulace a bezpečnosti chcete mít alespoň tematické clustery odděleny pořádně) a to je svět, ve kterém je také čím dál častější nasazování overlay. To vede na overlay přes overlay. Troubleshooting je noční můra, očekávejte problémy s MTU, penalizaci výkonu.
Zkrátka kontejnery a zejména jejich síťařinu je vhodné řešit nějak koordinovaně. Je to víc než skupina Docker hostitelů. Chceme takhle řešit celou skupinu, tedy cluster – a to je situace pro orchestrátor.
Když mám jeden notebook, spouštím kontejnery na něm. Jednoduché. Když mám celý cluster, musím si vybrat, kde kontejner poběží. Mám to rozhodovat sám? Počet hostitelů i kontejnerů se mi může neustále měnit a já potřebuji aplikovat nějaké složitější politiky. Například říct, že chci kontejner ve třech kopiích a to tak, ať jsou na různých hostitelích. Pokud hostitel nebo kontejner umře, chci to vyřešit (tzn. pokud počet běžících kontejnerů neodpovídá požadovanému, chci to opravit automaticky). Možná budu chtít hostitele obsazovat způsobem, že chci napakovat co nejvíc kontejnerů do co nejmenšího počtu hostitelů. Nebo naopak chci kontejnery rovnoměrně rozprostřít přes všechny hostitele. V některých případech možná potřebuji nějaké složitější politiky – tento kontejner musí běžet někde, kde má pod sebou SSD, tenhle musí běžet na procesoru s vysokou frekvencí, tenhle tam, kde je 10G síťovka.
Orchestrátor obsahuje scheduler. Plánovač, který vyhledá toho správného hostitele pro váš kontejner na základě různých kritérií. Také bude monitorovat stav hostitelů a kontejnerů a postará se o to, že váš kontejner běží v počtu instancí, které požadujete – pokud ne, sjedná nápravu bez vašeho zásahu.
Jeden kontejner může nabízet službu jinému. Jak se najdou? A co když hostitel selže a kontejner se znovu vytvoří někde jinde? Od orchestrátoru budeme potřebovat nějaké service discovery ideálně s možností získat metadata o kontejnerech. Typicky nabízí základní DNS službu a pokročilejší discovery spočívající v možnosti sáhnout do nějakého API (často orchestrátor pro sebe využívá Etcd a dá vám přístup k některým metadatům).
Druhá věc je, že z výkonnostních důvodů chci službu reprezentovat třeba třemi instancemi kontejneru. Jak to zařídit, aniž bych musel ručně řešit, kde která instance je a jak na ní budu balancovat provoz? Orchestrátory typicky mají mechanismus, jak to řešit, a to jak pro interní komunikaci (jedna sada kontejnerů k jiné sadě kontejnerů) tak pro externí (klient přistupuje na web). U té externí to bývá složitější, protože už se dostáváme do reálného světa a například v případě Kubernetes je možnost přímo z orchestrátoru ovládat infrastrukturní load balancer v Azure. Nezapomeňte, že orchestrátor možná dokáže přijmout provoz na kterémkoli nodu a balancovat to na správný kontejner, ale uživatelé musíte také balancovat na nody orchestrátoru. Dělat to ručně je nepohodlné a integrace Kubernetes s infrastrukturou tady dává obrovský smysl.
Pokud je kontejner immutable jednotkou deploymentu znamená to, že při nasazování nové verze aplikace půjde o nový kontejner. Potřeboval bych nějaký mechanismus, který dokáže mou mikroslužbu upgradovat za provozu. Tedy balancovat provoz na stávající verzi a postupně přidávat kontejnery s novou verzí, ty se starou postupně odebírat, až nakonec zbydou jen kontejnery s novou verzí. Takový automatizovaný postup obvykle orchestrátor nabízí.
Orchestrátory kontejnerů dávají obrovskou míru flexibility. Neříkají vám, jak je máte používat. To je někdy výhoda (můžete si to upravit pro svoje potřeby), ale mnohdy nevýhoda – třeba se vám hodí nějaký popisnější systém, který vás vede k cíli s využitím best practices a dává vám vyšší hodnotu. Jste tak schopni získat funkční aplikace rychleji a snadněji. Orchestrátor je jako psát v C, PaaS jako psát v Ruby. To první je určitě velmi flexibilní a výsledky mohou být velmi optimalizované, ale kód je delší, méně lidí mu rozumí a trvá to déle napsat. Ruby vás navádí svým směrem, je jednoduché a intuitivní, rychle se dostanete k cíli, ten ale možná nebude tak dokonale optimalizovaný pro vaše potřeby. Oba přístupy mají velký smysl a záleží na konkrétním projektu co je pro vás důležitější.
Kontejnery mají svůj původ v systémech masivně distribuovaných postavených na eventuální konzistenci a stateless principech. Váš objednávkový systém ale není distribuovaný, chcete striktní konzistenci (transakční zpracování) a v principu je stavový. Ano, state lze externalizovat (třeba do Azure DocumentDB nebo Azure Redis), striktní transakce implementovat s využitím externí ACID databáze (třeba Azure SQL Database) a zbytek postavit jako distribuované stateless služby. Jde to, ale možná je to hodně práce, která nepřinese zas tak velkou užitnou hodnotu. Ti velcí to udělat musí, aby mohli škálovat, ale pro vaší stabilní bázi uživatelů to třeba nepotřebujete a proč pak dělat takové cvičení?
Jsou různé systémy, které se snaží se stavovými aplikacemi vypořádat. Už i některé orchestrátory něco málo v tomto dělají (Kubernetes). Dobrý příkladem platformy jako služba (PaaS), která řeší stav velmi elegantně, je Microsoft Service Fabric. Upřímně řečeno je zatím ideální pro C# a Windows svět, ale pracuje se intenzivně na jeho generalizaci pro Linux a jiné jazyky. Uvádím spíš pro zajímavost, že tento rámec nabízí programátorům přímo jednoduchý způsob, jak si mohou držet state v paměti (tradičními prostředky z pohledu programátora) a platforma to na pozadí pro ně řeší jako distribuovaný systém. Tedy tento state replikuje mezi členy a sama řeší problém konzistence, tedy volbu lídra a tak dále. To je příklad velmi elegantní pomoci s řešením problému stavovosti, který jinak musíte rozlousknout sami (třeba externalizací, což ale znamená větší latenci).
Až dosud jsme předpokládali, že kontejner s aplikací tak nějak je. Orchestrátor si ho převezme a začne kouzlit. Kontejner je ale něco jako binárka, je to výsledek nějaké kompilace, kompletace, instalace knihoven apod. Jak se ze zdrojového kódu stane kontejner? To můžete vyřešit různými způsoby, ale právě platformy (PaaS) nabízí integrované řešení typicky ve formě nějakých build packů. Jak v případě (Pivotal) Cloud Foundry, (Red Hat) OpenShift tak (Microsoft) Deis Workflow dáváte platformě zdrojový kód a manifest obsahující potřebné informace o dependencies. Build pack pak zajistí všechno potřebné pro vznik kontejneru. Všechny tři platformy jsou open source a zejména OpenShift a Deis staví nad Kubernetes orchestrátorem (Cloud Foundry typicky využívá svůj vlastní orchestrátor).
Kontejner není kladivo na všechno. Velmi často budete chtít využít nějakou službu mimo samotný cluster – databázi jako služba, cache jako služba, kognitivní API a tak podobně. V takovém případě chcete například pro účely testování vytvořit v rámci spouštění kontejneru nějakou novou databázi a login do ní zprostředkovat kontejneru jako environmentální proměnnou. Provedete deployment a současně s tím vám nějaký service broker zajistí login do DB, token pro vaše API volání na předpověď počasí nebo cokoli takového. To samotné orchestrátory typicky neřeší, ale přitom je to žádoucí zejména pro Continuous Integration / Continuous Delivery scénáře. Například Cloud Foudry používá service broker API a Deis umožňuje stejné API napojit na Kubernetes.
Možná vaše mikroslužba funguje tak, že reaguje nějakou akcí na konkrétní událost. Například když se objeví nový obrázek v objektové storage, provede jeho zmenšení do náhledu, který tam také uloží. Co kdyby tento kód neběžel trvale v nějakém zdroji typu VM nebo kontejner, ale byl spuštěn až v okamžiku, kdy je to potřeba? Nějaká platforma by se dozvěděla o příchozím triggeru a zajistila provisioning zdrojů pro spuštění vaší reakce. Bez serveru, VM nebo kontejneru, o kterém byste věděli a museli se o něj starat. To jsou mikroslužby dotažené do úplného konce a dobrým příkladem takového řešení může být Azure Functions. Stejně jako vždy si umím představit, že vaše aplikace nemusí nutně využívat jen jednu jedinou technologii. Pro frontend možná upřednostníte web jako službu (například Azure App Services), pro byznys logiku kontejnery v Kubernetes třeba v rámci Azure Container Service, pro perzistentní data třeba zvolíte NoSQL jako je Azure DocumentDB, využijete některé kognitivní služby jako je Cortana suite a na některé události budete reagovat s Azure Functions.
Chcete orchestrátor? Výborně, na výběr jich je několik. Představme si tři nejpoužívanější.
První možností je rámec Mesos, který vznikl ještě před Dockerem a jedná se o nesmírně robustní dvou-úrovňový scheduler, který třeba Twitter nasadil v neuvěřitelném množství nodů. Jeho specialitou je schopnost provozovat naprosté odlišné činnosti v jednom řešení. Nejčastěji jde o náročně Big Data workloady dohromady s byznys aplikacemi a kontejnery. V rámci Mesos pak provozujete tzv. frameworky, tedy třídy aplikací. DC/OS, postavený na Mesos, je vlastně operační systém pro celé datové centrum, který velmi precizně přiděluje zdroje aplikacím. Jeden z rámců je Marathon a to je právě orchestrátor pro kontejnery. Na tom jsou vidět ony dvě úrovně. Swarm, Kubernetes nebo Marathon jsou orchestrátory kontejnerů a Mesos je orchestrátor orchestrátorů (ostatně skutečně je technicky možné běžet Kubernetes uvnitř Mesos).
Složitosti stranou. Zvolte DC/OS pokud potřebujete něco, co má delší historii a je skutečně prověřeno životem. Také bych se zaměřil na DC/OS, pokud kromě kontejnerů chcete jedním šmahem vyřešit i Hadoop nebo Spark nad stejnými zdroji. Pokud jdete jen po kontejnerech, zvažte i další varianty.
Docker stojí za vším nadšením kolem kontejnerů, a tak není divu, že i v oblasti orchestrátorů chce hrát významnou roli. Po funkční stránce možná zatím nedosahuje schopností konkurentů (i když to se rychle mění), ale má jednu krásnou vlastnost. Pro jeho ovládání používá prakticky stejné API jako Docker na jediném stroji. Pokud už jste se naučili používat Docker na notebooku, pak prakticky stejné příkazy můžete použít pro celý cluster. To se může ukázat jako velká výhoda pro nenáročný přechod do produkčního nasazení.
Pokud chcete kontejnery, je Kubernetes pravděpodobně nejdál. Některé jeho designové vlastnosti nemusí sednout každému (například koncept podů, tedy to, že jednotkou nasazení není kontejner, ale jeden a více kontejnerů v podu), ale myslím, že je dnes pro kontejnery nejlepší volbou. V čem jsou jeho výhody?
Kubernetes byl první kdo začal razit koncept přímé adresovatelnosti kontejnerů (tedy v jeho případě spíše podů), tedy IP per kontejner. K tomu se ostatní orchestrátory dopracovaly teprve nedávno, když všichni museli uznat, že to dává smysl. Síťově to můžete řešit různými způsoby a díky standardu CNI si mezi nimi lze vybírat. Možná skončíte u overlay přes overlay, ale v on-premise třeba bude lepší využít Calico a v případě Azure určitě CNI plugin právě pro toto prostředí, které zajistí nativní integraci s SDN implementací v Azure.
Druhá pro mě zásadní vlastnost také souvisí se sítí a tou je řešení problému příchozího provozu. Orchestrátory obvykle nabízí balancování a service discovery uvnitř svého světa, ale v něm uživatelé nejsou. Často pak orchestrátor nechá na vás, jak dostanete provoz uživatelů do clusteru a ještě vás potrápí s detaily implementace uvnitř clusteru (to je obvykle řešeno jako reverse proxy). Kubernetes nabízí schopnost orchestrátoru promluvit k infrastruktuře a dohodnout se. To je přesně i příklad provozu v Azure, kdy Kubernetes dokáže přímo mluvit k Azure Load Balanceru a pro vaši službu si vyžádat novou vnější adresu a zajistit balancování. Taková integrace je pro praxi naprosto zásadní.
Můj třetí důvod pro Kubernetes jako hlavní volbu je jeho pokračující snaha přestat předstírat, že všechno na světě je stateless. Pomalu začíná přidávat podporu pro stavové, řekněme tradičnější, aplikace. Loni bych vám tvrdil, že provozovat MySQL v kontejneru v produkci je nesmysl, ale dnes už bych se možná pomalu odvážil říct, že snad ok (nicméně – stále bych bez ohledu na to dal přednosta nějaké DB as a Service službě, kdy pro vás v cloudu databázi někdo vytvoří, zajistí HA a backup a tak podobně). Neřekl bych, že je hotovo, ale rozhodně jde Kubernetes správným směrem.
Předposlední argument pro tento orchestrátor vychází z toho, že byl první, kdo velmi dobře zpracoval desired state principy a především narolování nových verzí kontejnerů (tedy aplikací).
Je tu ještě jedna výhoda – nad Kubernetes se začínají stavět platformy. Projekt OpenShift (tažený firmou Red Hat) se před nějakou dobou transformoval do platformy nad Kubernetes. Deis je nativní řešení pro platformní služby nad Kubernetes a pro jeho výborné vlastnosti a zaměření Azure tímto směrem se Microsoft v dubnu 2017 rozhodl pro akvizici firmy aktivní v tomto open source projektu a chce akcelerovat jeho rozvoj (samozřejmě open source způsobem) a integrovat do Azure řešení. Slyšel jsem i o snahách rozjet Cloud Foundry nad Kubernetes místo proprietárního orchestrátoru Diego.
Proč a jak provozovat kontejnery v cloudu na příkladu Azure? První je to, že sestavit cluster bezpečně, spolehlivě a opakovatelně vyžaduje dost znalostí. Jeden ze zakladatelů Kubernetes, který se projektu věnoval ještě v Googlu před otevřením kódu komunitě, je nyní Microsoft zaměstnanec a se svým týmem automatizoval celý engine pro provisioning Kubernetes clusteru na kliknutí se všemi best practices (služba je součástí Azure Container Service, která podporuje kromě Kubernetes také DC/OS a Swarm, takže si můžete vybrat, kterou cestou se vydáte). Možná nevíte, jaký orchestrátor použít a jestli vám to bude dávat smysl. Celý cluster pro vás připravíme během několika minut – stačí říct jaký orchestrátor a kolik a jak velkých nodů chcete. Teprve v ten okamžik začnete platit a jakmile cluster zrušíte, neplatíte ani korunu.
Druhý důvod pro kontejnery v cloudu je jejich nedostatečná izolace z pohledu různých regulací a certifikací. Enterprise nebude chtít provozovat aplikaci, která řeší objednávání obědů pro zaměstnance ve stejném clusteru, ve kterém jsou citlivé údaje o pacientech, protože izolace kontejnerů není zdaleka tak silná, jako v případě hypervisorů (kontejner sdílí kernel a na něm záleží, jestli je to opravdu bezpečné, zatímco v případě hypervisoru izolaci pomáhají například i speciální instrukce CPU, takže oddělení je realizováno i na úrovni železa). Pravděpodobně tedy budete potřebovat clusterů hned několik pro různé třídy aplikací nebo prostředí (test, dev, prod). Vytvářet a rušit cluster tak budete daleko častěji, než jednou za rok a plná automatizace ve službě jako je Azure Container Service tady dává velký smysl. Navíc je tu nákladová stránka věci.
Cluster má nějaké zdroje k dispozici. Může být velký nebo malý. Dokážete dopředou odhadnou kolik přesně zdrojů bude každý cluster potřebovat a zajistit, že vaše spotřeba bude konstantní v čase (tedy nikdy nebudete mít zbytečně moc ani nepříjemně málo). To se v praxi těžko dělá, takže schopnost na kliknutí přidat nebo odebrat nody clusteru (se všemi bezpečnostními záležitostmi typu nakopírování klíčů apod.) se ukazuje jako dost důležitá. Navíc v cloudu platíte jen za to, co opravdu spotřebujete. Klidně můžete některé clustery na noc vypnout a ráno je automaticky vytvořit znova (třeba v dev prostředí). Nebo můžete clusteru na noc nebo víkend ubrat některé nody a ušetřit. Nebo naopak vaše aplikace zaznamenala úspěch, blíží se Vánoce, marketingová kampaň nebo zátěžový test a vy potřebujete 10x víc výkonu? V Azure stačí kliknout a půjčit si víc … třeba jen na pár hodin.
Velmi zásadní je, aby byl Kubernetes integrován s podvozkem zejména s ohledem na síťovou kontektivitu, load balancing od uživatelů nebo perzistenci datového úložiště. Řada zákazníků není v on-premise připravena na takovou míru automatizace a softwarové definovanosti, aby se Kubernetes mohl pěkně napojit. Místo budování lokální IaaS jen pro to, abyste mohli nad tím efektivně provozovat kontejnery, můžete jít do Azure, kde už je to pro vás všechno vymyšlené, odladěné a podporované. Jak síťařina, tak balancing, perzistence a k dispozici máte i privátní repositář pro vaše image integrovaný s identitou v Active Directory (tedy skutečně jde o Enterprise řešení se vším všudy, žádné stahování neověřených imagů z internetu, vše máte plně pod kontrolou s integrací na Enterprise řízení identity).
Běhat kontejnery rovnou nad železem je pro internetové giganty, kteří v zásadě provozují jedinou aplikaci, ale v brutální škále. Věřím, že v Enterprise prostředí potřebujeme něco jiného – schopnost vytvářet, bořit a škálovat vícero clusterů s různou úrovní citlivost dat nebo prostředí a využít infrastrukturních konceptů IaaS pro bezpečný a flexibilní běh našich aplikací. To je důvod, proč jsem přesvědčen, že Kubernetes patří do cloudu a zejména do Azure.
Na závěr bych se rád vrátil k tématu PaaS vs. orchestrátor. Jsem zastáncem toho, že ideální je použít nástroj, který vede k cíli tak, že můžu co nejdřív získat nějaké výhody, být efektivnější a rychlejší, a ne budovat nějakou platformu, která jednou třeba i k něčemu byznysu bude. Možná je k dispozici nějaká managed služba, která bude rychlejší a jednodušší, než se pokusit nacpat třeba databázi či identity systém do kontejneru. Možná můj webový frontend není mikroslužba a bude rychlejší a efektivnější použít cloudovou PaaS a její prostředky pro zajištění dostupnosti a efektivity. Zkrátka – použijte to, co dává smysl. Kubernetes, platformní služby nebo klidně i obyčejné VM. Vraťme se ale ke kontejnerům.
Rozhodnutí padlo, chcete kontejnery. Je lepší použít orchestrátor nebo nad ním nasadit nějaké PaaS řešení? Jste připraveni získat velkou flexibilitu, ale sami se poprat s některými výzvami jako je deployment aplikace ze zdrojáků, připojení na externí služby typu databáze nebo reverzní proxy, logování a integrace s CI/CD platformou? Pak za mne Kubernetes. Možná ale dává větší smysl nehrát si s technikáliemi a raději získat schopnost co nejdřív provozovat reálné aplikace. Ať vám něco poradí s tím, jak aplikace nasazovat, ať vám něco automatizuje překlopení aplikace ze zdrojáků do funkčního kontejneru, ať vám něco založí novou databázi a připojí vás na ni. V takovém případě, pokud chcete stále Kubernetes jako základní mechanismus řízení kontejnerů, bych šel do Red Hat OpenShift nebo nasadil nástroje z dílny Deis (Helm, Workflow, …). Třeba to pro vaše prostředí vymyslíte lépe, než oni, ale třeba po roce práce zjistíte, že jste vyvinuli zase jen svůj klon OpenShift nebo Deis a zůstali na to sami.
Kontejnery v cloudu? To mi dává velký smysl. Microsoft do kontejnerů velmi investuje jak ve světě Linux, tak Windows. V Azure můžete provozovat tři open source orchestrátory zcela nativně a máte podporu pro PaaS kontejnerová řešení jako je Cloud Foundry, OpenShift nebo Deis. Klasiká webově orientovaná PaaS Azure App Services dnes podporuje deployment Linux kontejnerů a v Linux kontejneru snadno získáte třeba SQL pro Linux nebo .NET Core. Investujte čas vývoje a provozu aplikací v kontejnerech a získejte co nejdřív zkušenosti. Nejrychlejší a nejpohodlnější cesta k tomu vede přes Azure, vyzkoušejte to.
Tomáš Kubica
Azure člověk, Microsoft