Ahoj všichni! Jmenuji se Kirill a jsem CTO ve společnosti Adapty. Většina naší architektury je na AWS a dnes budu hovořit o tom, jak jsme pomocí spotových instancí v produkčním prostředí snížili náklady na servery třikrát, a také jak nastavit jejich automatické škálování. Nejprve bude přehled, jak to funguje, a poté podrobný návod, jak začít.
Co jsou to Spot instance?
Níže je několik snímků obrazovky, které ukazují historii cen pro spotové instance.
m5.velké v regionu eu-západ-1 (Irsko). Cena je většinou stabilní po dobu 3 měsíců, aktuálně úspora 2.9x.
m5.velký v regionu us-východ-1 (Severní Virginie). Cena se v průběhu 3 měsíců neustále mění, aktuálně šetří od 2.3x do 2.8x v závislosti na zóně dostupnosti.
t3.small v regionu us-východ-1 (Severní Virginie). Cena je stabilní 3 měsíce, aktuálně 3.4x úspora.
Architektura služeb
Základní architektura služby, o které budeme hovořit v tomto článku, je znázorněna na obrázku níže.
Application Load Balancer → EC2 Target Group → Elastic Container Service
Application Load Balancer (ALB) se používá jako balancer, který odesílá požadavky cílové skupině EC2 (TG). TG je zodpovědná za otevírání portů na instancích pro ALB a jejich připojení k portům kontejnerů Elastic Container Service (ECS). ECS je analogem Kubernetes v AWS, který spravuje kontejnery Docker.
Jedna instance může mít několik spuštěných kontejnerů se stejnými porty, takže je nemůžeme nastavit pevně. ECS sdělí TG, že spouští novou úlohu (v terminologii Kubernetes se tomu říká pod), zkontroluje volné porty na instanci a přiřadí jeden z nich ke spuštěné úloze. TG také pravidelně kontroluje, zda na ní instance a API pracuje pomocí kontroly stavu, a pokud vidí nějaké problémy, přestane tam posílat požadavky.
Skupiny automatického škálování EC2 + poskytovatelé kapacity ECS
Výše uvedený diagram nezobrazuje službu EC2 Auto Scaling Groups (ASG). Z názvu můžete pochopit, že je zodpovědný za škálování instancí. Donedávna však AWS nemělo zabudovanou schopnost spravovat počet běžících strojů z ECS. ECS umožnilo škálovat počet úloh například pomocí CPU, RAM nebo počtu požadavků. Pokud však úlohy obsadily všechny volné instance, nové stroje se automaticky nevytvářely.
To se změnilo s příchodem poskytovatelů kapacit ECS (ECS CP). Nyní může být každá služba v ECS přidružena k ASG, a pokud se úkoly nevejdou na běžící instance, budou vyvolány nové (ale v rámci stanovených limitů ASG). Funguje to i v opačném směru, pokud ECS CP vidí nečinné instance bez úloh, vydá příkaz ASG k jejich vypnutí. ECS CP má schopnost specifikovat cílové procento zatížení instance, takže určitý počet strojů je vždy volný pro úlohy rychlého škálování; o tom budu mluvit o něco později.
Spouštěcí šablony EC2
Poslední službou, o které budu hovořit, než se budu podrobně věnovat vytváření této infrastruktury, jsou EC2 Launch Templates. Umožňuje vytvořit šablonu, podle které se spustí všechny stroje, aby se to neopakovalo pokaždé od začátku. Zde můžete vybrat typ počítače, který se má spustit, bezpečnostní skupinu, obraz disku a mnoho dalších parametrů. Můžete také zadat uživatelská data, která budou nahrána do všech spuštěných instancí. V uživatelských datech můžete spouštět skripty, můžete například upravovat obsah souboru
Jedním z nejdůležitějších konfiguračních parametrů pro tento článek je
Ohledně disku - AWS nedávno
Vytvoření služby
Přejděme k vytvoření popsané služby. V tomto procesu dodatečně popíšu několik užitečných bodů, které nebyly zmíněny výše. Obecně se jedná o návod krok za krokem, ale nebudu uvažovat o některých zcela základních nebo naopak zcela konkrétních případech. Všechny akce se provádějí ve vizuální konzoli AWS, ale lze je reprodukovat programově pomocí CloudFormation nebo Terraform. V Adapty používáme Terraform.
Spouštěcí šablona EC2
Tato služba vytvoří konfiguraci strojů, které budou použity. Šablony se spravují v sekci EC2 -> Instance -> Launch templates.
Obraz stroje Amazon (AMI) — zadejte obraz disku, se kterým se budou spouštět všechny instance. Pro ECS se ve většině případů vyplatí použít optimalizovaný obrázek od Amazonu. Je pravidelně aktualizován a obsahuje vše potřebné pro fungování ECS. Chcete-li zjistit aktuální ID obrázku, přejděte na stránku
Typ instance — uveďte typ instance. Vyberte si ten, který nejlépe vyhovuje vašemu úkolu.
Klíčový pár (přihlášení) — zadejte certifikát, pomocí kterého se můžete v případě potřeby připojit k instanci přes SSH.
Nastavení sítě — zadejte parametry sítě. Síťová platforma ve většině případů by měl existovat virtuální privátní cloud (VPC). Skupiny zabezpečení — skupiny zabezpečení pro vaše instance. Vzhledem k tomu, že budeme používat balancer před instancemi, doporučuji zde specifikovat skupinu, která povoluje příchozí spojení pouze z balanceru. To znamená, že budete mít 2 skupiny zabezpečení, jednu pro balancer, která umožňuje příchozí připojení odkudkoli na portech 80 (http) a 443 (https), a druhou pro počítače, která umožňuje příchozí připojení na libovolných portech ze skupiny balancerů. . Odchozí spojení v obou skupinách musí být navázáno protokolem TCP na všechny porty na všechny adresy. Můžete omezit porty a adresy pro odchozí připojení, ale pak je potřeba neustále sledovat, že se nesnažíte k něčemu přistupovat na uzavřeném portu.
Úložiště (svazky) — zadejte parametry disku pro počítače. Velikost disku nemůže být menší, než je uvedeno v AMI, pro ECS Optimized je to 30 GiB.
Pokročilé detaily — zadejte další parametry.
Možnost nákupu — zda chceme nakupovat spotové instance. Chceme, ale toto políčko zde nezaškrtneme; nakonfigurujeme jej ve skupině Auto Scaling, tam je více možností.
Profil instance IAM — uveďte roli, se kterou budou instance spouštěny. Aby instance běžely v ECS, potřebují oprávnění, která se obvykle nacházejí v roli ecsInstanceRole. V některých případech jej lze vytvořit, pokud ne, pak zde
Dále je zde mnoho parametrů, v podstatě můžete všude ponechat výchozí hodnoty, ale každý z nich má jasný popis. Vždy povoluji instanci optimalizovanou EBS a možnosti T2/T3 Unlimited, pokud jsou použity
Uživatel čas — uveďte uživatelská data. Soubor upravíme /etc/ecs/ecs.config
, který obsahuje konfiguraci agenta ECS.
Příklad toho, jak mohou vypadat uživatelská data:
#!/bin/bash
echo ECS_CLUSTER=DemoApiClusterProd >> /etc/ecs/ecs.config
echo ECS_ENABLE_SPOT_INSTANCE_DRAINING=true >> /etc/ecs/ecs.config
echo ECS_CONTAINER_STOP_TIMEOUT=1m >> /etc/ecs/ecs.config
echo ECS_ENGINE_AUTH_TYPE=docker >> /etc/ecs/ecs.config
echo "ECS_ENGINE_AUTH_DATA={"registry.gitlab.com":{"username":"username","password":"password"}}" >> /etc/ecs/ecs.config
ECS_CLUSTER=DemoApiClusterProd
— parametr označuje, že instance patří do clusteru s daným názvem, to znamená, že tento cluster bude moci umístit své úlohy na tento server. Cluster jsme ještě nevytvořili, ale tento název použijeme při jeho vytváření.
ECS_ENABLE_SPOT_INSTANCE_DRAINING=true
— parametr určuje, že když je přijat signál k vypnutí instance bodu, všechny úlohy na ní by měly být převedeny do stavu Draining.
ECS_CONTAINER_STOP_TIMEOUT=1m
- parametr určuje, že po přijetí signálu SIGINT mají všechny úkoly 1 minutu před ukončením.
ECS_ENGINE_AUTH_TYPE=docker
— parametr udává, že se jako autorizační mechanismus používá schéma Docker
ECS_ENGINE_AUTH_DATA=...
— parametry připojení k registru soukromých kontejnerů, kde jsou uloženy vaše obrazy Docker. Pokud je veřejný, nemusíte nic uvádět.
Pro účely tohoto článku použiji veřejný obrázek z Docker Hub, proto specifikujte parametry ECS_ENGINE_AUTH_TYPE
и ECS_ENGINE_AUTH_DATA
nepotřebují.
Je dobré vědět: Doporučuje se pravidelně aktualizovat AMI, protože nové verze aktualizují verze Docker, Linux, ECS agent atd. Abyste na to nezapomněli, můžete
EC2 Auto Scaling Group
Auto Scaling Group je zodpovědná za spouštění a škálování instancí. Skupiny se spravují v sekci EC2 -> Auto Scaling -> Auto Scaling Groups.
Spustit šablonu — vyberte šablonu vytvořenou v předchozím kroku. Necháme výchozí verzi.
Možnosti nákupu a typy instancí — určete typy instancí pro klastr. Šablona Adhere to launch používá typ instance ze šablony Launch Template. Kombinace možností nákupu a typů instancí umožňuje flexibilně konfigurovat typy instancí. My toho využijeme.
Volitelná základna On-Demand — počet běžných, nebodových instancí, které budou vždy fungovat.
Procento na vyžádání nad základnou — procentuální poměr regulérních a spotových instancí, 50-50 bude rozděleno rovnoměrně, 20-80 za každou regulérní instanci budou zvýšeny 4 spotové instance. Pro účely tohoto příkladu uvedu 50-50, ale ve skutečnosti nejčastěji děláme 20-80, v některých případech 0-100.
Typy instancí — zde můžete zadat další typy instancí, které budou v clusteru použity. Nikdy jsme to nepoužili, protože vlastně nechápu smysl toho příběhu. Možná je to způsobeno limity na konkrétní typy instancí, ale lze je snadno zvýšit pomocí podpory. Pokud aplikaci znáte, rád si ji přečtu v komentářích)
Síť — nastavení sítě, vyberte VPC a podsítě pro stroje, ve většině případů byste měli vybrat všechny dostupné podsítě.
Vyrovnávání zatížení - nastavení balanceru, ale to uděláme samostatně, zde se ničeho nedotkneme. Zdravotní kontroly bude také konfigurován později.
Velikost skupiny — uvedeme limity počtu strojů v clusteru a požadovaný počet strojů na začátku. Počet počítačů v clusteru nebude nikdy menší než zadané minimum a větší než maximum, i když by mělo dojít ke škálování podle metrik.
Zásady škálování — parametry škálování, ale budeme škálovat na základě běžících úloh ECS, takže škálování nakonfigurujeme později.
Instance ochrany proti vodnímu kameni — ochrana instancí před smazáním při zmenšení. Povolíme to, aby ASG neodstranilo stroj, na kterém jsou spuštěné úlohy. Poskytovatel kapacity ECS zakáže ochranu pro instance, které nemají úkoly.
Přidat štítky — můžete zadat značky pro instance (k tomu musí být zaškrtnuto políčko Označit nové instance). Doporučuji zadat Name tag, pak budou mít všechny instance, které jsou spuštěny v rámci skupiny, stejný název a je vhodné si je prohlížet v konzoli.
Po vytvoření skupiny ji otevřete a přejděte do sekce Pokročilé konfigurace Proč nejsou všechny možnosti viditelné v konzole ve fázi vytváření.
Zásady ukončení — pravidla, která se berou v úvahu při mazání instancí. Jsou aplikovány v pořadí. Obvykle používáme ty na obrázku níže. Nejprve jsou odstraněny instance s nejstarší Launch Template (pokud jsme například aktualizovali AMI, vytvořili jsme novou verzi, ale všechny instance se na ni podařilo přepnout). Poté se vyberou instance, které jsou nejblíže následující zúčtovací hodině. A pak se vyberou ty nejstarší na základě data spuštění.
Je dobré vědět: pro aktualizaci všech počítačů v clusteru, pohodlné použití
Application Load Balancer a EC2 Target Group
Balancer se vytváří v sekci EC2 → Load Balancing → Load Balancers. Použijeme Application Load Balancer, srovnání různých typů balancerů si můžete přečíst na
Posluchači - má smysl vytvořit porty 80 a 443 a přesměrovat z 80 na 443 pomocí pravidel balanceru později.
Zóny dostupnosti — ve většině případů vybíráme zóny dostupnosti pro každého.
Nakonfigurujte nastavení zabezpečení — zde je uveden certifikát SSL pro balancer, nejpohodlnější možnost je ELBSecurityPolicy-2016-08
. Po vytvoření balanceru to uvidíte Název DNS, které potřebujete ke konfiguraci CNAME pro vaši doménu. Takhle to například vypadá v Cloudflare.
Skupina zabezpečení — vytvořte nebo vyberte bezpečnostní skupinu pro balancer, více jsem o tom psal výše v sekci EC2 Launch Template → Network settings.
Cílová skupina — vytvoříme skupinu, která je zodpovědná za směrování požadavků z balanceru na stroje a kontrolu jejich dostupnosti, abychom je mohli v případě problémů nahradit. Typ cíle musí být instance, Protokol и Přístav libovolná, pokud pro komunikaci mezi balancerem a instancemi používáte HTTPS, pak je potřeba do nich nahrát certifikát. Pro účely tohoto příkladu to neuděláme, jednoduše ponecháme port 80.
Zdravotní kontroly — parametry pro kontrolu funkčnosti služby. V reálné službě by se mělo jednat o samostatný požadavek, který implementuje důležité části obchodní logiky, pro účely tohoto příkladu ponechám výchozí nastavení. Dále můžete vybrat interval požadavku, časový limit, kódy úspěchu atd. V našem příkladu uvedeme kódy úspěchu 200-399, protože obrázek Dockeru, který bude použit, vrátí kód 304.
Zaregistrujte cíle — zde se vybírají vozy pro skupinu, ale v našem případě to provede ECS, takže tento krok přeskočíme.
Je dobré vědět: na úrovni balanceru můžete povolit protokoly, které se v určitém čase uloží do S3
Definice úlohy ECS
V předchozích krocích jsme vytvořili vše, co souvisí s infrastrukturou služeb, nyní přejdeme k popisu kontejnerů, které spustíme. To se provádí v sekci ECS → Definice úloh.
Kompatibilita typu spuštění - vyberte EC2.
Provádění úlohy role IAM - Vybrat ecsTaskExecutionRole
. Pomocí něj se zapisují protokoly, poskytuje se přístup k tajným proměnným atd.
V části Definice kontejneru klikněte na Přidat kontejner.
Obraz — odkaz na obrázek s kódem projektu; pro tento příklad použiji veřejný obrázek z Docker Hub
Limity paměti — limity paměti pro kontejner. Tvrdý limit — pevný limit, pokud kontejner překročí zadanou hodnotu, provede se příkaz docker kill, kontejner okamžitě zemře. Měkký limit — měkký limit, kontejner může překročit zadanou hodnotu, ale tento parametr bude zohledněn při zadávání úloh do strojů. Pokud má například počítač 4 GiB RAM a měkký limit kontejneru je 2048 MiB, pak tento počítač může mít s tímto kontejnerem maximálně 2 spuštěné úlohy. Ve skutečnosti jsou 4 GiB paměti RAM o něco méně než 4096 MiB, což lze zobrazit na kartě Instance ECS v clusteru. Měkký limit nemůže být větší než pevný limit. Je důležité pochopit, že pokud je v jednom úkolu několik kontejnerů, jejich limity se sečtou.
Mapování přístavů - v Hostitelský port Označujeme 0, to znamená, že port bude přidělován dynamicky a bude sledován cílovou skupinou. Kontejnerový přístav — port, na kterém vaše aplikace běží, je často specifikován v příkazu spuštění nebo přiřazen v kódu vaší aplikace, Dockerfile atd. Pro náš příklad použijeme 3000, protože je uveden v
Zdravotní prohlídka — parametry kontroly stavu kontejneru, nezaměňovat s parametry konfigurovanými v cílové skupině.
životní prostředí - nastavení prostředí. CPU jednotky - obdoba Memory limitů, pouze o procesoru. Každé jádro procesoru má 1024 jednotek, takže pokud má server dvoujádrový procesor a kontejner je nastaven na 512, lze na jednom serveru spustit 4 úlohy s tímto kontejnerem. CPU jednotky vždy odpovídají počtu jader, nemůže jich být o něco méně, jako je tomu u pamětí.
Příkaz — příkaz ke spuštění služby uvnitř kontejneru, všechny parametry jsou specifikovány oddělené čárkami. Může to být gunicorn, npm atd. Pokud není zadáno, použije se hodnota direktivy CMD z Dockerfile. Naznačujeme npm,start
.
Proměnné prostředí — proměnné prostředí kontejneru. Mohou to být jednoduchá textová data nebo tajné proměnné
Skladování a protokolování — zde nastavíme přihlašování do CloudWatch Logs (služba pro protokoly od AWS). Chcete-li to provést, zaškrtněte políčko Auto-configure CloudWatch Logs. Po vytvoření Definice úkolu se v CloudWatch automaticky vytvoří skupina protokolů. Standardně se v něm logy ukládají na dobu neurčitou, doporučuji změnit Retention period z Never Expire na požadovanou dobu. To se provádí ve skupinách CloudWatch Log, musíte kliknout na aktuální období a vybrat nové.
ECS Cluster a ECS Capacity Provider
Přejděte do sekce ECS → Clustery a vytvořte cluster. Jako šablonu vybereme EC2 Linux + Networking.
Název clusteru - velmi důležité, zde vytvoříme stejný název, jaký je uveden v parametru Launch Template ECS_CLUSTER
, v našem případě - DemoApiClusterProd
. Zaškrtněte políčko Vytvořit prázdný cluster. Volitelně můžete povolit Container Insights pro zobrazení metrik pro služby v CloudWatch. Pokud jste vše udělali správně, pak v sekci Instance ECS uvidíte stroje, které byly vytvořeny ve skupině Auto Scaling.
Přejděte na kartu Poskytovatelé kapacity a vytvořit nový. Dovolte mi připomenout, že je potřeba řídit vytváření a vypínání strojů v závislosti na počtu spuštěných úloh ECS. Je důležité si uvědomit, že poskytovatele lze přiřadit pouze do jedné skupiny.
Skupina automatického škálování — vyberte dříve vytvořenou skupinu.
Řízené škálování — povolit, aby poskytovatel mohl službu škálovat.
Cílová kapacita % — jaké procento strojů nabitých úkoly potřebujeme. Pokud zadáte 100 %, budou všechny stroje vždy zaneprázdněny spuštěnými úlohami. Pokud zadáte 50 %, pak bude polovina vozů vždy zdarma. V tomto případě, pokud dojde k prudkému nárůstu nákladu, se nové taxíky okamžitě dostanou k volným vozům, aniž by museli čekat na nasazení instancí.
Spravovaná ochrana před ukončením — enable, tento parametr umožňuje poskytovateli odstranit ochranu instancí před smazáním. K tomu dochází, když na stroji nejsou žádné aktivní úlohy a umožňuje Cílová kapacita %.
Nastavení služby ECS a škálování
Poslední krok :) Chcete-li vytvořit službu, musíte přejít do dříve vytvořeného clusteru na kartě Služby.
Typ spuštění — musíte kliknout na Přepnout na strategii poskytovatele kapacity a vybrat dříve vytvořené poskytovatele.
Definice úkolu — vyberte dříve vytvořenou definici úlohy a její revizi.
Název služby — aby nedošlo k záměně, vždy označujeme totéž jako Definice úkolu.
Typ služby - vždy replika.
Počet úkolů — požadovaný počet aktivních úkolů ve službě. Tento parametr je řízen změnou měřítka, ale musí být stále specifikován.
Minimální zdravé procento и Maximální procento — určit chování úkolů během nasazení. Výchozí hodnoty jsou 100 a 200, což znamená, že v době nasazení se počet úloh několikrát zvýší a poté se vrátí na požadovanou hodnotu. Pokud máte spuštěnou 1 úlohu, min=0 a max=100, pak během nasazení bude zabita a poté bude spuštěna nová, to znamená, že dojde k výpadku. Pokud běží 1 úloha, min=50, max=150, pak k nasazení vůbec nedojde, protože 1 úlohu nelze rozdělit na polovinu nebo zvýšit jedenapůlkrát.
Typ nasazení — opusťte Průběžnou aktualizaci.
Šablony umístění — pravidla pro zadávání úkolů na strojích. Výchozí hodnota je AZ Balanced Spread – to znamená, že každá nová úloha bude umístěna na novou instanci, dokud se nezvýší počet počítačů ve všech zónách dostupnosti. Obvykle děláme BinPack - CPU a Spread - AZ; s touto politikou jsou úkoly umístěny co nejhustěji na jednom počítači na CPU. Pokud je nutné vytvořit nový stroj, vytvoří se v nové zóně dostupnosti.
Typ vyvažovače zátěže — vyberte Application Load Balancer.
Služba IAM role - Vybrat ecsServiceRole
.
Název vyvažovače zátěže — vyberte dříve vytvořený balancer.
Období odkladu zdravotní kontroly — pauza před provedením kontroly stavu po spuštění nové úlohy, obvykle ji nastavujeme na 60 sekund.
Kontejner pro vyvážení nákladu — v položce Název cílové skupiny vyberte dříve vytvořenou skupinu a vše se automaticky vyplní.
Automatické škálování služeb — parametry škálování služby. Chcete-li upravit požadovaný počet služeb, vyberte možnost Konfigurovat automatické škálování služeb. Při škálování nastavujeme minimální a maximální počet úloh.
Role IAM pro automatické škálování služeb - Vybrat AWSServiceRoleForApplicationAutoScaling_ECSService
.
Zásady automatického škálování úloh — pravidla pro škálování. Existují 2 typy:
- Sledování cíle — sledování cílových metrik (využití CPU/RAM nebo počet požadavků na každý úkol). Například chceme, aby průměrné zatížení procesoru bylo 85 %, když bude vyšší, budou přibývat nové úlohy, dokud nedosáhne cílové hodnoty. Pokud je zatížení nižší, úlohy budou naopak odstraněny, pokud není povolena ochrana proti zmenšení (Zakázat scale-in).
- Krokové škálování - reakce na libovolnou událost. Zde můžete nakonfigurovat reakci na libovolnou událost (CloudWatch Alarm), když k ní dojde, můžete přidat nebo odebrat zadaný počet úkolů nebo zadat přesný počet úkolů.
Služba může mít několik pravidel škálování, to může být užitečné, hlavní věcí je zajistit, aby nebyla ve vzájemném rozporu.
Závěr
Pokud jste postupovali podle pokynů a použili stejný obrázek Docker, vaše služba by měla vrátit stránku jako je tato.
- Vytvořili jsme šablonu, podle které se spouštějí všechny stroje ve službě. Také jsme se naučili, jak aktualizovat stroje při změně šablony.
- Nakonfigurovali jsme zpracování signálu zastavení okamžité instance, takže do minuty po jeho obdržení jsou ze stroje odstraněny všechny běžící úlohy, takže se nic neztratí ani nepřeruší.
- Zvedli jsme vyvažovačku, abychom rovnoměrně rozložili zatížení mezi stroje.
- Vytvořili jsme službu, která běží na spotových instancích, což snižuje náklady na stroje asi 3krát.
- Nakonfigurovali jsme automatické škálování v obou směrech, abychom zvládli zvýšené pracovní zatížení bez nákladů na prostoje.
- Capacity Provider používáme k tomu, aby aplikace spravovala infrastrukturu (stroje) a ne naopak.
- Jsme skvělí.
Pokud máte předvídatelné výkyvy zatížení, například inzerujete ve velké e-mailové kampani, můžete nastavit škálování
Můžete také škálovat na základě dat z různých částí vašeho systému. Máme například funkcionalitu
Budu rád, když mi v komentářích řeknete zajímavé případy použití spotových instancí a ECS nebo něco o škálování.
Brzy zde budou články o tom, jak zpracováváme tisíce analytických událostí za sekundu na převážně bezserverovém zásobníku (s penězi) a jak funguje nasazení služeb pomocí GitLab CI a Terraform Cloud.
Odebírejte nás, bude to zajímavé!
Průzkumu se mohou zúčastnit pouze registrovaní uživatelé.
Používáte v produkci spotové instance?
-
22,2%Ano 6
-
66,7%No18
-
11,1%Dozvěděl jsem se o nich z článku a plánuji je používat3
Hlasovalo 27 uživatelů. 5 uživatelů se zdrželo hlasování.
Zdroj: www.habr.com