Jak Roští dostalo Let’s encrypt

Máme za sebou víkend s velkým V. Poslední dva měsíce jsme strávili vývojem a máme hromadu novinek, které se během minulého víkendu sešly do jedné větve a nakonec se dostaly i do produkce. Některé vlastnosti ještě nejsou aktivované, protože bychom asi nespali vůbec, ale přijde i na ně.

Nejlépe bych dění shrnul asi následujícím seznamem:

  • Let’s encrypt
  • Automatické nabíhání
  • Podpora více lokalit
  • Vylepšení vývojového prostředí
  • Quoty
  • Vylepšená validace DNS záznamů
  • Nový Docker (1.12.2)
  • Nová verze Docker API (1.24)
  • Přišli jsme na to, proč byl pomalý řadič

Změn bylo hodně, u některých jsme počítaly s problémy, ale u žádné s tak velkými. Nedostupnost nebyla úplně malá, ale podařilo se nám ji udržet mezi přibližně jednou a sedmou hodinou ranní, což nám doufám odpustíte, protože odměna za to fakt stojí. Sobotní výpadek mezi 3:00 a 7:00 byl způsobem řadičem a nepočítali jsme s ním. Nicméně se nám podařilo vyřešit i to. Ale pojďme na to postupně.

Let’s encrypt

LE se stávalo takovou naší Nemesis. Celkem jsme ho implementovali třikrát. Ne že by se minimálně druhý pokus nepovedl, ale výsledek byl takový, že bychom ho do produkčního prostředí nedostali. Měli jsme to spojené s provázáním domén u aplikací s DNS zónou, což se ukázalo tak komplikované, že jsme nakonec od nasazení upustili. Několik desítek hodin práce tak vylétlo komínem. O prvním pokusu raději ani nebudu mluvit, byl to výstřel do tmy a nesedlo by to.

Nakonec jsme vyvinuli vlastního daemona, který konfiguruje Nginx tak, aby se choval jako reverzní proxy a stará se o získávání certifikátů. Je napsaný v Go. Vybrali jsme Go spíše jako pokus, ale výsledek je ohromující. Daemon má REST API, které si poradí se stovkami konkurenčních požadavků, aniž by se to nějak významně projevilo na CPU.

Let’s encrypt si můžete zkusit u své aplikace v záložce parametry, kde se dá zapnout. Musíte mít doménu nasměrovanou na náš hlavní load balancer, což jsou záznamy:

Na starém load balanceru to fungovat nebude. U LE přepínače je k tomu velké varování. Také nebudou fungovat wildcard domény, protože je LE nepodporuje. Takové domény zůstanou automaticky na HTTP a ostatní pojedou přes HTTPS.

Hned v prvních dnech jsme narazili na limit dvaceti subdomén k jedné doméně druhého řádu. S tím nic neuděláme, takže subdomény pod rostiapp.cz mohou získávat certifikát i několik týdnů. Mezitím pojedou všechny na HTTP jak jste byli zvyklí.

Automatické nabíhání

Během posledních pár měsíců jsme měli problémy s výpadky napájení. Když už došlo k restartu serveru, nemohli jsme nahodit kontejnery hned a už vůbec nemohly naběhnout sami, protože se load balancer připojuje na jejich interní IP adresy. Ty se s každým startem mění, takže jsme to museli řešit přes administraci a to chvilku trvalo.

Kvůli tomu se také stávalo, že se na chvilku a nebo v případě nějaké chyby i na delší dobu, objevila na doméně A aplikace z domény B. Minimalizovali jsme to procesními změnami, ale teď už je takové chování velmi nepravděpodobné.

Nyní když naběhne server, automaticky se nastartují i všechny kontejnery s pevně danou konfigurací (ta se dřív dynamicky měnila). I díky novému Dockeru, který už umí pracovat s více kontejnery najednou, se tak výpadek služeb během restartu zmenší z řádově desítek minut na minuty.

Doufáme, že neplánované výpadky už nebudeme mít, ale naštěstí nám tato vlastnost pomůže i při těch plánovaných.

Podpora více lokalit

Problémy se servery v posledních měsících nás vedly k tomu, že bychom se mohli porozhlédnout po nějaké cloudové službě a provozovat Roští tam. K tomu potřebujeme, aby administrace párovala server s aplikací a databázový server tak, aby byly u sebe. Nemusí to být úplně stejný server, ale mělo by to být stejné datacentrum. To znamená, že když aplikace poběží v Německu, tak nesmí používat databázi v Česku a podobně.

Nová verze administrace tuto vlastnost má a tak můžeme začít testovat různé cloudové služby a nakonec snad jednu či dvě vybrat.

Ideálně bychom se chtěli dostat do stavu, aby případné problémy nepostihly 50 % služeb, jako tomu je často teď, ale třeba jen 5 nebo 10 %.

Vylepšení vývojového prostředí

Na vývoj používáme Vagrant a jeho konfiguraci jsme řešili skriptem. Teď jsme přešli na Ansible a sestavení vývojového prostředí je díky tomu stabilnější a spolehlivější. Můžeme teď také začít pracovat na integračních testech a stagingu. Administrace je už docela velká a tahle změna nám hodně pomůže.

Staging prostčedí se subsetem produkčních dat by nám měl pomoci minimalizovat problémy, které máme při nasazování nových vlastností. Bohužel to na Roští není tak jednoduché jako u jiných projektů, protože administrace ovládá spoustu serverů a zrcadlení celého stacku je nákladné finančně i časově. Musíme najít tedy nějaký kompromis.

Quoty

Moc jsme o tom nemluvili, ale když jsme přišli o souborový systém Btrfs, přišli jsme i o možnost quote, tedy omezení diskového prostoru pro jednotlivé aplikace. Nechávali jsme to tedy být, ale občas nám to způsobilo nějaké problémy, třeba když jedna aplikace začala vytvářet velké množství obrázků v /tmp a zaplnila celý disk.

Implementace není snadná a ani naše řešení není čisté, protože linuxové quoty jsou vázané na UID a GID procesu a naše kontejnery používají obě čísla stejná, takže tudy cesta nevedla. Druhou možností je Btrfs, přece jen za ty dva pokročilo, ale quoty tam pořád ještě nejsou stabilní a nemáme na to zatím odvahu.

Tak nakonec vytváříme každé aplikaci image s filesystémem a mountujeme ho na místo, kde kontejner očekává data. Nevýhodou je, že s quotami nejde jít dolů, ale jen nahoru. I tak myslíme, že to je lepší řešení než žádné.

Tato vlastnost ještě není zapnutá, ale během pár dnů bude.

Vylepšená validace DNS záznamů

Občas se stávalo, že uživatel udělal chybu při zadávání záznamů v DNS zóně a to vedlo k problému v konfiguraci Bindu a doména zmizela z DNS po přibližně dvou týdnech. Problém je samozřejmě v naší administraci, kde jsme měli chyby ve validaci. Nová verze administrace validaci vylepšila a toto se už nebude stávat. Vycházeli jsme z chyb, se kterými jsme se v posledních pár měsících uživatelé setkali.

Nový Docker (1.12.2) a Docker API (1.24)

Nejstarší server pluto.rosti.cz ještě běžel na Dockeru 1.8 a ostatní servery také byly trochu pozadu, takže jsme aktualizovali na verze 1.12. S tím jsme změnily i verzi API, se kterou komunikuje administrace s Dockerem a to na 1.24. Nejdůležitější změnou pro vás je rychlost startu kontejnerů, protože Docker od verze 1.11 umí pracovat s kontejnery paralelně a je možné spustit stovky kontejnerů během několika sekund.

Přišli jsme na to, proč byl pomalý řadič

Minulý týden v sobotu jsme narazili na novém poli s RAID 5 na problém. Server se začal kolem třetí hodiny ranní chovat neuvěřitelně pomalu a skončilo to vesměs samovolně někdy kolem deváté hodiny ráno. Netušili jsme o co jde a asi si dokážete představit, jak nám bylo. Problém se teď opakoval a naštěstí jsme byli vzhůru a nakonec ho identifikovali. šlo o Patrol Read, funkci, která kontroluje zda v poli nejsou nějaké problémy. Díky tomu může řadič včas odstranit vadný disk.

Patrol Read bylo nastaveno na 30 % zatížení disků, ale u disků je taková hodnota dost imaginární, takže i toto číslo sestřelilo kompletně výkon IO operací. Po nastavení na 2 % se všechno uklidnilo a tento týden už to bylo v pořádku.

A co bude dál

Během prvních pár dní v tomto týdnu se objevil problém, který nás mrzí. Nasazovaly jsme třeba nový PHP image s minoritní opravou composeru, což vedlo k neočekávanému výsledku, kdy v imagi nebylo rozšíření mbsting. Snažíme se problémy vychytat procesními změnami, ale i tak občas narazíme na něco nového. V tomto případě šlo o lidskou chybu. Necommitnul jsem změny v imagích do gitu a když Martin dělal ten malý fix, tak se tam moje změny nedostaly.

V dalších týdnech se zaměříme na zmíněný Cloud, emaily a DDOS útoky, ke kterým ještě vydáme jeden blogpost, protože to je komplikovaná oblast. Taky se chystáme zapnout v současné době vypnuté quoty. Mezitím bychom ještě rádi upravili naši homepage a změnili ceník tak, aby byl čitelnější. K ceníku také přidáme speciální blogpost.

Byl to náročný víkend i týden. Nejlépe to asi zprostředkuje tento tweet:

Držte nám palce a pokud narazíte na chybu, tak nám napište.

Let’s encrypt už brzy

Špatných zpráv bylo za poslední týden víc než jsme zvyklí a tak trochu odlehčím atmosféru. Před 14 dny jsme dokončili kód, který umožní spustit podporu Let’s encrypt na Roští. Zmiňoval jsem to i dřív, ale raději ještě jednou napíši: Museli jsme kompletně přepsat způsob, jakým jsou domény u aplikací uloženy. A co z toho plyne? Čeká nás masivní migrace.

V současné době jsou domény u aplikací uloženy ve velkém text fieldu a oddělené mezerou nebo novým řádkem. Systém s tím doposud nějak pracoval, ale určitě vás napadne, že spravovat tímto způsobem domény je nepohodlné. Nejvážnější problém jsou oprávnění. Tedy že subdomény z jedné domény druhého řádu je možné používat mezi více účty. Kontrola tohoto stavu je v současné době obalena hromadou kódu, který není nutný, protože ho může pohlídat databáze. A to je také to, oč jsme se snažili.

V nové verzi administraci bude mít každá doména druhého řádu zónu a v ní subdomény a tyto subdomény budou přiřazeny aplikacím. Pokud budete chtít použít u aplikace jen doménu třetího řádu, tak to samozřejmě nevadí, ale zónu pro celou doménu vám stejně vytvoříme. Není nějak povinné ji používat, ale je lepší, když na ní svoji doménu u registrátora namíříte.

Nicméně, tímto krokem získáme záznam v databázi pro každou doménu/subdoménu a můžeme k němu ukládat i další věci jako třeba informaci, že má být s SSL certifikátem nebo že pro ni máme získat certifikát ze služby Let’s encrypt.

A to je důvod, proč to tak dlouho trvá a ještě chvilku trvat bude. Migrace, kterou chystáme nebude snadná, nebude bez problémů a nebude hotová během pár minut. Musíme se na ní připravit, upravit naše vývojové prostředí a všechno pořádně otestovat. Všechno by se mělo rozjet příští týden ve čtvrtek a pokud to půjde dobře, další týden už bude možné aktivovat Let’s encrypt u vašich domén.

Kromě toho budeme schopni začít s implementací registrace domén, ale ještě předtím se chceme věnovat nové funkci „Služby“, která vrátí MongoDB tam kam patří, do naší administrace.

Domény a MongoDB

Máme za sebou další PoSobotu a tak je možná čas se podívat trochu zpátky. Poslední měsíc řešíme dva problémy a to je MongoDB a správu domén. Obojí se nám trochu protahuje, takže vám alespoň zkusím nastínit, kde je problém.

MongoDB nám udělala čáru přes rozpočet, když nám ztratila informace s několika přístupy. Data zůstala netknuta, ale uživatelé se k nim nedostali. Rozhodli jsme se kvůli tomuto incidentu podporu pro MongoDB na chvilku vyhodit z administrace. Pokud MongoDB potřebujete, napište nám na podporu, databázi vám samozřejmě dáme.

Abychom mohli MongoDB vrátit zpátky do administrace, musíme udělat jednu důležitou změnu a to vytvořit službu, kterou pracovně nazýváme „services“. Bude to další sekce v administraci pod aplikacemi, kde ale nebudou vaše skripty s HTTP výstupem, ale budou tam databáze, alespoň tedy ze začátku hlavně databáze.

Když se to podaří, budete si moci vytvořit vlastní instanci MySQL, PostgreSQL, ElasticSearch a MongoDB, které budou společné pro všechny vaše aplikace. Všechno bude samozřejmě připravené k použití, ale pokud máte nějaké speciální požadavky na konfiguraci, s touto službou je budete moci realizovat. Cena kontejnerů s databázemi bude stejná jako s aplikacemi. Bude tedy záležet jen na vaší aplikaci, kolik toho bude potřebovat.

S tímhle budeme mít ještě dost práce, takže nebudu říkat, že to za 14 dní bude, ale tohle je naše priorita číslo jedna hned po doménách.

Domény jsou momentálně naše největší bolest, protože jsou uloženy v databázi dost nesystémově, což nám v současnosti komplikuje implementaci SSL certifikátů přes Let’s Encrypt a další služby, které jedna za druhou implementují své API. Podporu pro domény jsme měli už dvakrát napsanou, ale nemůžeme se shodnout, jak to nakonec má být, takže oboje implementace jsme hodili do koše.

A tak jako všechny dobré věci, i tahle se nakonec vyřeší náhodou. Pustili jsme se do mikroservicy s REST API, která bude spravovat naše load balancery. Díky tomu dostaneme z administrace opravdu hodně kódu a přesuneme starosti s SSL úplně mimo ni, což nám nakonec pomůže propojit domény v aplikacích, DNS a poště tak, abychom zajistili bezpečnost i čistý design.

První dvě zahozené implementace sice fungovaly, ale při testování jsme v nich našli chyby, které bychom do produkce poslat nemohli a navíc by nás stálo strašně moc času je vyřešit. Napotřetí to tedy snad vyjde. Nechceme slibovat termíny ale už nadcházející víkend budeme snad vědět, zda to bude za 14 dní nebo někdy později.

A tak pokračujeme dál, držte nám palce a na další PoSobotě snad už s podporou SSL.

PHP 7.0 je tu a k němu nový server

Dlouho jsme na blog nic nepsali, ale teď se nám podařilo dokončit něco, co stojí za zmínku. Nasadili jsme stabilní PHP 7.0, které už se nemusíte bát používat produkčně. Kromě toho máme nový server a také jste si mohli všimnout změn při placení. Ale teď postupně.

Mezi obrazy máme PHP 7.0 už nějaký čas, ale uživatelům jsme ho nedoporučovali. Čekali jsme na podporu ze strany komunitního repositáře Dotdeb, který nám PHP 7.0 naservíroval do Debianu a my se mohli soustředit „jen“ na integraci do našeho prostředí. Dělali jsme dříve nějaké pokusy s vlastními buildy PHP, ale Dotdeb má celý proces odladěný a není důvod této práce nevyužít.

S PHP 7.0 jsme se rozhodli změnit jednu věc – už nepoužíváme Apache, ale Nginx + PHP-FPM. Proti Apachi nic nemáme, ale mod_php pouvažujeme za špatný koncept. Jedinou velkou překážkou by mohla být podpora pro .htaccess, která je bez Apache samozřejmě pryč. Nicméně u nás máte plnou kontrolu nad web serverem a jeho konfigurací, takže pokud .htaccess opravdu potřebujete, tak použijte nástroj na převedení .htaccess do konfigurace Nginxu na winginx.com a váš kód bude opět fungovat a navíc rychleji. Je to dáno tím Apache se zapnutou podporou .htaccess s každým requestem testuje přítomnost .htaccess v aktuálním adresáři i nadřazených adresářích a pokud na nějaký narazí, tak ho zpracuje. Tato operace se nedá cachovat, protože by pak Apache nereagoval na změny v těchto souborech.

Během ledna jsme pořídili nový server, nainstalovali a umístili do racku. Pár týdnů se zdánlivě nic nedělo, ale to není tak úplně přesné, protože jsme do administrace dodělávali podporu pro více serverů. Ta tam byla již od začátku, ale až s novým serverem jsme tuto funkci začali testovat a nakonec dostali až do produkce. Nová administrace má teď k dispozici tři web servery a na nich spoustu místa pro nové aplikace. Aplikace založené v posledních 14 dnech tedy už běží na novém, rychlejším hardwaru.

Abych nezapomněl, už u nás můžete platit kartou. Od začátku jsme pracovali na vlastním fakturačním systému, který jsme měli ještě před založením Roští a bylo nám líto ho nevyužít. A tak jsme se v lednu s Martinem bavili o Fakturoidu, že by mohl mít pro Roští docela pozitivní přínos a také bychom se zbavili jednoho systému, o který se musíme starat.

Netrvalo to moc dlouho a pustili jsme se do implementace. Úpravy kódu zabraly jen pár hodin, za to migrace dat a ladění celého platebního workflow nás stálo 4 dny. Ale vyplatilo se. Máme platbu kartou, nemusíme se starat o fakturaci, účetní si exportuje data, která potřebuje a účetně jsme otevřeli Roští platbám z celého světa a hlavně z docela komplikované Evropy.

Koncem roku jsme se také stali plátci DPH. Bohužel jsme kvůli tomu museli mírně zvednout ceny. Na druhou stranu nám to pootevřelo dveře k větším klientům.

A co budeme dělat dál? Určitě domény. Už máme hotový kód, který z domén dělá záznam v databázi, což je klíčové pro mnoho věcí. Částečně jsme implementovali podporu pro SSL certifikáty k těmto doménám a se slinou v koutku už koukáme na Let’s encrypt, které nám ale spoustu věcí úplně neulehčuje, třeba limitem kolik certifikátů můžeme stáhnout za hodinu a za den. Kromě certifikátů se nám konečně otevře cesta k registraci domén. Nechci slibovat nějaké termíny, ale doufám, že příště vám už budu psát o tom, jak implementujeme API nějakého registrátora.

Druhá věc, kterou máme v plánu, je naše API. K němu máme napsáno jen velmi málo. Máme dokumentaci, kterou zatím upravujeme a diskutujeme nad tím, co má být vlastně cílem, k čemu ho budeme používat my a k čemu naši uživatelé, ale už nejsme daleko od skutečné implementace. Opět nebudu slibovat termíny, ale slíbím vám API, přes které budete moct přidávat, upravovat, mazat a monitorovat aplikace. Stejně jako domény, tak API vyžaduje nějaký refactoring v naší administraci. Část logiky dnes máme na místech, kde ji úplně nechceme a než se pustíme do API, musí být tato část vyřešena.

A to je zatím vše. Pracujeme na Roští každý den a jsme rádi, že se vám líbí. Víme to, protože za poslední tři měsíce jsme vyrostli dvakrát. Děkujeme, že jste s námi a že díky vám můžeme posunovat hosting v České Republice za hranice FTP a PHP.

Velká várka oprav

Máme za sebou více jak dva měsíce provozu nové administrace a tak jsme se pustili do nějakého opravování. Něco už je nasazené, něco bude. Ale začneme od začátku.

Minulý týden jsme se byli podívat na LinuxDays a říct vám něco o Dockeru na webhostingu. Rozhodli jsme se to pojmout propagačně a zaměřit se na pokročilejší uživatele, kteří už o Dockeru něco vědí. Přednášel jsem já a moji nervozitu prosím přehlédněte 🙂

A teď už k opravám. Možná jste postřehli, že příkaz „enable-redis„, který vám nakonfiguruje v kontejneru Redis databázi, nefungoval. Používal konfiguraci s chybami a navíc pro jinou verzi Redisu. Naše chyba, málo jsme tuhle vlastnost otestovali, teď už to je opravené.

Měli jsme problém s tím, že se nám na serverech začali množit kontejnery, ke kterým nepatřila žádná appka. Ukázalo se, že někdy v minulosti došlo k výpadku RQ workera pro jednu z našich front, což vedlo k tomu, že se nějaký čas tato chyba projevovala. Důsledky jsme identifikovali a odstranili až nyní. Píši to jen pro zajímavost, protože uživatele to nějak neovlivnilo.

Další problém byl způsobem chováním Dockeru, které popisuji i v přednášce nahoře – mění se chování Docker API. I když používáme stále verzi API 1.18, tak s aktualizací na Docker 1.8.2 došlo k odstranění cpuShare parametru z volání API, které vytváří kontejner. Změnu chápu, ale že se to promítlo i do starších verzí API, to už méně. Výsledek byl nefunkční přepínač „High CPU“ v administraci. Naštěstí byla oprava jednoduchá a nasadili jsme ji rychle.

Další chyba byla logická a týkala se hlášky o tom, že je kontejner v chybovém stavu. Ta se má zobrazit 60 sekund poté, co nebyl kontejner vytvořen, i když o to uživatel skrze administraci požádal. Při rozhodování jestli hlášku zobrazit nebo ne, jsme používali datum vytvoření kontejneru a aktuální čas, takže při změně parametrů se objevila hned, jak se spustil task s vytvořením na pozadí.

Na přání jednoho z uživatelů jsme upravili PHP kontejner tak, aby obsahoval modul pro MongoDB. Z PHP je tedy nyní možné přistupovat do Monga.

PHP image jsme také trochu překopali. Nyní už podporujeme jen verze 5.6 a nově 7.0. Starší aplikace mohou zůstat na současných imagích. Nové už musí použít tyto. Pokud budete chtít starší verzi i k nové aplikaci, napište nám prosím na podporu. V současné době je využití starších verzí opravdu minimální. PHP 7.0 ještě nepoužívejte v produkci, máme ji jen pro otestování. Chybí ji většina modulů, například GD.

Dále jsme na homepage upravili stránku s ceníkem tak, aby vás méně mátla. Ujasnili jsme cenu za zálohování a za certifikáty.

Na starém Roští se objevil problém s placením přes GoPay. Došlo k nějakým úpravám API na straně GoPay, o kterých nám zapomněli říct 🙁 Podpora pro GoPay v novém Roští je na cestě, ale ještě pořád máme před sebou nějaké důležitější tasky. Snad se tedy dočkáte v listopadu.

U PHP kontejnerů se při přesměrování objevil problém, kdy Apache přidával port 8000 do URL adresy a stránka pak nefungovala. Trápilo nás to dlouho, ale konečně jsme to vyřešili. Už se tedy tohoto bugu nemusíte bát.

A to je všechno. Většina oprav už je nasazena, další se objeví během zítřka. Děkujeme za podporu a budeme se těšit u dalšího reportu.