„Cloud-native“ nebo jednoduše „cloudové“ aplikace jsou navrhovány speciálně pro provoz v cloudových infrastrukturách. Obvykle jsou sestaveny jako soubor slabě propojených mikroslužeb, zabalených do kontejnerů, které jsou spravovány cloudovou platformou. Tyto aplikace jsou z výchozího nastavení připraveny na selhání, což znamená, že spolehlivě fungují a škálují i při vážných selháních na úrovni infrastruktury. Na druhé straně se s tím pojí soubor omezení (kontrakty), které cloudová platforma ukládá na kontejnerové aplikace, aby je mohla automaticky spravovat.

I přesto, že si mnoho organizací plně uvědomuje nezbytnost a důležitost přechodu na cloudové aplikace, stále neví, kde začít. V tomto příspěvku se zaměříme na řadu principů, jejichž dodržování při vývoji kontejnerových aplikací umožní využít potenciál cloudových platforem a zajistit spolehlivý chod a škálovatelnost aplikací i při vážných selháních na úrovni IT infrastruktury. Konečným cílem zde uvedených principů je naučit se vytvářet aplikace, které mohou být automaticky spravovány cloudovými platformami, jako je Kubernetes.
Principy návrhu softwaru
Ve světě programování se principy chápou jako celkem obecná pravidla, která je třeba dodržovat při vývoji softwaru. Jejich použití je možné s jakýmkoliv programovacím jazykem. Každý princip má své cíle, jejichž dosažení obvykle slouží šablony a praktiky. Existuje také řada základních principů vytváření kvalitního softwaru, z nichž vycházejí všechny ostatní. Uvedeme příklady základních principů:
- (Keep it simple, stupid) – nezjednodušovat;
- (Don’t repeat yourself) – neopakovat se;
- (You aren’t gonna need it) – nevytvářet, co není bezprostředně potřeba;
- (Separation of concerns) – oddělovat odpovědnosti.
Jak je vidět, tyto principy nestanovují žádná konkrétní pravidla, ale patří mezi takzvaná zdravá rozumová hlediska vycházející z praktických zkušeností, s nimiž se ztotožňuje mnoho vývojářů a na které se pravidelně odvolávají.
Kromě toho existuje – soubor prvních pěti principů objektově orientovaného programování a návrhu, které formuloval Robert Martin. SOLID zahrnuje zjednodušené a otevřené k interpretaci vzájemně se doplňující principy, které – pokud se aplikují v celku – pomáhají vytvářet kvalitnější softwarové systémy a lépe je podporovat v dlouhodobém horizontu.
Principy SOLID se vztahují na oblast OOP a jsou formulovány v jazyce takových pojmů a konceptů, jako jsou třídy, rozhraní a dědičnost. Analogicky lze pro cloudové aplikace formulovat také principy vývoje, kde základním prvkem nebude třída, ale kontejner. Dodržováním těchto principů lze vytvářet kontejnerové aplikace, které lépe odpovídají cílům a úkolům cloudových platforem, jako je Kubernetes.
Cloudově orientované kontejnery: přístup Red Hat
Dnes lze do kontejnerů relativně snadno zabalit téměř jakoukoli aplikaci. Aby však byly aplikace efektivně automatizovány a orchestracovány v rámci cloudové platformy jako Kubernetes, je třeba vyvinout dodatečné úsilí.
Základem pro níže uvedené myšlenky byla metodologie a řada dalších prací zaměřených na různé aspekty vývoje webových aplikací, od správy zdrojového kódu až po modely škálování. Popisované principy se vztahují pouze na vývoj kontejnerových aplikací, které jsou postaveny na mikroservisách a jsou určeny pro cloudové platformy, jako je Kubernetes. Základním prvkem v našich úvahách je obraz kontejneru a pod cílovou prostředí pro spuštění kontejnerů rozumíme platformu orchestrace kontejnerů. Cílem navrhovaných principů je vytvářet kontejnery, pro které lze na většině platforem orchestrace automatizovat úkoly plánování (scheduling – výběr hostitele pro spuštění instance kontejneru), škálování a monitorování. Principy jsou předkládány v libovolném pořadí.
Princip jedné odpovědnosti (Single Concern Principle, SCP)
Tento princip je do značné míry podobný principu jediné odpovědnosti (Single Responsibility Principle, ), který je součástí sady SOLID a říká, že každý objekt by měl mít jednu odpovědnost, a tato odpovědnost by měla být plně inkapsulována v třídě. Podstatou SRP je, že každá odpovědnost je důvodem pro změny a třída by měla mít pouze jeden a jen jeden důvod pro změnu.
Ve SCP místo slova „odpovědnost“ (responsibility) používáme slovo „úkol“ (concern), abychom naznačili vyšší úroveň abstrakce a širší účel kontejneru ve srovnání s OOP třídou. A pokud je cílem SRP mít pouze jeden důvod pro změny, pak SCP představuje snahu rozšířit možnosti znovupoužití a výměny kontejnerů. Dodržováním SRP a vytvářením kontejneru, který řeší pouze jeden úkol a dělá to funkčně úplným způsobem, zvyšujete šance na znovupoužití tohoto kontejneru v různých kontextech aplikace.
Princip SCP říká, že každý kontejner by měl řešit pouze jeden úkol a dělat to dobře. Navíc, SCP ve světě kontejnerů je snáze dosažitelné než SRP ve světě OOP, protože kontejnery obvykle vykonávají pouze jeden proces, a většinu času tento proces řeší pouze jeden úkol.
Pokud nějaký kontejnerový mikroslužba musí řešit více úkolů najednou, může být rozdělena na jednodeskové kontejnery a sloučena v rámci jednoho podu (jednotky nasazení kontejnerové platformy) pomocí šablon sidecar a init-kontejnerů. Kromě toho SCP usnadňuje výměnu starého kontejneru (například webového serveru nebo zpravodajského brokera) za nový, který řeší stejný úkol, ale má rozšířenou funkčnost nebo se lépe škáluje.

Princip vysoké pozorovatelnosti (High Observability Principle, HOP)
Při používání kontejnerů jako jednotného způsobu balení a spouštění aplikací jsou samotné aplikace považovány za „černou skříňku“. Pokud se jedná o cloudové kontejnery, musí poskytovat prostředí pro běh speciální API rozhraní, aby kontrolovala zdravotní stav kontejnerů a v případě potřeby přijímala odpovídající opatření. Bez toho nebude možné standardizovat automatizaci aktualizace kontejnerů a řízení jejich životního cyklu, což na druhou stranu sníží odolnost a použitelnost softwarového systému.
V praxi by kontejnerová aplikace měla mít minimálně API pro různé typy kontrol zdraví: testy aktivity (liveness) a testy připravenosti (readiness). Pokud aplikace žádá o více, měla by poskytovat i další prostředky ke kontrole svého stavu. Například registraci důležitých událostí prostřednictvím STDERR a STDOUT pro agregaci protokolů pomocí Fluentd, Logstash a dalších podobných nástrojů. A také integraci s knihovnami pro sledování a sběr metrik, jako jsou OpenTracing, Prometheus a podobně.
Obecně lze aplikaci stále považovat za „černou skříňku“, ale musí být vybavena všemi API, které platforma potřebuje k tomu, aby ji co nejlépe monitorovala a spravovala.
Princip přizpůsobení životnímu cyklu (Life-cycle Conformance Principle, LCP)
LCP je opak HOP. Pokud HOP prohlašuje, že kontejner by měl poskytovat platformě API rozhraní ke čtení, LCP vyžaduje, aby aplikace byla schopna přijímat informace od platformy. Kromě toho musí kontejner nejen přijímat události, ale také se přizpůsobit, jinými slovy reagovat na ně. Odtud název principu, který lze chápat jako požadavek na poskytování API rozhraní pro zápis platformě.

Platformy mají různé typy událostí, které pomáhají řídit životní cyklus kontejneru. Ale rozhodnout, které z nich přijímat a jak reagovat, by měla sama aplikace.
Je jasné, že některé události jsou důležitější než jiné. Například, pokud aplikace špatně reaguje na neočekávané ukončení, musí být schopna přijímat zprávy signal: terminate (SIGTERM) a co nejrychleji iniciovat svůj proces ukončení, aby stihla před příchodem signálu: kill (SIGKILL), který následuje po SIGTERM.
Kromě toho mohou být pro životní cyklus aplikace důležité takové události, jako jsou PostStart a PreStop. Například po spuštění může aplikace potřebovat určitý čas na „ohřev“, než začne reagovat na požadavky. Nebo aplikace musí nějakým zvláštním způsobem uvolnit zdroje při ukončení.
Princip neměnnosti kontejnerového obrazu (Image Immutability Principle, IIP)
Obecně se má za to, že kontejnerové aplikace by měly zůstat neměnné po sestavení, i když jsou spuštěny v různých prostředích. Odtud vyplývá potřeba externalizovat úložiště dat během provozu (jinými slovy, použít k tomu externí prostředky), a také spoléhat na externí, specificky nastavené konfigurace pro dané provozní prostředí, místo aby se modifikovaly nebo vytvářely unikátní kontejnery pro každé prostředí. Po jakýchkoli změnách v aplikaci by měl být kontejnerový obraz znovu sestaven a nasazen ve všech používaných prostředích. Mimochodem, při správě IT systémů se používá podobný princip, známý jako princip neměnnosti serverů a infrastruktury.
Cílem IIP je zabránit vytváření samostatných kontejnerových obrazů pro různá provozní prostředí a používat všude stejný obraz spolu s odpovídající konfigurací pro konkrétní prostředí. Dodržování tohoto principu umožňuje realizovat takové důležité praktiky z hlediska automatizace cloudových systémů, jako je rollback (vrátit zpět) a rollout (přenést vpřed) aktualizací aplikace.

Princip jednorázovosti procesů (Process Disposability Principle, PDP)
Jednou z nejdůležitějších charakteristik kontejneru je jeho efemérnost: instanci kontejneru lze snadno vytvořit a snadno zničit, takže ji lze kdykoli snadno nahradit jinou instancí. Důvodů pro takovou výměnu může být celá řada: selhání testu na vhodnost, škálování aplikace, přesun na jiný hostitel, vyčerpání zdrojů platformy nebo jiné situace.
V důsledku toho by kontejnorové aplikace měly uchovávat svůj stav pomocí externích prostředků, nebo používat vnitřní distribuované schéma s redundancí. Kromě toho by mělo být aplikaci umožněno rychle se spouštět a rychle se zastavovat, a také být připraveno na náhlé fatální selhání hardwaru.
Jednou z praktik, která pomáhá realizovat tento princip, je vytváření malých kontejnerů. Cloudová prostředí mohou automaticky vybírat hostitele pro spuštění instance kontejneru, takže čím menší je velikost kontejneru, tím rychleji se spustí – jednoduše se rychleji zkopíruje na cílový hostitel přes síť.
Princip soběstačnosti (Self-containment Principle, S-CP)
Podle tohoto principu by měly být během sestavení zahrnuty všechny potřebné komponenty do kontejneru. Kontejner by měl být navržen s ohledem na to, že v systému existuje pouze čisté jádro Linuxu, takže všechny potřebné knihovny musí být umístěny přímo v kontejneru. Také by tam měly být umístěny věci jako runtime pro odpovídající programovací jazyk, aplikační platforma (pokud je to nutné) a další závislosti, které budou potřebné během provozu kontejnerové aplikace.

Výjimky se dělají pouze pro konfigurace, které se liší od prostředí k prostředí, a měly by být poskytovány v době běhu, například pomocí Kubernetes ConfigMap.
Aplikace může zahrnovat několik kontejnerizovaných komponent, například samostatný kontejner databázového systému jako součást kontejnerové webové aplikace. Podle principu S-CP by tyto kontejnery neměly být sloučeny do jednoho, ale měly by být navrženy tak, aby kontejner databázového systému obsahoval vše potřebné pro provoz databáze, a kontejner webové aplikace – vše potřebné pro fungování webové aplikace, včetně webového serveru. Výsledkem je, že během provozu kontejner webové aplikace bude závislý na kontejneru databázového systému a bude se na něj obracet podle potřeby.
Princip omezení v době běhu (Runtime Confinement Principle, RCP)
Princip S-CP určuje, jak má být kontejner sestaven a co by měl obsahovat binární soubor obrazu. Ale kontejner není jen "černá skříňka", která má pouze jednu charakteristiku – velikost souboru. Během běhu kontejner získává i další rozměry: objem používané paměti, procesorový čas a další systémové prostředky.

A tady se uplatní princip RCP, podle kterého by měl kontejner dekapsulovat své požadavky na systémové prostředky a předávat je platformě. S profilováním prostředků každého kontejneru (kolik potřebuje prostředků CPU, paměti, sítě a diskového systému) může platforma optimálně provádět správu a automatické škálování, řídit IT kapacity a udržovat SLA úrovně pro kontejnery.
Kromě splnění požadavků na prostředky kontejneru je pro aplikaci také důležité, aby nepřekročila stanovené limity. Jinak, v případě nedostatku prostředků, platforma s větší pravděpodobností zařadí aplikaci mezi ty, které je třeba přerušit nebo migrovat.
Když mluvíme o orientaci na cloud, máme na mysli především způsob práce.
Výše jsme formulovali řadu obecných principů, které tvoří metodologický základ pro vytváření kvalitních kontejnerových aplikací pro cloudová prostředí.
Poznamenejme, že kromě těchto obecných principů budete potřebovat také další pokročilé metody a techniky práce s kontejnery. Kromě toho máme několik krátkých doporučení, která mají konkrétnější charakter a měla by být aplikována (nebo neaplikována) v závislosti na situaci:
- Snažte se zmenšit velikost obrazů: odstraňte dočasné soubory a nenainstalujte nepotřebné balíčky – čím menší je velikost kontejneru, tím rychleji se sestavuje a kopíruje na cílový host přes síť.
- Orientujte se na libovolné uživatelské ID: nepoužívejte příkaz sudo nebo nějaká zvláštní userid pro spuštění svých kontejnerů.
- Označte důležité porty: čísla portů lze nastavovat i během běhu, ale je lepší je uvést pomocí příkazu EXPOSE – ostatním lidem a programům bude snazší používat vaše obrazy.
- Ukládejte trvalá data na objemy: data, která musí zůstat po zničení kontejneru, by měla být zapisována na objemy.
- Zapisujte metadata obrazu: tagy, štítky a anotace usnadňují používání obrazů – jiní vývojáři vám budou vděční.
- Synchronizujte hostitele a obrazy: některé kontejnerové aplikace vyžadují synchronizaci kontejneru s hostitelem na základě určitých atributů, jako je čas nebo identifikátor stroje.
- Na závěr se podělíme o šablony a osvědčené postupy, které pomohou efektivněji implementovat výše zmíněné principy:
11. června v 11:00
Co se dozvíte:
- Immutable Red Hat Enterprise Linux CoreOS
- OpenShift service mesh
- Operator framework
- Knative framework
Zdroj: habr.com
