Jak mám navrhnut vysokou dostupnost a business continuity v Azure? Mám zůstat v jednom regionu, dělat DR z jednoho do druhého nebo obsadit rovnou dva? Pojďme se podívat na tři scénáře. Který vybrat záleží na byznys pohledu. Kde je hranice, kdy je lepší se omluvit a dát zákazníkům dáreček (jaký je finanční dopad) versus udržet aplikaci nahoře za cenu vyšších nákladů (a kolik bude stát tohle)?
Všechny navržené architektury nejsou vyloženě specifické pro Azure, ale vycházejí z fyzikálního limitu rychlosti světla s kterým ani Microsoft nedokáže nic udělat. Pokud se chcete vyvarovat toho, že jedna místní událost shodí všechno, musíte datová centra umístit dostatečně daleko od sebe - do různých regionů. Pak ale fyzikálně nepřekonatelná rychlost světla prakticky znemožní dělat mezi nimi synchronní operace (jinak bude výkon nesmyslně tragický - nechcete dělat legendární dvoufázový commit přes půl Evropy) a přichází asynchronní řešení a tedy obě lokality nejsou totéž, "netikají" vám stejně.
V další části budu používat dva zaběhnuté termíny - RPO (Recovery Point Objective) a RTO (Recovery Time Objective). Recovery data nedržíte synchronně (pak bychom mluvili spíše o HA), takže vaše kopie je nějakou dobu zpožděná. Při recovery tedy část zapsaných dat ztrácíte za dobu mezi posledním recovery pointem a okamžikem výpadku. To označujeme RPO a byznysově to znamená objednávky, které byly dokončeny, ale přišli jste o ně. Jiná věc je pokud dojde k havárii za jak dlouho je vše nahoře tak, že jste schopni dále provozovat byznys, tedy přijímat nové objednávky. To se označuje RTO. Možná je pro váš byznys zásadní rychle vyřizovat objednávky a to, že jste o nějaké zapsané přišli nevadí, protože jsou o tom papíry a dá se vyřešit zpětně ručně - pak vás trápí RTO, méně RPO. Možná naopak je pro váš byznys zásadní přijít o co nejméně už uzavřených objednávek a nedostupnost služby tak zásadní není - uzákazníci mohou s objednávkou pár hodin počkat. Pak akcentujete RPO, méně pak RTO. Většinou se pohybujete někde mezi těmito extrémy - podstatné ale je, že stanovení RPO/RTO je otázka byznysu.
Takhle si já pro sebe definuji tři úrovně business continuity v Azure s tím, že i první už obsahuje velmi dobrou úroveň dostupnosti:
Azure region není jeden rack s jedním switchem. Design regionů zálěží na jejich stáří a fyzických podmínkách okolí, ale vždy jde o soustavu do značné míry oddělených zón, takže fatální havárie v jedné nepřeruší provoz těch ostatních. Proto Azure dosahuje výborné dostupnosti i v jediném regionu. Nicméně přestože je všechno dobře navržené, přírodní katastrofa, fatální operační omyl nebo letadlová bomba může provoz ohrozit - všechno je blízko u sebe.
Dostupnost je daná střední chybovostí (MTBF) a rychlostí řešení chyby (MTTR) a právě druhá jmenovaná vlastnost je v moderní éře akcentovaná. V rámci jednoho regionu je tedy dobré dbát na redundanci (extrémně rychlé MTTR) nebo alepsoň rychlé recovery (solidní MTTR). To vede na cluster. Vřele doporučuji přenechat starost za jeho nastavení, správu, patchování a příslušné garance Microsoftu - tedy zvolit některou z platformních služeb. Řada z nich nabízí i v jediném reginu velmi zajímavá SLA (a to na službu, nikoli jen infrastrukturu). Tak například 99,99% přichází s Azure SQL, Azure Cosmos DB a hned jak vyjdou z preview režimu i Azure MySQL a Azure PostgreSQL pro vaše data. Webové služby a API dostanete s 99,95% SLA v rámci App Service. Můžete si samozřejmě smontovat svůj cluster sami s využitím Availability Setů, kde máte SLA 99,95% na to, že nepůjdou dolu všechna VM naráz a balancing na členy clusteru vám obstará třeba Azure Application Gateway (SLA 99,95% pokud uděláte deployment ve dvojici) nebo zabudovaný jednodušší Azure Load Balancer. Dokonce i v situaci, kdy nemůžete použít cluster (například aplikace je zastaralá), lze dostat SLA 99,9% na jednotlivou VM v případě použití Premium storage.
Co když aplikační chyba poškodí vaše data, administrátor omylem smaže důležitý soubor nebo vás nakazí destruktivní vir? SLA vám v ten okamžik nepomůže, potřebujete backup. Schopnost obnovit stav ze zálohy (místo složité reinstalace a rekonstrukce) je důležitá pro vaše MTTR a tím i dostupnost aplikace.
U platformních služeb jako jsou App Services či databáze Azure SQL, Azure Cosmos DB, Azure MySQL i Azure Postgresql jsou přímo integrované automatické zálohy, stačí je mít pouze zapnuté (u databází je to výchozí nastavení) a využít když potřebujete. Jednodušší to snad být nemůže. Pro deployment do VM využijte Azure Backup, který je velmi dobře integrovaný s Azure. Jednak zálohovacího agenta vám Azure na vyžádání sám nainstaluje, Backup tlačítko najdete v GUI přímo i na konkrétním VM a podporována je aplikačně konzistentní záloha pro Windows (VSS technologie) i Linux VM (přes spuštění vlastního skriptu ve VM nebo vám může stačit file-system konzistentní záloha, která je nativně připravena). Opět velmi jednoduché a dokonale integrované řešení.
Ne vždy je nedostupnost aplikace způsobena infrastrukturou - co když je pomalá aplikace nebo obsahuje nějakou chybu? Možná vám chybí nějaký klíčový patch a vystavujete se tak bezpečnostnímu riziku, které může vést k nedostupnosti. Monitoring aplikace, výkonnosti, chybovosti, dostupnosti i chování uživatelů je tak velmi důležitým prvkem pro zajištění co nejvyšší dostupnosti a o to se v Azure stará Application Insights. Kromě toho všeho dokáže i zátěžové testy jako služba (simulujte si předvánoční horečku nanečisto, ať víte, že to dobře dopadne) nebo komplexní webové průchodové testy (robot proklikává klíčové funkce ve vaší aplikaci). Pro bezpečnost doporučuji Azure Security Center a také Azure Log Analytics pro práci s logy (zejména pro ty middlewarové pokud provozujete svoje vlastní řešení ve VM místo platformní služby - aplikační logy typicky sbíráte hlavně s Application Insights). Možná vám bude dávat smysl tohle celé zaobalit do Operations Management Suite (hybridní řešení pro správu) a získat tak hloubkové bezpečnostní analýzy a další klíčové funkce (OMS přichází v balíčcích, které vám dají cenově zvýhodněné řešení zejména pokud si chcete pořídit Application Insights, Security Center, Azure Backup, analýzu logů, samotné OMS - vyjde to pak levněji jako balíček, např. OMS E2).
Jak už bylo řečeno Azure nabízí velmi příjemná SLA, ale co když vám ani ta nestačí? Například nemáte problém s tím, že v rámci SLA dojde někdy k rychlému zapauzování VM na několik vteřin kvůli updatu hypervisoru pod ní nebo třeba i restartu a výpadku na několik minut při nějaké havárii (když to není dost často, tedy minimálně tak, aby bylo dodrženo SLA). Jenže je tu i riziko, že vše pojede bez sebemenšího výpadku celý rok a pak dojde na pár hodin k odstřižení celého regionu. To se v Azure sice běžně nestává, ale teoretická možnost to je. Stejné výsledné SLA, ale možná větší efekt na váš byznys. Pak tedy možná budete přemýšlet o disaster recovery strategii - co uděláte, když se odmlčí celý Azure region?
Při DR nepotřebujeme, aby byly hodnoty RTO/RPO ve vteřinách či minutách (obvykle mluvíme v hodinách) - takové multi-region nasazení si rozebereme v úrovni tři, ale to má dramatické dopady na finance. Možná vašemu byznysu s ohledem na náklady stačí recovery v desítkách minut. Nechcete platit za CPU, RAM a další zdroje, když je aktuálně nepotřebujete.
Řešením tedy je nějakým způsobem zajistit, že v druhém regionu jsou všechna potřebná k data k rekonstrukci celého prostředí. Jak to zařídit záleží na typu služby - IaaS funguje jinak, než platformní služba. Podívejme se na tři nejčastější zástupce - VM, Azure SQL a Web App.
VM není ideální (na rozdíl třeba od blob dat, záloh apod.) řešit na úrovni replikace storage díky (a to je dobrá věc) velké vzdálenosti mezi regiony. Ta je totiž mezi regiony asynchronní a negarantuje konzistentní stav vašich disků. Potřebujeme tedy jiné řešení, které dokáže VM dostat do konzistentního stavu a tento pravidelně synchronizovat s druhým datovým centrem. Takovým řešením je Azure Site Recovery. S tímto řešením se podle situace (typ OS, míra přírůstků na disku apod.) dostanete i na RPO tak nízké, jako 30 vteřin (tzn. druhý region je jen 30 vteřin za prvním). ASR dokáže i komplikovanější scénáře jako je koordinovaná konzistence vícevrstvých aplikací (tzn. určitou sadu VM potřebujete ve stavu z identického času).
ASR vám pak umožní iniciovat vytvoření prostředí v druhém regionu a to včetně pravidelného testování řešení. Musí se samozřejmě vytvořit příslušné VM, ty musí nastartovat apod., takže počítejte s RTO miniálně v desítkách minut u menších VM (Azure SLA, které ovšem počítá s rezervou, mluví o 4 hodinovém RTO pro nešifrované VM, 6 hodin pro šifrované VM pro velikost VM 100GB - větší mašiny přidají čas navíc). Teprve v okamžiku havárie začnete platit za další zdroje, tedy samotná VM (do té doby platíte jen za službu ASR a obsazenou storage). Samostatnou kapitolou je IP/DNS adresace, ale o tom později.
Platformní SQL nabízí nejen výborné SLA 99,99%, ale také automatické zálohování s point-in-time restore granularitou kolem pěti minut pro logy a kolem hodiny pro inkrementy. Inkrementy jsou ukládány do storage accountu, který je geo-redundantní a čitelný v druhém regionu (RA-GRS) - čitelný znamená, že data jsou tam k dispozici ke čtení okamžitě, nemusíte čekat na failover storage a to má vliv na nízké RTO. Řešení tedy dosahuje RPO pod jednu hodinu. Azure SQL vám umožní tato data vzít a provést restore do jiné Azure SQL v cílovém regionu - vaše RTO (doba obnovy) tak záleží především na velikosti databáze a u těch největší může trvat několik hodin.
Webové a API aplikace doporučuji nasazovat způsobem, kdy všechno potřebné k jejich deploymentu je dostupné někde mimo. Tzn. instalace není ruční proces, ale automatizovaná úloha. Typicky se tohle řeší z version control systému a ten sám o sobě nabízí geo-redundanci. Například Visual Studio Team Services nebo GitHub to umožňují. Můžete také držet vše potřebné k instalaci v geo-replikované storage. Těmito postupy se typicky nasazuje applikace samotná, takže tento proces lze jednoduše zopakovat na druhé straně v okamžiku, kdy je to potřeba.
Něco jiného mohou být masivní statická data jako jsou obrázky, javascriptové client-side aplikace, videa apod. Ty možná nedáváte do App Services (na webový server), ale přímo do Blob storage (ta díky CORS může obsah servírovat rovnou klientovi bez nutnosti průchodu web serverem) - v takovém případě dejte blob storage na geo-reoredundantní variantu a o replikaci se nemusíte starat. Nicméně RA-GRS bude mít čtecí přístup v druhém regionu okamžitě dostupný, ale na jiné URL - vaše aplikace by s tím tedy měla počítat (tzn. ideálně poznat v kterém regionu je nasazena a podle toho upravit URL "obrázků"). Azure tým po nějaké době provede failover storage, takže data budou i na původní URL, ale pro nízké RTO nechcete čekat. Jinou kapitolou je, pokud používáte Azure CDN - tam jsou vaše data offloadována do CDN a v zásadě nemusíte nic moc dělat.
Pak je tu URL aplikace, ale o tom později.
Tohle je velké téma a asi by stálo za to se mu podrobněji věnovat v samostatném článku. Nicméně dnes nastíním nejzákladnější přístupy a jejich specifika.
První varianta spočívá v přesunutí kompletní IP adresace v okamžiku disaster recovery. To má jednu zásadní výhodu - nemusíte si nijak hrát s DNS a klienti chodí tam co dříve, nevadí žádný caching překladů apod. Z operačního hlediska spočívá řešení v přesunutí i všech podpůrných systémů, zejména DNS serveru (a pokud jsou servery v doméně uvnitř Azure VM tak i celého AD ... jinou variantou by bylo použít Azure Active Directory Domain Services). Zní to skvěle? Pojďme tedy na nevýhody.
Síťaři budou trochu vyděšení. Nemůžete mít stejné adresní prostory na dvou místech, takže musí dojít ke změně směrování - IP z původního místa musí zmizet (kompletně) a směrování se celé překlopit. Překlápění veřejných IP od Azure není možné, takže tady mluvíme o interních aplikacích, které uživatelé používají přes VPN nebo ExpressRoute. Je tedy nutné zajistit, aby provoz směroval do správného datového centra, tedy budete potřebovat ideálně dynamický routing a mít to dobře rozmyšlené - jedna nečekaná dynamická routa navíc může celé řešení zlikvidovat. Nejhorší jsou tady situace, kdy se to povede tak nějak napůl - tohle nejlépe funguje v režimu všechno nebo nic. A tím se dostáváme k poslední zásadní nevýhodě - složité testování. Nemůžete si jen tak dát požární cvičení a mít stejné adresy na dvou místech. To může vést k menší ochotě disaster recovery pravidelně zkoušet a to pak má vliv na úspěšnost v okamžiku, kdy je to potřeba naostro.
Pro interní aplikace je to dobrý a relativně jednoduchý scénář.
Druhá varianta počítá s tím, že IP adresy po failover budou jiné. V ten okamžik musíme vyřešit dva problémy - jak se najdou aplikační komponenty a jak aplikace najde uživatel.
Co se aplikačních komponent týče může být řešením používat nějaké dynamické přidělení DNS jména serveru. Azure interní DNS to pro vás může udělat nebo si můžete napojit svoje AD/DNS ve VM. V každém případě nenapojujte aplikační kompentny natvrdo přes IP adresy, při recovery se zapotíte.
Pro externí uživatele (ale i pro discovery interních endpointů v některých metodách) můžete změnit DNS záznamy nějakým jiným způsobem. Například v rámci ASR využít Azure DNS, které lze ovládat (mimo jiné) z PowerShell a externí DNS záznamy přepsat (na veřejné adresy, které získáte v druhém regionu). Totéž samozřejmě lze udělat i pro jiné externí DNS systémy. V takových případech nechávejte relativně krátké TTL, ať přeučení Internetu netrvá moc dlouho (zejména u vašich zákazníků, kteří nepoužívají ani vaše ani Microsoft DNS servery může trvat hodinu, než se informace zpropaguje Internetem).
Pokud vám to zní všechno nějak moc ručně a také pomalu z pohledu RTO, je tady varianta využít Azure Traffic Manager (nebo jiný DNS balancer). Řešení spočívá v tom, že aplikace dostane doménové jméno (pozor - kvůli DNS protokolu je problém s root doménami, potřebujete vždy appka.mojedomena.cz), které bude mít na starost Azure Traffic Manager. V něm k této doméně přiřadíte doménové jméno aplikace ve variantě první region a druhý region, takže například appka.westeurope.mojedomena.cz a appka.northeurope.mojedomena.cz). ATM vrátí uživateli jednu nebo druhou podle nějakého schématu, například podle priority a také podle toho, zda endpoint žije (pravidelně si testuje dostupnost aplikace). Klient potom (aniž by to nějak věděl) vznese druhý DNS dotaz tentokrát už na doménové jméno obsahující buď west nebo north a DNS server (ten může být libovolný) ho najde a odpoví IP adresou. Jinak řečeno vytvoříte si veřejnou IP v obou regionech a přiřadíte k nim příslušné DNS záznamy. Pak v Azure Traffic Manager vytvoříte hlavní záznam a health check. Klient před i po failover přistupuje na stejné DNS jméno a failover (z pohledu sítě/DNS) je zcela automatický, protože ATM pozná, že aplikace na jedné straně přestala odpovídat.
V případě platformního SQL toto běží na doménovém jméně a po disaster recovery bude jiné. Velmi bych doporučoval to ošetřit aplikačně, respektive změnou connection stringu. Například při deploymentu Web App je toto součástí metadat a je snadné to upravit, takže není nutné nijak zasahovat do kódu. Je také možné hrát si s překladem DNS podobně jako u Azure Traffic Manager, ale osobně, pokud nejste proti, bych to řešil connection stringem.
U App Services bych ani vteřinu neváhal a použil Azure Traffic Manager.
Pořád málo? Vážně potřebujete, aby druhý region nebyl nikdy pozadu víc jak pár vteřin (RPO třeba pod 30 vteřin) a současně aby recovery proces netrval déle jak pár vteřin (RTO pod 30 vteřin)? Dobrá, ale připravte se, že to budete muset zaplatit. V zásadě tady jde o to, že kvůli nízkému RTO není při failover čas něco někam kopírovat, vytvářet nějaké zdroje apod. Všechno už tam musí být a musí to běžet - díky tomu dostanete fantastické hodnoty, ale všechno platíte dvakrát.
Co potřebujeme je synchronizovat state tak, aby všechno bylo jen pár vteřin za primární site a to v akceschopném režimu, tedy pro recovery jde jen o to přepnout se do zapisovacího režimu místo read only a přesměrovat uživatele. Žádné vytváření zdrojů, žádné obnovy ze zálohy, starty serverů, žádné kopírování. Veškerý perzistentní state tedy externalizujme do něčeho, co ho umí dobře replikovat. Jednou z možností je rozhodně Azure SQL. To můžete jednoduše nastavit tak, že dělá okamžité asynchronní transakční replikace do živého Azure SQL v druhém regionu. RPO je pod 5 vteřin. Druhá Azure SQL je nahoře, dokonce je dostupná pro čtení (ale pozor, je za první opožděná, tak možná budete číst 5 vteřin stará data, s čímž musíte v aplikaci počítat), takže stačí v rozhodný okamžik přepnout do write režimu (RTO očekávejte pod 30 vteřin). Pokuste se veškerý (hlavně dlouhodobý a perzistentní) state externalizovat do řešení jako je Azure SQL (nebo CosmosDB či nějakou vámi spravovanou a geo-replikovanou databázi). Nedoporučoval bych cokoli dlouhodobého držet třeba uvnitř aplikačního serveru apod. Pokud máte session state třeba v Azure Redis, tak ta není geo-replikována, což obvykle nevadí, resp. při překlopení počítáte s tím, že session budou přerušeny a například obsah košíku lidem zmizí (ostatně děje se to velmi vyjímečně). V zásadě state, který můžete postrádat nechť je třeba v Azure Redis a co má být perzistentní, ať je v Azure SQL nebo CosmosDB.
Co se perzistentního state vs. konzistence týče záleží na architektuře aplikace a databáze, resp. vaší potřebě transakčního zpracování a vaší reakce na efekty snížené konzistence (až někam k eventuální konzistenci). Tradiční pojetí = pouze jeden region musí být aktivní pro zápis i čtení minimálně pro okruh transakčně konzistentních dat (jinak řečeno pokud máte dvě skupiny uživatelů napříč kterými nikdy nemusíte dělat ACID transakci, můžete je poslat do různých regionů a data rozdělit do dvou databází zapisujících v odlišných regionech). Pokud hledáte řešení aktivní současně na obou stranách s laditelnou konzistencí, jděte do Cosmos DB.
Tohle už jsme probrali - jděte do Azure Traffic Manager (DNS balancer). Pokud jedete klasickou konzistentní relační DB, použijte prioritu tak, že mluvíte do primárního regionu, kde je zapisovací DB. Existují i situace, kdy je zapisování velmi vzácné a aplikace primárně čte (například koukání na spotřebu elektřiny, kdy hodně lidí kouká, ale jen jeden zapisuje a že jsou data pár vteřin stará nevadí) - pak můžete rozhazovat do regionů pro rozklad zátěže (protože čtecí DB máte i v druhém a případný zápis sice v aplikaci nasměrujete do druhého regionu a bude tedy pomalejší, ale to nemusí vadit ... nebo ti co zapistují chodí napřímo rovnou tam). Pokud jedete distribuovaný systém v nějakém režimu se sníženou konzistencí (to není nic ošklivého, máto zásadní výhody i nevýhody) , tedy čtete i zapisujete v obou regionech, můžete ATM nastavit na balancing. V takovém případě pracují (obsluhují uživatele) oba regiony současně a díky rozdělení zátěže může snížit kapacitu (= náklady) v každém regionu (za cenu větší aplikační složitosti získáte active/active, který vám uspoří na zdrojích).
V tomto scénáři není druhý region skutečnou kopií prvního a je tedy na nás zajistit, aby byl web server, aplikáč apod. ve stejném stavu (stejná verze kódu, knihoven apod.). Z toho důvodu pro tento scénář zásadně nedoporučuji jakýkoli ruční deployment, ale striktní automatizované nasazení. U web aplikace je to relativně snadné (třeba z VSTS apod.), ale pokud u aplikační části provozujete vlastní server, ujistěte se, že je konzistentní. Desired State nástroje by měly být vaším nejlepším přítelem - PowerShell DSC (lze získat spolu s Azure Automation, OMS apod.), Ansible, Chef, Puppet, Saltstack. Další variantou je samozřejmě využít kontejnerů jako jednotky deploymentu.
Business continuity zdaleka není jen technická otázka - je to o byznysu. Lepší dostupnost = vyšší náklady na její zajištění. Výpadek = byznysové náklady (ztráta objednávky, nutnost dodat jiné dražší zboží, refundaci, dáreček). Hledáte stav, kdy marginální náklady na dostupnost jsou stejné jako marginální náklady výpadku. V ten okamžik jste to trefili akorát.
Začněte v jednom regionu - je to jednoduché! Použijte platformní služby, dají vám velmi vysokou dostupnost. Pokud chcete víc, přidejte DR - nebude to stát o moc víc. Je byznys opravdu náročný? Jděte do skutečného multi-region nasazení, Azure má prostředky, jak vám s tím významně pomoci.