Přijímáme 10 000 událostí v Yandex.Cloud. Část 1

Ahoj všichni, přátelé!

* Tento článek je napsán na základě otevřeného praktika REBRAIN & Yandex.Cloud, pokud raději koukáte na video, můžete ho najít na tomto odkazu — https://youtu.be/cZLezUm0ekE

Nedávno jsme měli možnost si na vlastní kůži vyzkoušet Yandex.Cloud. Protože jsme se chtěli s tím seznámit důkladně a dlouhodobě, okamžitě jsme se vzdali myšlenky spustit jednoduchý WordPress blog s cloudovou databází — to by bylo příliš nudné. Po krátkém zamyšlení jsme se rozhodli rozvinout něco podobného produkční architektuře služby pro příjem a analýzu událostí v režimu téměř v reálném čase.

Jsem si naprosto jistý, že naprostá většina online (a nejen online) podniků tak či onak shromažďuje hromady informací o svých uživatelích a jejich chování. Minimálně to je nezbytné pro přijímání určitých rozhodnutí — například, pokud spravujete online hru — můžete se podívat na statistiky, na jaké úrovni uživatelé nejčastěji uvíznou a odinstalují vaši hru. Nebo proč uživatelé opouštějí vaši stránku, aniž by něco koupili (ahoj, Yandex.Metrika).

Takže, náš příběh: jak jsme psali aplikaci v Golangu, testovali Kafka vs RabbitMQ vs YQS, psali jsme streaming dat do Clickhouse clusteru a vizualizovali data pomocí Yandex DataLens. Samozřejmě, že to všechno bylo okořeněno infrastrukturními vymoženostmi jako docker, terraform, gitlab ci a samozřejmě také Prometheus. Jdeme na to!

Okamžitě bych chtěl zmínit, že vše nastavit na jednou nedokážeme — k tomu budeme potřebovat několik článků v sérii. Trochu o struktuře:

1. část (tu právě čtete). Určíme si technické požadavky a architekturu řešení, a také napíšeme aplikaci v Golangu.
2. část. Nasadíme naši aplikaci do produkce, uděláme ji škálovatelnou a otestujeme zátěž.
3. část. Pokusíme se pochopit, proč musíme uchovávat zprávy v bufferu a ne v souborech, a porovnáme mezi sebou Kafka, RabbitMQ a Yandex Queue Service.
4. část. Budeme rozvíjet Clickhouse cluster, psát streaming pro přenášení dat z bufferu a nastavíme vizualizaci v DataLens.
5. část. Přivedeme celou infrastrukturu do pořádku — nastavíme CI/CD pomocí Gitlab CI, připojíme monitoring a službu objevování pomocí Prometheus a Consul.

Technické požadavky

Nejdříve formulujeme technické zadání — co přesně chceme na výstupu.

  1. Chceme mít endpoint ve formátu events.kis.im (kis.im — testovací doména, kterou budeme používat po celou dobu článků), který by měl přijímat události pomocí HTTPS.
  2. Události jsou jednoduchý JSON ve formátu: {"event": "view", "os": "linux", "browser": "chrome"}. V konečné fázi přidáme trochu více polí, ale význam to moc mít nebude. Pokud máte zájem, můžeme přepnout na protobuf.
  3. Služba by měla být schopna zpracovávat 10 000 událostí za sekundu.
  4. Měla by existovat možnost horizontálního škálování — jednoduchým přidáváním nových instancí do našeho řešení. A bylo by dobré, pokud bychom mohli umístit front-end do různých geografických lokalit za účelem snížení latence při požadavcích klientů.
  5. Odolnost vůči poruchám. Řešení by mělo být dostatečně stabilní a být schopné přežít pád jakékoli části (do určitého počtu, samozřejmě).

Architektura

Pro takové úkoly byly už dávno vynalezeny klasické architektury, které umožňují efektivní škálování. Na obrázku je příklad našeho řešení.

Přijímáme 10 000 událostí v Yandex.Cloud. Část 1

Takže, co máme:

1. Vlevo jsou naše zařízení, která generují různé události, ať už se jedná o dokončení úrovně hráčů ve hře na mobilním telefonu nebo vytvoření objednávky v internetovém obchodě prostřednictvím běžného prohlížeče. Událost, jak je uvedeno v technické dokumentaci, je jednoduchý JSON, který se odesílá na náš endpoint — events.kis.im.

2. První dva servery jsou jednoduché vyrovnávače zatížení, jejichž hlavními úkoly jsou:

  • Být neustále dostupní. K tomu můžeme použít například keepalived, který přepíná virtuální IP mezi uzly v případě problémů.
  • Termínovat TLS. Ano, TLS budeme termínovat právě na nich. Za prvé, aby naše řešení splnilo technickou dokumentaci, a za druhé, abychom snížili zátěž při navazování šifrovaného spojení na našich backendových serverech.
  • Vyrovnávat přicházející požadavky na dostupné backend servery. Klíčové slovo zde — dostupné. Na základě tohoto pochopíme, že vyrovnávače zatížení by měly být schopny monitorovat naše servery s aplikacemi a přestat vyrovnávat provoz na selhané uzly.

3. Za vyrovnávači zatížení následují aplikační servery, na kterých běží dostatečně jednoduchá aplikace. Měla by být schopna přijímat přicházející požadavky po HTTP, validovat zaslaný JSON a ukládat data do vyrovnávací paměti.

4. Jako buffer na schématu je zobrazen kafka, i když samozřejmě na této úrovni je možné použít i jiné podobné služby. Kafka, rabbitmq a yqs porovnáme ve třetím článku.

5. Předposledním bodem naší architektury je Clickhouse — sloupcová databáze, která umožňuje uchovávat a zpracovávat obrovské objemy dat. Na této úrovni je nutné přenést data z bufferu do samotného úložiště (o tom bude ve 4. článku).

Tato schéma nám umožňuje nezávisle horizontálně škálovat každý vrstvu. Když si backend servery neporadí — přidáme další — protože jsou to stateless aplikace, a tudíž je možné to udělat i automaticky. Pokud buffer v podobě kafky nevyhovuje — přidáme další servery a přeneseme na ně část partií našeho tématu. Pokud selhává clickhouse — to není možné 🙂 Ve skutečnosti přidáme servery a rozdělením dat je zvládneme.

Mimochodem, pokud se rozhodnete zrealizovat volitelnou část našeho TZZ a provést škálování na různých geografických polohách, není nic jednoduššího:

Přijímáme 10 000 událostí v Yandex.Cloud. Část 1

V každé geografické poloze nasazujeme load balancer s aplikací a kafkou. Celkově stačí 2 servery aplikace, 3 uzly kafky a cloudový load balancer, například cloudflare, který bude kontrolovat dostupnost uzlů aplikace a vyvažovat požadavky podle geografických poloh na základě původní IP adresy klienta. Tímto způsobem data zaslaná americkým klientem přistanou na amerických serverech. A data z Afriky — na afrických.

Dále je to velmi jednoduché — použijeme nástroj mirror z balíčku kafky a zkopírujeme všechna data ze všech lokalit do našeho centrálního datového centra, umístěného v Rusku. Uvnitř data analyzujeme a zapisujeme je do Clickhouse pro následnou vizualizaci.

Takže jsme se vyřešili architektury — začínáme testovat Yandex.Cloud!

Píšeme aplikaci

Na cloud si ještě budeme muset chvíli počkat a napsat dostatečně jednoduchou službu pro zpracování příchozích událostí. Použijeme golang, protože se velmi dobře osvědčil jako jazyk pro psaní síťových aplikací.

Po hodině práce (možná i dvou hodinách) dostaneme přibližně takovou věc: https://github.com/RebrainMe/yandex-cloud-events/blob/master/app/main.go.

Jaké hlavní body bychom zde chtěli zdůraznit:

1. Při spuštění aplikace je možné zadat dvě volby. Jedna určuje port, na kterém budeme naslouchat příchozím http požadavkům (-addr). Druhá - adresu kafka serveru, kam budeme zapisovat naše události (-kafka):

addr     = flag.String("addr", ":8080", "TCP adresa pro naslouchání")
kafka    = flag.String("kafka", "127.0.0.1:9092", "Kafka koncové body")

2. Aplikace používá knihovnu sarama ([] github.com/Shopify/sarama) pro odesílání zpráv do kafka clusteru. Hned jsme nastavili parametry zaměřené na maximální rychlost zpracování:

config := sarama.NewConfig()
config.Producer.RequiredAcks = sarama.WaitForLocal
config.Producer.Compression = sarama.CompressionSnappy
config.Producer.Return.Successes = true

3. Do naší aplikace je také integrován klient prometheus, který sbírá různé metriky, jako jsou:

  • počet požadavků na naši aplikaci;
  • počet chyb při zpracování požadavku (nelze přečíst post požadavek, poškozený json, nelze zapsat do kafky);
  • čas zpracování jednoho požadavku od klienta, včetně doby zápisu zprávy do kafky.

4. Tři endpointy, které naše aplikace zpracovává:

  • /status — просто возвращаем ok, чтобы показать, что мы живы. Хотя можно и добавить некоторые проверки, типа доступности кафка кластера.
  • /metrics — по этому url prometheus client будет возвращать собранные им метрики.
  • /post — основной endpoint, куда будут приходить POST запросы с json внутри. Наше приложение проверяет json на валидность и если все ок — записывает данные в кафка-кластер.

Dovolím si poznamenat, že kód není ideální - je možné (a nutné!) ho ještě vylepšit. Například, můžeme přestat používat vestavěný net/http a přepnout na rychlejší fasthttp. Nebo bychom mohli ušetřit čas zpracování a CPU zdroje tím, že by kontrola platnosti json byla provedena až ve fázi, kdy se data převedou z bufferu do clickhouse clusteru.

Kromě vývojového aspektu jsme hned mysleli na naši budoucí infrastrukturu a rozhodli jsme se nasadit naši aplikaci prostřednictvím dockeru. Konečný Dockerfile pro sestavení aplikace - https://github.com/RebrainMe/yandex-cloud-events/blob/master/app/Dockerfile. Vzhledem k tomu je dost jednoduchý, jediný aspekt, na který bych chtěl upozornit, je multistage sestavení, které umožňuje snížit finální obraz našeho kontejneru.

První kroky v cloudu

Nejprve se registrováme na cloud.yandex.ru. Po vyplnění všech potřebných polí nám vytvoří účet a vydají grant na určitou částku peněz, kterou můžeme použít pro testování služeb cloudu. Pokud se rozhodnete zopakovat všechny kroky z našeho článku, tento grant by měl stačit.

Po registraci pro vás bude vytvořený samostatný cloud a adresář default, ve kterém můžete začít vytvářet cloudové zdroje. Ve skutečnosti v Yandex.Cloudu vypadá vzájemná vazba zdrojů následujícím způsobem:

Přijímáme 10 000 událostí v Yandex.Cloud. Část 1

Na jeden účet můžete vytvořit několik cloudů. A uvnitř cloudu vytvořit různé adresáře pro různé projekty společnosti. Více o tom lze přečíst v dokumentaci — https://cloud.yandex.ru/docs/resource-manager/concepts/resources-hierarchy. Mimochodem, níže v textu na ni budu často odkazovat. Když jsem nastavoval celou infrastrukturu od nuly — dokumentace mi několikrát pomohla, takže doporučuji ji prostudovat.

Pro správu cloudu můžete použít jak webové rozhraní, tak konzolovou utilitu — yc. Instalaci provedete jedním příkazem (pro Linux a Mac OS):

curl https://storage.yandexcloud.net/yandexcloud-yc/install.sh | bash

Pokud uvnitř vás zuří vnitřní bezpečnostní specialistka ohledně spouštění skriptů z internetu — tak za prvé, můžete otevřít skript a přečíst si ho, a za druhé, spouštíme ho pod svým uživatelem — bez root práv.

Pokud chcete nainstalovat klienta pro Windows, můžete využít návod zde a následně provést yc init, abyste ho plně nakonfigurovali:

vozerov@mba:~ $ yc init
Vítejte! Tento příkaz vás provede procesem konfigurace.
Navštivte prosím https://oauth.yandex.ru/authorize?response_type=token&client_id= pro získání OAuth tokenu.

Zadejte prosím OAuth token:
Vyberte prosím cloud k použití:
 [1] cloud-b1gv67ihgfu3bp (id = b1gv67ihgfu3bpt24o0q)
 [2] fevlake-cloud (id = b1g6bvup3toribomnh30)
Zadejte prosím svou numerickou volbu: 2
Váš aktuální cloud byl nastaven na 'fevlake-cloud' (id = b1g6bvup3toribomnh30).
Vyberte prosím složku k použití:
 [1] default (id = b1g5r6h11knotfr8vjp7)
 [2] Vytvořit novou složku
Zadejte prosím svou numerickou volbu: 1
Vaše aktuální složka byla nastavena na 'default' (id = b1g5r6h11knotfr8vjp7).
Chcete konfigurovat výchozí výpočetní zónu? [Y/n]
Kterou zónu chcete použít jako výchozí profil?
 [1] ru-central1-a
 [2] ru-central1-b
 [3] ru-central1-c
 [4] Nepoužívat výchozí zónu
Zadejte prosím svou numerickou volbu: 1
Vaše výchozí výpočetní zóna profilu byla nastavena na 'ru-central1-a'.
vozerov@mba:~ $

V zásadě je proces jednoduchý — nejprve je třeba získat oauth token pro správu cloudu, vybrat cloud a složku, kterou budete používat.

Pokud máte několik účtů nebo složek uvnitř jednoho cloudu, můžete vytvořit další profily s oddělenými nastaveními přes yc config profile create a přepínat mezi nimi.

Kromě výše uvedených způsobů tým Yandex.Cloud napsal velmi dobrý plugin pro terraform pro správu cloudových zdrojů. Z mé strany jsem připravil git-repozitář, kde jsem popsal všechny zdroje, které budou vytvořeny v rámci článku — https://github.com/rebrainme/yandex-cloud-events/. Zajímá nás větev master, pojďme si ji zklonovat lokálně:


vozerov@mba:~ $ git clone https://github.com/rebrainme/yandex-cloud-events/ events
Cloning into 'events'...
remote: Enumerating objects: 100, done.
remote: Counting objects: 100% (100/100), done.
remote: Compressing objects: 100% (68/68), done.
remote: Total 100 (delta 37), reused 89 (delta 26), pack-reused 0
Receiving objects: 100% (100/100), 25.65 KiB | 168.00 KiB/s, done.
Resolving deltas: 100% (37/37), done.
vozerov@mba:~ $ cd events/terraform/

Všechny hlavní proměnné využívané v terraformu jsou uvedeny v souboru main.tf. Pro začátek práce vytvořte v adresáři terraform soubor private.auto.tfvars s následujícím obsahem:

# Yandex Cloud Oauth token
yc_token = ""
# Yandex Cloud ID
yc_cloud_id = ""
# Yandex Cloud folder ID
yc_folder_id = ""
# Default Yandex Cloud Region
yc_region = "ru-central1-a"
# Cloudflare email
cf_email = ""
# Cloudflare token
cf_token = ""
# Cloudflare zone id
cf_zone_id = ""

Všechny proměnné můžete získat pomocí yc config list, protože jsme již konzolovou utilitu nastavili. Doporučuji ihned přidat private.auto.tfvars do .gitignore, abyste omylem nezveřejnili soukromá data.

V private.auto.tfvars jsme také uvedli údaje od Cloudflare — pro vytváření dns záznamů a pro proxování hlavní domény events.kis.im na naše servery. Pokud nechcete používat Cloudflare, odstraňte inicializaci providera cloudflare v main.tf a soubor dns.tf, který je zodpovědný za vytváření potřebných dns záznamů.

V naší práci budeme kombinovat všechny tři způsoby — a webové rozhraní, a konzolovou utilitu, a terraform.

Virtuální sítě

Omlouvám se, tento krok bychom mohli přeskočit, protože při vytváření nového cloudu se automaticky vytvoří samostatná síť a 3 podsítě — po jedné na každou zónu dostupnosti. Ale přesto bych chtěl udělat pro náš projekt samostatnou síť se svou adresací. Obecný schéma fungování sítě v Yandex.Cloud je znázorněno na obrázku níže (poctivě převzato z https://cloud.yandex.ru/docs/vpc/concepts/)

Přijímáme 10 000 událostí v Yandex.Cloud. Část 1

Takže vytváříte společnou síť, ve které budou moci zdroje mezi sebou komunikovat. Pro každou zónu dostupnosti se vytváří podsíť se svou adresací a připojuje k společné síti. Výsledkem je, že všechny cloudové zdroje v ní mohou komunikovat, i když se nacházejí v různých zónách dostupnosti. Zdroje připojené k různým cloudovým sítím si mohou vzájemně uložit pouze prostřednictvím externích adres. Mimochodem, jak ta magie uvnitř funguje, bylo dobře popsáno na Habré..

Vytváření sítě je popsáno v souboru network.tf z repozitáře. Tam vytváříme jednu společnou privátní síť internal a připojujeme k ní tři podsítě v různých zónách dostupnosti — internal-a (172.16.1.0/24), internal-b (172.16.2.0/24), internal-c (172.16.3.0/24).

Inicializujeme terraform a vytváříme sítě:

vozerov@mba:~\/events\/terraform (master) $ terraform init
... přeskočeno ..

vozerov@mba:~\/events\/terraform (master) $ terraform apply -target yandex_vpc_subnet.internal-a -target yandex_vpc_subnet.internal-b -target yandex_vpc_subnet.internal-c

... přeskočeno ...

Plán: 4 přidáno, 0 změněno, 0 zničeno.

Chcete tyto akce provést?
  Terraform provede výše uvedené akce.
  Pouze "ano" bude akceptováno jako schválení.

  Zadejte hodnotu: ano

yandex_vpc_network.internal: Vytváření...
yandex_vpc_network.internal: Vytvoření dokončeno po 3s [id=enp2g2rhile7gbqlbrkr]
yandex_vpc_subnet.internal-a: Vytváření...
yandex_vpc_subnet.internal-b: Vytváření...
yandex_vpc_subnet.internal-c: Vytváření...
yandex_vpc_subnet.internal-a: Vytvoření dokončeno po 6s [id=e9b1dad6mgoj2v4funog]
yandex_vpc_subnet.internal-b: Vytvoření dokončeno po 7s [id=e2liv5i4amu52p64ac9p]
yandex_vpc_subnet.internal-c: Ještě se vytváří... [10s uplynulo]
yandex_vpc_subnet.internal-c: Vytvoření dokončeno po 10s [id=b0c2qhsj2vranoc9vhcq]

Aplikace dokončena! Zdroje: 4 přidány, 0 změněny, 0 zničeny.

Skvěle! Vytvořili jsme naši síť a nyní jsme připraveni na vytvoření našich interních služeb.

Vytváření virtuálních strojů

Pro testování aplikace nám bude stačit vytvořit dva virtuální stroje — první budeme potřebovat pro sestavení a spuštění aplikace, druhý — pro spuštění Kafka, kterou budeme používat pro ukládání příchozích zpráv. A vytvoříme ještě jeden stroj, kde nastavíme Prometheus pro monitorování aplikace.

Virtuální stroje se budou konfigurovat pomocí Ansible, takže před spuštěním Terraformu se ujistěte, že máte nainstalovanou jednu z nejnovějších verzí Ansible. A nainstalujte potřebné role z Ansible Galaxy:

vozerov@mba:~\/events\/terraform (master) $ cd ..\/ansible\/ 
vozerov@mba:~\/events\/ansible (master) $ ansible-galaxy install -r requirements.yml
- cloudalchemy-prometheus (master) je již nainstalován, přeskočeno.
- cloudalchemy-grafana (master) je již nainstalován, přeskočeno.
- sansible.kafka (master) je již nainstalován, přeskočeno.
- sansible.zookeeper (master) je již nainstalován, přeskočeno.
- geerlingguy.docker (master) je již nainstalován, přeskočeno.
vozerov@mba:~\/events\/ansible (master) $

Uvnitř složky Ansible je příklad konfiguračního souboru .ansible.cfg, který používám. Možná to bude užitečné.

Před vytvořením virtuálních strojů se ujistěte, že máte spuštěný ssh-agent a přidaný ssh klíč, jinak se Terraform nebude moci připojit k vytvořeným strojům. Samozřejmě jsem narazil na chybu v OS X: https://github.com/ansible/ansible/issues/32499#issuecomment-341578864. Aby se vám takový problém neopakoval, před spuštěním Terraformu přidejte malou proměnnou do env:

vozerov@mba:~\/events\/terraform (master) $ export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES

Ve složce s Terraformem vytváříme potřebné zdroje:

vozerov@mba:~\/events\/terraform (master) $ terraform apply -target yandex_compute_instance.build -target yandex_compute_instance.monitoring -target yandex_compute_instance.kafka
yandex_vpc_network.internal: Obnovuji stav... [id=enp2g2rhile7gbqlbrkr]
data.yandex_compute_image.ubuntu_image: Obnovuji stav...
yandex_vpc_subnet.internal-a: Obnovuji stav... [id=e9b1dad6mgoj2v4funog]

Byl vygenerován plán provedení, který je uveden níže.
Akce s prostředky jsou označeny následujícími symboly:
  + vytvořit

... přeskočeno ...

Plán: 3 přidat, 0 změnit, 0 zničit.

... přeskočeno ...

Pokud vše dopadlo dobře (a mělo by), budou mít tři virtuální stroje:

  1. build — stroj pro testování a sestavení aplikace. Docker byl automaticky nainstalován pomocí ansible.
  2. monitoring — stroj pro monitorování — na něm je nainstalován prometheus & grafana. Přihlašovací údaje jsou standardní: admin / admin.
  3. kafka — malý stroj s nainstalovanou kafka, dostupný na portu 9092.

Ujistíme se, že jsou všechny na místě:

vozerov@mba:~\/events (master) $ yc compute instance list
+----------------------+------------+---------------+---------+---------------+-------------+
|          ID          |    NAME    |    ZONE ID    | STATUS  |  EXTERNAL IP  | INTERNAL IP |
+----------------------+------------+---------------+---------+---------------+-------------+
| fhm081u8bkbqf1pa5kgj | monitoring | ru-central1-a | RUNNING | 84.201.159.71 | 172.16.1.35 |
| fhmf37k03oobgu9jmd7p | kafka      | ru-central1-a | RUNNING | 84.201.173.41 | 172.16.1.31 |
| fhmt9pl1i8sf7ga6flgp | build      | ru-central1-a | RUNNING | 84.201.132.3  | 172.16.1.26 |
+----------------------+------------+---------------+---------+---------------+-------------+

Prostředky jsou na místě, a odsud můžeme vyčíst jejich ip adresy. Všude dále budu používat ip adresy pro připojení přes ssh a testování aplikace. Pokud máte účet na cloudflare připojený k terraformu, klidně používejte nově vytvořené DNS názvy.
Mimochodem, při vytváření virtuálky je přidělena interní ip a interní DNS název, takže k serverům uvnitř sítě se lze obracet pomocí jmen:

ubuntu@build:~$ ping kafka.ru-central1.internal
PING kafka.ru-central1.internal (172.16.1.31) 56(84) bytes of data.
64 bytes from kafka.ru-central1.internal (172.16.1.31): icmp_seq=1 ttl=63 time=1.23 ms
64 bytes from kafka.ru-central1.internal (172.16.1.31): icmp_seq=2 ttl=63 time=0.625 ms
^C
--- statistiky pingování kafka.ru-central1.internal ---
2 pakety odeslány, 2 přijaty, 0% ztráta paketů, čas 1001ms
rtt min/avg/max/mdev = 0.625/0.931/1.238/0.308 ms

To se nám hodí pro určení koncového bodu aplikace s kafkou.

Sestavujeme aplikaci

Skvěle, servery jsou, aplikace je — zbývá ji jen sestavit a publikovat. Pro sestavení použijeme běžný docker build, ale jako úložiště obrazů vezmeme službu od Yandexu — container registry. Ale všechno po pořádku.

Zkopírujeme aplikaci na build stroj, přihlásíme se přes ssh a sestavíme obraz:

vozerov@mba:~\/events\/terraform (master) $ cd ..
vozerov@mba:~\/events (master) $ rsync -av app\/ ubuntu@84.201.132.3:app\/\n\n... přeskočeno ...\n\nsent 3849 bytes  received 70 bytes  7838.00 bytes\/sec\ntotal size is 3644  speedup is 0.93\n\nvozerov@mba:~\/events (master) $ ssh 84.201.132.3 -l ubuntu\nubunt@build:~$ cd app\nubunt@build:~\/app$ sudo docker build -t app .\nSending build context to Docker daemon  6.144kB\nStep 1\/9 : FROM golang:latest AS build\n... přeskočeno ...\n\nSuccessfully built 9760afd8ef65\nSuccessfully tagged app:latest

Polovina práce hotová — nyní můžeme zkontrolovat funkčnost naší aplikace spuštěním a odesláním na kafka:

ubuntu@build:~\/app$ sudo docker run --name app -d -p 8080:8080 app \/app\/app -kafka=kafka.ru-central1.internal:9092\n\nZ místního počítače můžeme odeslat testovací událost a podívat se na odpověď:\n\nvozerov@mba:~\/events (master) $ curl -D - -s -X POST -d '{"key1":"data1"}' http:\/\/84.201.132.3:8080\/post\nHTTP\/1.1 200 OK\nContent-Type: application\/json\nDate: Mon, 13 Apr 2020 13:53:54 GMT\nContent-Length: 41\n\n{"status":"ok","partition":0,"Offset":0}\nvozerov@mba:~\/events (master) $

Aplikace odpověděla úspěšným zápisem a uváděním id partition a offsetu, do kterého zpráva přišla. Nyní stačí vytvořit registr v Yandex.Cloud a nahrát tam náš obraz (jak to udělat pomocí tří řádků, je popsáno ve souboru registry.tf). Vytváříme úložiště:

vozerov@mba:~\/events\/terraform (master) $ terraform apply -target yandex_container_registry.events\n\n... přeskočeno ...\n\nPlan: 1 to add, 0 to change, 0 to destroy.\n\n... přeskočeno ...\n\nApply complete! Resources: 1 added, 0 changed, 0 destroyed.

Pro autentizaci v kontejnerovém registru existuje několik způsobů — pomocí oauth tokenu, iam tokenu nebo klíče servisního účtu. Podrobnější informace o těchto metodách jsou v dokumentaci. https://cloud.yandex.ru/docs/container-registry/operations/authentication. Budeme používat klíč servisního účtu, proto vytvoříme účet:

vozerov@mba:~\/events\/terraform (master) $ terraform apply -target yandex_iam_service_account.docker -target yandex_resourcemanager_folder_iam_binding.puller -target yandex_resourcemanager_folder_iam_binding.pusher\n\n... přeskočeno ...\n\nApply complete! Resources: 3 added, 0 changed, 0 destroyed.

Nyní zbývá vytvořit pro něj klíč:

vozerov@mba:~\/events\/terraform (master) $ yc iam key create --service-account-name docker -o key.json\nid: ajej8a06kdfbehbrh91p\nservice_account_id: ajep6d38k895srp9osij\ncreated_at: "2020-04-13T14:00:30Z"\nkey_algorithm: RSA_2048

Získáváme informace o id našeho úložiště, přenášíme klíč a autorizujeme se:

vozerov@mba:~\/events\/terraform (master) $ scp key.json ubuntu@84.201.132.3:\nkey.json                                                                                                                    100% 2392   215.1KB\/s   00:00\n\nvozerov@mba:~\/events\/terraform (master) $ ssh 84.201.132.3 -l ubuntu\n\nubunt@build:~$ cat key.json | sudo docker login --username json_key --password-stdin cr.yandex\nWARNING! Your password will be stored unencrypted in \/home\/ubuntu\/.docker\/config.json.\nConfigure a credential helper to remove this warning. See\nhttps:\/\/docs.docker.com\/engine\/reference\/commandline\/login\/#!credentials-store\n\nLogin Succeeded\nubunt@build:~$

Pro nahrání obrazu do registru budeme potřebovat ID kontejnerového registru, vezmeme jej z nástroje yc:

vozerov@mba:~ $ yc container registry get events
id: crpdgj6c9umdhgaqjfmm
folder_id:
name: events
status: ACTIVE
created_at: "2020-04-13T13:56:41.914Z"

Poté označíme náš obraz novým názvem a nahrajeme ho:

ubuntu@build:~$ sudo docker tag app cr.yandex/crpdgj6c9umdhgaqjfmm/events:v1
ubuntu@build:~$ sudo docker push cr.yandex/crpdgj6c9umdhgaqjfmm/events:v1
Push se odkazuje na repozitář [cr.yandex/crpdgj6c9umdhgaqjfmm/events]
8c286e154c6e: Nahráno
477c318b05cb: Nahráno
beee9f30bc1f: Nahráno
v1: digest: sha256:1dd5aaa9dbdde2f60d833be0bed1c352724be3ea3158bcac3cdee41d47c5e380 velikost: 946

Můžeme se ujistit, že byl obraz úspěšně nahrán:

vozerov@mba:~/events/terraform (master) $ yc container repository list
+----------------------+-----------------------------+
|          ID          |            NAME             |
+----------------------+-----------------------------+
| crpe8mqtrgmuq07accvn | crpdgj6c9umdhgaqjfmm/events |
+----------------------+-----------------------------+

Mimochodem, pokud nainstalujete nástroj yc na stroj s linuxem, můžete použít příkaz

yc container registry configure-docker

k nastavení dockeru.

Závěr

Odvedli jsme velký a náročný kus práce a výsledek je:

  1. Navrhli jsme architekturu našeho budoucího servisu.
  2. Napsali jsme aplikaci v golangu, která realizuje naši obchodní logiku.
  3. Sestavili jsme ji a umístili do soukromého kontejnerového registru.

V další části se dostaneme k zajímavé části — nasadíme naši aplikaci do produkce a konečně ji zatížíme. Zůstaňte s námi!

Tento materiál je k dispozici ve formátu videonahrávky otevřené praktikum REBRAIN & Yandex.Cloud: Příjmáme 10 000 požadavků za sekundu na Yandex Cloud — https://youtu.be/cZLezUm0ekE

Pokud máte zájem navštěvovat takové akce online a klást otázky v reálném čase, připojte se k kanálu DevOps by REBRAIN.

Rádi bychom poděkovali Yandex.Cloud za možnost uspořádat takovou akci. Odkaz na ně — https://cloud.yandex.ru/prices

Pokud potřebujete migrovat do cloudu nebo máte otázky k vaší infrastruktuře, neváhejte poslat žádost.

P.S. Máme 2 bezplatné audity měsíčně, možná právě váš projekt bude mezi nimi.

Zdroj: habr.com

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster