Stručně: automatizuj způsob, jakým se servery vracejí k životu, dřív než způsob, jakým vznikají. Izolaci mezi tenanty ber jako produkt, ne jako funkci. Počítej s tím, že každý ruční krok se jednou promění v tiket. Role a oprávnění postav dřív, než přijde druhý zákazník. Člověka buď jen kvůli věcem, které musí opravit člověk. A zálohy prodávej jako něco, co zákazník vidí a může spustit tlačítkem. Téměř všechno ostatní, co nás provoz RE:NODE naučil, z těchto šesti bodů vyplývá.
Platforma vyrostla na 500+ klientů a 1 200+ serverů napříč hostingem herních serverů, VDS, webů, databází a úložišť, s desítkami nodů a více než 30 službami pod automatizovaným řízením životního cyklu a s průměrným časem nasazení pod pět minut. Na poměry cloudu to není velká flotila. Je to přesně ta velikost, kde zkratky z doby padesáti serverů přestávají být levné a začínají chodit na e-mail.
Následují zásady a názory, ne příběhy z bojiště. Kde se hodí příklad, je zjevně smyšlený. Pokud provozuješ servery pro jiné lidi - herní komunitu, malou agenturu, hostingový vedlejšák - většina z toho platí i pro tebe, jen v desetinovém měřítku.
Automatizuj obnovu dřív než vytváření#
Každý hostingový projekt začíná tou zábavnou částí: tlačítkem, které vytvoří server. Platba projde, objeví se kontejner, přidělí se port, vygeneruje se heslo, zákazník dostane e-mail. Dobře se to staví a dobře se to ukazuje na demu.
Je to ale zároveň nejméně důležitá automatizace celé platformy. Vytvoření proběhne jednou na server. Obnova proběhne pokaždé, když proces spadne, node se restartuje, zaplní se disk nebo se pokazí update - za život serveru mnohokrát. Když je vytváření ruční, ztratíš pár minut na objednávku. Když je ruční obnova, ztratíš noci.
Pravidlo, ke kterému to dospělo: než se nový druh serveru smí prodávat, musí platforma umět bez člověka odpovědět na tři otázky.
- Má běžet?
- Opravdu běží?
- Pokud se ty dvě odpovědi liší, co je bezpečné s tím udělat?
Ve třetí otázce je celý návrh. „Restartuj ho“ je nasnadě a často špatně. Řekněme, že herní server padá při startu kvůli rozbitému modu. Nekonečné restartování jen pálí CPU na sdíleném nodu a plní log. Logika obnovy proto potřebuje paměť: musí vědět, kolikrát už to zkoušela, a kdy přestat a někomu to oznámit.
V RE:NODE z toho vznikl watcher, který každé dvě minuty hlídá, jestli uptime nešel zpět nebo jestli server neodpadl do offline. Restarty, které si vyžádal zákazník, se nepočítají. Tři nevyžádané restarty za hodinu dají na stránku serveru varování a automaticky otevřou tiket, šest server pozastaví. Čísla jsou méně důležitá než tvar: automatická obnova, pak automatická eskalace, pak tvrdá zarážka. Pohled ze strany zákazníka popisuje článek proč se tvůj herní server pořád restartuje.
Druhá věc, kterou obnova vynutí, je idempotence. Akce obnovy se bude opakovat - kvůli watcheru, kvůli člověku, kvůli druhé kopii watcheru, na kterou se zapomnělo. „Spusť tento server“ musí být bezpečné provést dvakrát. „Přidel port“ musí poznat, že port už přidělený je. Každá neidempotentní akce v platformě nakonec proběhla dvakrát a výsledek byl vždycky horší, než kdyby neproběhla vůbec.
Požadovaný stav, ne skripty#
Druhá zásada vyplývá z první. Na začátku bylo zřizování sled kroků: vytvoř kontejner, pak připoj úložiště, pak přidel porty, pak zapiš konfiguraci. Sled se píše snadno a obnovuje strašně, protože když selže třetí krok, zůstane napůl postavený server a skript neví, která polovina chybí.
Model, který bychom dnes zvolili od prvního dne, je požadovaný stav a reconciliation. Databáze říká, co má existovat: tento server, tolik paměti, tyto porty, tento image, běžící nebo zastavený. Smyčka to porovnává s tím, co skutečně existuje na nodu, a mezeru zavírá po jednom bezpečném kroku. Vytvoření je jen reconciliation z ničeho. Obnova je reconciliation z něčeho rozbitého. Změny tarifu, změny portů i migrace jsou stejná smyčka s jiným cílem.
# The whole idea, minus the hard parts.def reconcile(server): want = desired_state(server) # from the database have = observed_state(server) # from the node for step in plan(have, want): # smallest safe steps first if not step.apply(): # every step is idempotent record_failure(server, step) return # retry on the next pass mark_converged(server)Nic z toho není nové - takhle uvažují Kubernetes, Terraform i většina správy konfigurace. Poučení není ve vzoru, ale v tom, jak brzy ho potřebuješ. Na první napůl postavený server by se nemělo čekat. Dodatečně nasadit požadovaný stav na systém ve tvaru skriptů stojí mnohem víc než s ním začít, protože do té doby je každý okrajový případ vyřešený zvláštní větví ve skriptu, na kterou nikdo nechce sáhnout.
Izolace mezi tenanty je produkt#
Zákazníci nekupují kontejner. Kupují jistotu, že se jejich server chová stejně, ať je soused nečinný, nebo ve smyčce spouští špatně napsaný plugin. Bez toho nezáleží na ničem jiném ze seznamu funkcí.
Existují tři zdroje, u nichž izolace rozhoduje, jestli platforma působí spravedlivě: CPU, paměť a disk. Pevné názory, které k nim máme:
| Zdroj | Co dělat vždy | Proč |
|---|---|---|
| CPU | Tvrdé omezení na zakoupený podíl | Burst zdarma je fajn, dokud se nevezme |
| Paměť | Zastavit na limitu, bez swapu | Swap zpomalí jednoho tenanta pro všechny |
| Disk | Kvóta na server, vynucená | Jeden plný disk nesmí znamenat výpadek nodu |
V RE:NODE je každý server vlastní kontejner, CPU je tvrdě omezené na zakoupený podíl a na limitu paměti kernel kontejner zastaví a ten se čistě restartuje, místo aby swapoval - což je opak výchozího nastavení upstream Pterodactylu. Právě to lidi překvapuje. Server, který se zabije a restartuje, vypadá v dané chvíli hůř než server, který pomalu swapuje. V praxi ale swapující server stáhne s sebou diskové I/O všech ostatních na nodu a nejvíc trpí zákazník, který neudělal nic špatně. Mechaniku popisuje Linux swap a OOM killer, stranu sdíleného hardwaru sdílené CPU a hluční sousedé.
Nepříjemné je, že přísná izolace dělá z platformy méně štědrou. Hosting, který ti zdarma dovolí burst na 400 % CPU, vyhraje benchmark nad tím, který tě škrtí na zaplacených 200 %. Ten burst je ale půjčený od sousedů a zmizí přesně ve chvíli, kdy je node vytížený, tedy když ho potřebuješ. Raději prodáváme menší číslo, které platí v pátek v 21:00.
Izolace se týká i všeho, co zdroj není. Přihlašovací údaje na server, ne na účet. Zálohy omezené na server, který je vytvořil. Logy, které nemohou uniknout výstup jiného tenanta. Porty, které se přidělují, ne hádají. Každá z těchto věcí je místo, kde zkratka ušetří odpoledne a vytvoří třídu chyb, při které jeden zákazník vidí data jiného. A právě z té třídy chyb se hostingová platforma po stránce reputace nevzpamatuje.
Každý ruční krok se stane tiketem#
Tuhle zásadu bychom pověsili na zeď. Každý krok na cestě zákazníka, který vyžaduje člověka na naší straně, bude ve velkém měřítku tiket. Ne někdy. Pokaždé, násobeno počtem zákazníků, a přijde v nejhorší možný okamžik.
Počty jsou jednoduché a brutální. Krok, který zabere pět minut času personálu a potřebuje ho jedna objednávka z deseti, zní neškodně. Při několika stovkách zákazníků je to částečný úvazek, a to úvazek poskládaný z vyrušení. Hůř, zákazník při tom čeká, takže je to i zdržení, kterého si všimne.
Jak to používat: když se nějaká kategorie tiketů objeví víc než několikrát, není to problém podpory, ale chybějící funkce. Tiket je bug report napsaný někým, kdo nevěděl, že jde o chybu. Běžné vzorce, zhruba v pořadí, v jakém je hostingová platforma potká:
- „Můžete mi otevřít port“ - zákazník potřebuje obrazovku s porty, ne člověka.
- „Můžete obnovit včerejší zálohu“ - zálohy potřebují tlačítko obnovy, které zákazník stiskne sám.
- „Kamarád potřebuje přístup, ale ne k fakturaci“ - potřebuješ subuživatele s granulárními oprávněními.
- „Špatný soubor se nahrál a server nenaběhne“ - potřebuješ správce souborů a konzoli, která ukáže skutečnou chybu.
- „Je to výpadek, nebo to mám jen u sebe“ - potřebuješ status stránku a grafy na každý server.
Ne každý ruční krok jde odstranit. V RE:NODE se herní, aplikační, webové a databázové servery vytvářejí hned po proběhlé platbě, obvykle do minuty, ale VDS se pořád připravuje ručně do 24 hodin. To je záměrný kompromis: celý virtuální stroj s vlastním operačním systémem má víc způsobů, jak se pokazit, než kontejner ze známého image, a objem zatím automatizaci neospravedlňuje. Jde o to udělat ten kompromis vědomě, napsat zpoždění na stránku produktu, aby nikoho nepřekvapilo, a vrátit se k němu, až se čísla změní.
Důsledek: uživatelské rozhraní produktu je vlastně soupis tiketů, které už nedostáváš. Když se dnes díváme na hostingový panel, čteme ho jako seznam věcí, které už tým omrzelo dělat ručně.
RBAC od prvního dne, ne od zákazníka padesát#
Řízení přístupu je funkce, kterou si všichni plánují přidat později, a později je vždycky pozdě. Důvodem není bezpečnostní divadlo. První verze každého panelu modeluje „uživatel vlastní server“ a ve chvíli, kdy server sdílejí dva lidé - herní komunita se třemi správci, agentura a její klient - se ten model rozpadne způsobem, který prosákne do každé tabulky a každé kontroly oprávnění v kódu.
Co udělat první den, i když to rozhraní zatím nezobrazuje:
- Oprávnění je jedno sloveso nad jedním druhem věci: spustit server, číst soubory, zapisovat soubory, vidět fakturaci.
- Role je pojmenovaná množina oprávnění.
- Tým je množina lidí.
- Grant spojuje tým se serverem prostřednictvím role.
K tomuhle modelu RE:NODE dospělo: role drží oprávnění, týmy drží lidi, granty spojují týmy se servery, s pozvánkami odkazem, kódem nebo e-mailem, časově omezeným přístupem a záznamem aktivity na každém serveru. Pro jednoho zákazníka s jedním serverem to vypadá přehnaně složitě. Je to jediný tvar, který přežije kontakt se skutečnými komunitami, kde ten, kdo platí, není ten, kdo restartuje, a ten, kdo restartuje, by neměl umět smazat svět.
Dva detaily znamenají víc, než se zdá. Časově omezený přístup, protože nejběžnější chybou v přístupech není dát někomu příliš, ale zapomenout mu to odebrat. A záznam aktivity, protože když se něco pokazí, první otázka je vždycky „kdo to udělal“, a bez záznamu je odpovědí hádka. Rady pro stranu zákazníka jsou v článku subuživatelé a nejmenší oprávnění.
Stejné pravidlo platí pro personál. Podpora by měla vidět stav serveru, aniž by mohla číst jeho soubory, a nikdo z týmu by neměl potřebovat root heslo nodu k běžné práci. Pokud je přístup personálu vše, nebo nic, bude to vše, pro všechny, navždy.
Monitoring, který budí kvůli správným věcem#
Monitoring, který budí kvůli všemu, tě naučí ho ignorovat. Monitoring, který nebudí kvůli ničemu, je dashboard. Užitečná verze je mezi tím a je to hlavně rozhodnutí, koho vzbudit a kvůli čemu.
Pravidlo, na kterém to stojí: člověk se budí, jen když platí tři věci současně. Zákazníci jsou zasaženi nebo brzy budou, platforma to sama neopraví a čekání do rána to zhorší. Vše ostatní je tiket, graf nebo řádek v logu.
| Signál | Kdo se to dozví | Kdy |
|---|---|---|
| Node nedostupný | Člověk v pohotovosti | Okamžitě |
| Disk nodu se rychle plní | Člověk v pohotovosti | Než se zaplní |
| Selhala záložní úloha | Fronta personálu | Další pracovní hodinu |
| Jeden server padá dokola | Zákazník, pak tiket | Po dosažení prahu |
| Jeden server na 100 % CPU | Nikdo | Funguje, jak se prodává |
Poslední řádek je ten, o kterém se lidé hádají. Zákazníkův server na 100 % svého podílu CPU je pomalý, ne rozbitý, a platforma by kvůli tomu neměla nikoho budit ani ho pozastavovat. Dělá přesně to, co říká omezení. Alert na něj vyrábí šum, který zakrývá signály, na kterých opravdu záleží.
Druhé pravidlo: alertuj na příznak a trend, ne jen na práh. Řekněme, že disk nodu je ve 3:00 ráno na 85 %. To samo o sobě není naléhavé. Pokud o půlnoci byl na 60 %, je to velmi naléhavé. Kontrola rychlosti změny zachytí utíkající log nebo zálohu, která zapomněla mazat staré, dlouho před tím, než by to udělal pevný práh, a nespustí se na nodu, který na 85 % tiše stojí měsíc.
Třetí: každé upozornění má odkaz na runbook, i krátký. Napůl spící mozek nepřemýšlí dobře a upozornění „plní se disk nodu“ plus tři řádky o tom, kam se podívat nejdřív, má větší cenu než krásný dashboard. Obecnější verze je v článku monitoring, který ti něco řekne.
Upozornění, na které nemusí člověk nic dělat, není alert. Je to návyk, který si budujeme: alerty ignorovat.
Zálohy jsou funkce produktu, ne práce pro provoz#
Většina platforem bere zálohy jako něco, co provoz tiše dělá na pozadí. Pro hostingovou firmu je to podle nás špatně, protože záloha, kterou zákazník nevidí, je záloha, které zákazník nevěří, a záloha, kterou si zákazník nemůže obnovit sám, se v nejhorší možnou chvíli změní v tiket.
Ve skutečnosti jsou to dva záložní systémy s různou úlohou:
- Zálohy platformy chrání byznys: noční, kopírované na oddělený hardware, ověřované, mazané podle plánu. Zákazníci se jich nedotknou. Existují pro den, kdy node zemře.
- Zálohy zákazníka chrání zákazníka před ním samým: sloty v každém tarifu, vytvářené na požádání nebo podle plánu, obnovované tlačítkem, stažitelné, uzamykatelné proti rotaci a uložené mimo stroj, který chrání.
Ten, který vidí zákazník, mění objem podpory. Většina ztrát dat na hostingové platformě není selhání hardwaru. Je to zákazník, který nainstaluje plugin, jenž sežere svět, smaže špatnou složku nebo upgraduje verzi hry, která neumí číst starý save. Tlačítko obnovy, které zákazník o půlnoci stiskne, aniž by se kohokoli ptal, má větší cenu než jakákoli redundance na naší straně.
Dvě designová rozhodnutí stojí za zopakování. Zamykání: možnost připnout jednu zálohu, aby ji rotace nikdy nesmazala, protože záloha, kterou chceš, je často ta před začátkem problému, tedy přesně ta, kterou se rotace chystá odstranit. A poctivé mazání: v RE:NODE smazání serveru smaže i jeho zálohy, i zamčené. Některé lidi to překvapí, ale záloha, která přežije server, ke kterému patří, jsou data držená bez důvodu, a mělo by se to říct jasně, ne nechat objevit.
Zásada pod tím je domácí průpovídka: záloha, kterou nikdo neobnovil, je hypotéza. Ověřování musí být automatické, protože člověk, který kontroluje obnovy ručně, s tím přestane týden, kdy má plno. Mechaniku rozebírají články zálohy, které opravdu fungují a vyzkoušej obnovu dřív, než ji potřebuješ.
Reakce na incident je hlavně příprava#
Samotný incident je nejmenší částí reakce na incident. Části, které rozhodují o tom, jak dopadne, se odehrávají týdny předem: jestli umíš říct, kterých zákazníků se to týká, jestli jim to umíš rychle sdělit a jestli se potom dá zjistit, co se vlastně stalo.
Na čem trváme u každé platformy této velikosti:
- Cesta od „node X není zdravý“ k „tito zákazníci jsou zasaženi“ jedním dotazem. Pokud k tomu je potřeba tabulka, bude zpráva o stavu pozdní a mlhavá.
- Status stránka, kterou během incidentu aktualizuje člověk a jindy systém, hostovaná někde, kde nesdílí osud s tím, o čem informuje.
- Každá automatická akce zapsaná do logu událostí s tím, co, kdy, proč a která komponenta ji provedla. Když smyčka obnovy něco restartuje, musí být ten restart za týden vysvětlitelný.
- Krátké písemné zhodnocení po všem, čeho si zákazníci všimli, zaměřené na to, co systém dovolil, aby se stalo, ne na to, kdo co zmáčkl.
Poslední bod je spíš o kultuře než o nástrojích. Pokud zhodnocení hledá viníka, lidé přestanou hlásit téměř-nehody, a téměř-nehody jsou jediné lekce zdarma.
Co udělat jinak#
Při novém startu platformy zítra, s dnešními znalostmi, by to byly tyto změny. Žádná není dramatická. Všechny jsou první den levnější než tisící den.
Požadovaný stav od prvního commitu
O tomhle byla řeč výš, ale je to ta největší změna. Každý krok zřizování napsaný jako skript je budoucí migrační projekt. Od začátku patří do systému jedna reconciliation smyčka a vytváření, změna i obnova vedou stejnou cestou kódu.
Jedno místo pro limity a kvóty
Limity se rozprostřou: paměť v definici kontejneru, disk v nástroji kvót, sloty záloh v systému fakturace, porty v tabulce přidělení. Každý je sám o sobě správně a dohromady se rozcházejí. Všechny limity tarifu patří do jednoho záznamu, který čtou všechny komponenty, takže změna tarifu je jeden zápis, ne pět.
Log událostí jako plnohodnotný produkt
Audit a log událostí se staví dřív než dashboard. Čte ho podpora, ukazuje ho zákazníkův přehled aktivity, závisí na něm zhodnocení incidentů a je potřeba pro jakoukoli otázku souladu s předpisy. Dodatečné doplnění znamená hádat historii, kterou jsi nezaznamenal.
Lokace jako data, ne jako předpoklad
I platforma, která běží na jednom místě, by to neměla předpokládat v kódu. Lokace se od začátku modeluje jako vlastnost nodu a serveru, aby přidání druhé bylo změnou konfigurace, ne přepisem. Ne proto, že se druhá plánuje, ale proto, že pevně zakódované předpoklady jsou ty drahé.
Zkoušej cestu obnovy podle plánu
Kód obnovy je kód, který běží nejméně a záleží na něm nejvíc, což je špatná kombinace. Testovací server se podle plánu záměrně rozbíjí - zastaví se jeho proces, zaplní disk, poškodí konfigurace - a kontroluje se, že platforma si toho všimne a udělá správnou věc, stejně jako se mají podle plánu zkoušet obnovy záloh. Pokud obnova běží jen při skutečných selháních, testuje se jen při skutečných selháních.
Co nechat přesně tak, jak to je
Přísné limity zdrojů. Watcher, který eskaluje, místo aby restartoval donekonečna. Zálohy ovládané zákazníkem. Granulární role. Panel, který ukazuje skutečný výstup konzole, ne přívětivé shrnutí. Každé z toho dělalo platformu první den méně štědrou a ušetřilo mnohem víc, než stálo.
Za tím vším stojí jeden návyk: navrhovat nejdřív pro selhání. Platí to i tehdy, když velkou část kódu píší AI coding agenti: agent napíše cestu vytváření za odpoledne a cesta obnovy je pořád ta část, nad kterou musí člověk usilovně přemýšlet.
FAQ#
Co je nejtěžší na provozu multi-tenant hostingové platformy?
Spravedlnost pod zátěží. Vytvářet servery je snadné; zajistit, aby se špatný den jednoho tenanta nestal špatným dnem všech, vyžaduje tvrdé limity CPU, paměti a disku a ochotu vypadat méně štědře než hostingy, které nechají zákazníky půjčovat si od sousedů.
Má malý hosting automatizovat nejdřív zřizování, nebo obnovu?
Obnovu. Zřizování proběhne jednou na server a pomalá ruční verze stojí minuty. Obnova běží pokaždé, když se něco rozbije, většinou v noci, a ruční verze stojí tvůj spánek a důvěru zákazníků. Než zrychlíš tlačítko objednávky, zajisti, aby platforma uměla problém zjistit, zopakovat akci a eskalovat.
Vyplatí se RBAC u platformy jen s pár zákazníky?
Ano, alespoň v datovém modelu. Dodatečné přidání sdíleného přístupu k návrhu „jeden uživatel vlastní jeden server“ se dotkne každé kontroly oprávnění v kódu. Role a týmy můžeš v rozhraní skrývat, dokud je zákazníci nebudou chtít, ale tabulky by měly existovat od začátku.
Kolik upozornění má budit člověka?
Velmi málo. Budit jen tehdy, když jsou zákazníci zasaženi nebo brzy budou, systém to sám nevyřeší a čekání to zhorší. Výpadek nodu a rychle se plnící disk to splňují. Selhání zálohy je ranní tiket. Jeden server na plném CPU není alert vůbec.
Proč server na limitu paměti zastavit, místo aby swapoval?
Protože swap na sdíleném hardwaru promění paměťový problém jednoho tenanta v diskový problém všech. Čistý restart je viditelný a zákazník ho umí vyřešit; node, který potichu trhá disk, postihuje lidi, kteří neudělali nic špatně, a je mnohem těžší ho diagnostikovat.


