10 000 eseményt fogadunk a Yandex.Cloud-ban. 1. rész

Helló mindenkinek, barátok!

* Ez a cikk a REBRAIN & Yandex.Cloud nyílt gyakorlati munkájára épül, ha inkább videót néznél, ezt a linken találhatod — https://youtu.be/cZLezUm0ekE

Nemrég lehetőségünk nyílt élőben kipróbálni a Yandex Felhőt. Mivel hosszú és alapos élményt akartunk, rögtön lemondtunk arról az ötletről, hogy egy egyszerű WordPress blogot indítsunk felhőalapú adatbázissal — túl unalmas. Rövid gondolkodás után úgy döntöttünk, hogy valami hasonlót indítunk, mint egy termelési architektúra a rendezvények valós idejű fogadására és elemzésére.

Absolút meg vagyok győződve arról, hogy az online (és nem csak) üzletek túlnyomó többsége valamilyen módon rengeteg információt gyűjt felhasználóiról és azok cselekedeteiről. Legalábbis ez szükséges bizonyos döntések meghozatalához — például, ha online játékot vezetsz — megnézheted a statisztikát, hogy a felhasználók melyik szinten akadtak el leggyakrabban és törölték a játékodat. Vagy hogy miért hagyják el a weboldalad, anélkül, hogy bármit is vásárolnának (üdv, Yandex.Metrica).

Tehát a mi történetünk: hogyan írtunk egy alkalmazást golang nyelven, teszteltük a kafka vs rabbitmq vs yqs, adatstreaminget írtunk a Clickhouse klaszterbe, és adatvizualizálást végeztünk a Yandex Datalens segítségével. Természetesen mindezt infrastruktúra csodákkal fűszereztük, mint a docker, terraform, gitlab ci és természetesen prometheus. Induljunk!

Azonnal szeretném megjegyezni, hogy mindent egy lépésben nem tudunk beállítani — ehhez több cikkre lesz szükségünk a sorozaton belül. Egy kicsit a struktúráról:

1. rész (ezt olvasod). Meghatározzuk a műszaki feladatot és a megoldás architektúráját, valamint írunk egy alkalmazást golang nyelven.
2. rész. Az alkalmazásunkat élesbe tesszük, skálázhatóvá tesszük, és terhelést tesztelünk.
3. rész. Megpróbáljuk kideríteni, miért fontos a számunkra üzeneteket pufferben tárolni, nem fájlokban, és összehasonlítjuk a kafka, rabbitmq és a yandex queue service lehetőségeit.
4. rész. Clickhouse klasztert indítunk, streamelést írunk, hogy az adatokat a pufferből oda helyezzük, és beállítjuk a vizualizációt a datalensben.
5. rész. Az összes infrastruktúrát megfelelő állapotba hozzuk — beállítjuk a ci/cd-t, a gitlab ci segítségével, monitorozást és szolgáltatás felfedezést csatlakoztatunk a prometheus és consul segítségével.

Műszaki feladat

Első lépésként megfogalmazzuk a műszaki feladatot — mit szeretnénk elérni a végeredményben.

  1. Szeretnénk egy olyan endpoint-ot, mint az events.kis.im (a kis.im teszt domain, amelyet az összes cikk során használni fogunk), amely HTTPS-en keresztül fogadja az eseményeket.
  2. Az események egyszerű JSON formátumúak, például: {"event": "view", "os": "linux", "browser": "chrome"}. A végső lépésben egy kicsit több mezőt adunk hozzá, de ez nem fog nagy szerepet játszani. Ha szükséges, áttérhetünk a protobuf-ra.
  3. A szolgáltatásnak képesnek kell lennie másodpercenként 10 000 esemény feldolgozására.
  4. Lehetővé kell tenni a vízszintes skálázást — egyszerű új példányok hozzáadásával a megoldásunkhoz. Jó lenne, ha a front-end részt különböző földrajzi helyekre tudnánk vinni a késleltetés csökkentése érdekében a klienslekérdezések során.
  5. Hibaállóság. A megoldásnak elég stabilnak kell lennie, és túl kell élnie a bármely részleget érő hibákat (bizonyos mennyiségig természetesen).

Architektúra

Valójában az ilyen típusú feladatokra régóta kifejlesztett klasszikus architektúrák állnak rendelkezésre, amelyek lehetővé teszik a hatékony skálázást. A képen a mi megoldásunk példáját láthatjuk.

10 000 eseményt fogadunk a Yandex.Cloud-ban. 1. rész

Tehát, amit kínálunk:

1. Bal oldalon láthatók az eszközeink, amelyek különböző eseményeket generálnak, legyen szó játékosok szintlépéseiről okostelefonokon vagy megrendelések létrehozásáról böngészőkön keresztül. Az esemény, ahogy a műszaki leírásban meg van határozva, egy egyszerű JSON, amelyet az events.kis.im endpoint-ra küldünk.

2. Az első két szerver egyszerű terheléselosztók, fő feladataik:

  • Mindig elérhetőek legyenek. Ehhez például használhatunk keepalived-et, amely a virtuális IP-címet átkapcsolja a csomópontok között probléma esetén.
  • TLS-terminálni. Igen, a TLS-t éppen itt fogjuk terminálni. Először is, hogy a megoldásunk megfeleljen a műszaki leírásnak, másodsorban pedig, hogy a titkosított kapcsolat létrehozásának terhét levegyük a backend szervereinkről.
  • Terheléselosztani a bejövő lekérdezéseket az elérhető backend szerverek között. A kulcsszó itt az elérhető. Ennek alapján arra a megértésre jutunk, hogy a terheléselosztóknak képesnek kell lenniük figyelni a szervereinket, amelyek a programokat futtatják, és megszüntetni a forgalom terheléselosztását a leállt csomópontok felé.

3. A terheléselosztók mögött alkalmazásszerverek állnak, amelyeken egy viszonylag egyszerű alkalmazás fut. Ennek képesnek kell lennie HTTP-n keresztül bejövő lekérdezések fogadására, a megküldött JSON érvényesítésére, és az adatok tárolására egy pufferben.

4. A sémában pufferként a Kafka látható, bár persze ezen a szinten más hasonló szolgáltatások is használhatók. A Kafka, RabbitMQ és YQS összehasonlítását a harmadik cikkben végezzük el.

5. Architektúránk utolsó előtti pontja a Clickhouse — egy oszlop alapú adatbázis, amely lehetővé teszi hatalmas mennyiségű adat tárolását és feldolgozását. Ezen a szinten szükséges az adatokat a pufferből a tényleges tárolási rendszerbe átvinni (erről a negyedik cikkben lesz szó).

Ez a séma lehetővé teszi számunkra, hogy függetlenül, vízszintesen skálázzunk minden réteget. Ha a backend szerverek nem bírnak el a terheléssel — adjunk hozzá többet — hiszen ezek stateless alkalmazások, tehát mindezt automatikusan is megtehetjük. Ha a Kafka puffer nem bírja a terhelést — dobjunk be még néhány szervert, és osszuk el a topikunk egyes partícióit közöttük. Ha a Clickhouse nem bírja — ez nem lehetséges 🙂 Valójában itt is szervereket adhatunk hozzá, és shardingolhatjuk az adatokat.

Egyébként, ha meg szeretné valósítani a műszaki specifikációnk opcionális részét és skálázást különböző földrajzi helyeken, akkor ez a legegyszerűbb dolog:

10 000 eseményt fogadunk a Yandex.Cloud-ban. 1. rész

Minden földrajzi helyszínen beállítunk egy load balancert az alkalmazásunkkal és a Kafkával. Összességében elegendő, ha 2 alkalmazásszerver, 3 Kafka csomópont és egy felhő alapú balancer, például a Cloudflare, biztosítja az alkalmazás csomópontok elérhetőségét és a lekérdezések geolokáció szerinti egyensúlyozását az ügyfél eredeti IP-címe alapján. Így az amerikai ügyféltől küldött adatok az amerikai szerverekre, míg az afrikai adatok az afrikai szerverekre érkeznek.

Ezután minden nagyon egyszerű — használjuk a Kafka tükör eszközét, és másoljuk az összes adatot minden helyszínről a központi adatközpontunkba, amely Oroszországban található. Itt az adatokat feldolgozzuk, majd a Clickhouse-ba rögzítjük a későbbi vizualizációhoz.

Tehát az architektúrával megvagyunk — kezdjünk neki a Yandex.Cloud megrázásának!

Alkalmazás írása

Még egy kis időt várnunk kell a felhő megvalósításáig, és el kell készítenünk egy viszonylag egyszerű szolgáltatást a bejövő események feldolgozására. A Golang-ot fogjuk használni, mert nagyon jól bevált a hálózati alkalmazások megírására.

Egy óra (vagy talán két óra) elteltével körülbelül ilyesmit kapunk: https://github.com/RebrainMe/yandex-cloud-events/blob/master/app/main.go.

Milyen főbb szempontokat szeretnénk itt megemlíteni:

1. Az alkalmazás indításakor két flag-nak adhatunk meg értéket. Az egyik a port, amelyen a bejövő HTTP-kéréseket figyeljük (-addr). A másik pedig a Kafka szerver címe, ahova az eseményeinket rögzítjük (-kafka):

addr     = flag.String("addr", ":8080", "TCP cím, amit figyelni fogunk")
kafka    = flag.String("kafka", "127.0.0.1:9092", "Kafka végpontok")

2. Az alkalmazás a sarama könyvtárat használja ([] github.com/Shopify/sarama) üzenetek küldésére a Kafka klaszterre. A beállításokat azonnal a maximális feldolgozási sebességre optimalizáltuk:

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

3. Az alkalmazásunkban beépített Prometheus kliens is található, amely különböző metrikákat gyűjt, például:

  • az alkalmazásunkra vonatkozó kérések száma;
  • a kérés végrehajtása során fellépő hibák száma (nem lehetett elolvasni a post kérést, hibás JSON, nem lehetett rögzíteni a kafkában);
  • egy kérés feldolgozásának ideje a klienstől, beleértve az üzenet Kafka-ba írásának idejét.

4. Három endpoint, amelyet az alkalmazásunk kezel:

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

Megjegyzem, hogy a kód nem tökéletes - lehet (és kell is!) javítani rajta. Például el lehet hagyni a beépített net/http használatát, és áttérhetünk egy gyorsabb fasthttp-re. Vagy időt és CPU-erőforrásokat nyerhetünk azzal, ha a JSON érvényességének ellenőrzését későbbre halasztjuk - amikor az adatok áthelyeződnek a pufferről a ClickHouse klaszterre.

A fejlesztési szempontok mellett azonnal gondoltunk a jövőbeli infrastruktúránkra és úgy döntöttünk, hogy az alkalmazásunkat Docker környezetben telepítjük. A végső Dockerfile az alkalmazás felépítéséhez - https://github.com/RebrainMe/yandex-cloud-events/blob/master/app/Dockerfile. Általánosságban elmondható, hogy ez elég egyszerű, az egyetlen dolog, amire figyelni szeretnénk, az a multistage felépítés, amely lehetővé teszi a konténerünk végső képének csökkentését.

Első lépések a felhőben

Első lépésként regisztráljunk a cloud.yandex.ru. Miután kitöltöttük az összes szükséges mezőt, létrehoznak egy fiókot és adnak egy bizonyos összegű támogatást, amelyet a felhőszolgáltatások tesztelésére használhatunk. Ha meg szeretné ismételni a cikkünk lépéseit, ennek a támogatásnak elégnek kell lennie.

A regisztráció után egy külön felhőt és egy alapértelmezett katalogust hoznak létre az Ön számára, ahol elkezdheti a felhőalapú erőforrások létrehozását. Általában a Yandex.Cloud-ban az erőforrások összefonódása a következőképpen néz ki:

10 000 eseményt fogadunk a Yandex.Cloud-ban. 1. rész

Egy fiókhoz több felhőt is létrehozhat. A felhőn belül különböző mappákat is készíthet a cég különböző projektjei számára. További információ erről a dokumentációban található — https://cloud.yandex.ru/docs/resource-manager/concepts/resources-hierarchy. Egyébként a későbbiekben gyakran hivatkozni fogok rá. Amikor az egész infrastruktúrát nulláról állítottam be — a dokumentáció többször is jól jött, ezért javaslom, hogy nézze át alaposan.

A felhő kezeléséhez használhatja a webes felületet vagy a konzolos eszközt — yc. A telepítés egy parancs segítségével történik (Linux és Mac Os esetén):

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

Ha a hálózatról letöltött szkriptek futtatása miatt belső biztonsági aggályai vannak — először is, megnyithatja a szkriptet és elolvashatja, másodszor, a saját felhasználójaként futtatjuk — root jogok nélkül.

Ha Windows rendszerre szeretné telepíteni az ügyfelet, akkor kövesse az útmutatót itt majd futtassa yc init, hogy teljesen beállítsa:

vozerov@mba:~ $ yc init
Üdvözöljük! Ez a parancs végigvezet a konfigurációs folyamaton.
Kérem, látogasson el a https://oauth.yandex.ru/authorize?response_type=token&client_id= oldalra az OAuth token megszerzéséhez.

Kérjük, adja meg az OAuth tokent:
Kérjük, válassza ki a használni kívánt felhőt:
 [1] cloud-b1gv67ihgfu3bp (id = b1gv67ihgfu3bpt24o0q)
 [2] fevlake-cloud (id = b1g6bvup3toribomnh30)
Kérjük, adja meg a numerikus választását: 2
A jelenlegi felhője be van állítva 'fevlake-cloud' (id = b1g6bvup3toribomnh30) néven.
Kérjük, válassza ki a használni kívánt mappát:
 [1] default (id = b1g5r6h11knotfr8vjp7)
 [2] Hozzon létre egy új mappát
Kérjük, adja meg a numerikus választását: 1
A jelenlegi mappa be van állítva 'default' (id = b1g5r6h11knotfr8vjp7) néven.
Szeretné konfigurálni az alapértelmezett Compute zónát? [Y/n]
Melyik zónát szeretné alapértelmezettként használni?
 [1] ru-central1-a
 [2] ru-central1-b
 [3] ru-central1-c
 [4] Ne állítson be alapértelmezett zónát
Kérjük, adja meg a numerikus választását: 1
Az alapértelmezett Compute zóna be van állítva 'ru-central1-a' néven.
vozerov@mba:~ $

Alapvetően a folyamat nem bonyolult — először is, meg kell szereznie az OAuth tokent a felhő kezeléséhez, majd ki kell választania a felhőt és a mappát, amelyet használni fog.

Ha több fiókja van, vagy mappák egy felhőn belül, akkor további profilokat hozhat létre külön beállításokkal a yc config profile create parancs segítségével, és közvetlenül válthat közöttük.

A fent említett módszerek mellett a Yandex.Cloud csapata írt egy nagyon jó plugint a terraformhoz a felhőalapú erőforrások kezeléséhez. Én is készítettem egy git-repozitóriumot, amelyben leírtam azokat az erőforrásokat, amelyeket a cikk keretében létre fogunk hozni — https://github.com/rebrainme/yandex-cloud-events/. Minket a master ágazat érdekel, klónozzuk le helyben:


vozerov@mba:~ $ git clone https://github.com/rebrainme/yandex-cloud-events/ events
Klónozás az 'events'... 
remote: Objektumok felsorolása: 100, kész. 
remote: Objektumok számlálása: 100% (100/100), kész. 
remote: Objektumok tömörítése: 100% (68/68), kész. 
remote: Összesen 100 (delta 37), újrahasználva 89 (delta 26), pack-reused 0
Objektumok fogadása: 100% (100/100), 25.65 KiB | 168.00 KiB/s, kész. 
Delta-k megoldása: 100% (37/37), kész.
vozerov@mba:~ $ cd events/terraform/

Minden fő változó, amelyet a terraform használ, a main.tf fájlban van megadva. A munkakezdéshez hozzunk létre a terraform mappában egy private.auto.tfvars nevű fájlt az alábbi tartalommal:

# 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 = ""

Minden változót megkaphatunk a yc config list parancsból, mivel a parancssori eszközt már beállítottuk. Javaslom, hogy azonnal adjuk hozzá a private.auto.tfvars-t a .gitignore-hoz, hogy ne publikáljunk véletlenül privát adatokat.

A private.auto.tfvars-ban a Cloudflare adatait is megadtuk — a dns-rekordok létrehozásához és a fő domain, az events.kis.im proxizásához a szervereinkre. Ha nem kívánja használni a Cloudflare-t, akkor törölje a Cloudflare szolgáltató inicializálását a main.tf-ből és a szükséges dns rekordok létrehozásáért felelős dns.tf fájlból.

A munkánk során mindhárom módszert kombinálni fogjuk — a webes felületet, a parancssori eszközt és a terraformot.

Virtuális hálózatok

Őszintén szólva, ezt a lépést el is lehetett volna hagyni, mivel az új felhő létrehozásakor automatikusan létrejön egy külön hálózat és három alháló — egy a minden elérhetőségi zónához. De azért szeretnénk a projektünk számára egy külön hálózatot létrehozni a saját címzésünkkel. A Yandex Cloud hálózatának működési séma alább látható (őszintén szólva innen van átvéve). https://cloud.yandex.ru/docs/vpc/concepts/)

10 000 eseményt fogadunk a Yandex.Cloud-ban. 1. rész

Tehát létrehoz egy közös hálózatot, amelyen belül az erőforrások egymással kommunikálhatnak. Minden elérhetőségi zónához készül egy alháló a saját címzésével, és csatlakozik a közös hálózathoz. Ennek eredményeként az összes felhő-erőforrás kommunikálhat, még ha különböző elérhetőségi zónákban is helyezkednek el. Azok az erőforrások, amelyek különböző felhőhálózatokhoz csatlakoznak, csak külső címeken keresztül láthatják egymást. Egyébként, hogyan működik ez a varázslat belül, jól le van írva a Habr-on..

A hálózat létrehozása a repository network.tf fájljában van leírva. Ott létrehozunk egy közös privát hálózatot, belső (internal), és csatlakoztatunk hozzá három alhálót, amelyek különböző elérhetőségi zónákban helyezkednek el — internal-a (172.16.1.0/24), internal-b (172.16.2.0/24), internal-c (172.16.3.0/24).

Inicializáljuk a terraformot és létrehozzuk a hálózatokat:

vozerov@mba:~\/events\/terraform (master) $ terraform init
... skipped ..

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

... skipped ...

Terv: 4 hozzáadva, 0 megváltoztatva, 0 elpusztítva.

Szeretné végrehajtani ezeket a műveleteket?
  A Terraform végrehajtja a fenti műveleteket.
  Csak a 'yes' fogadható el a jóváhagyásra.

  Adjon meg egy értéket: yes

yandex_vpc_network.internal: Létrehozás...
yandex_vpc_network.internal: Létrehozás befejezve 3 másodperc után [id=enp2g2rhile7gbqlbrkr]
yandex_vpc_subnet.internal-a: Létrehozás...
yandex_vpc_subnet.internal-b: Létrehozás...
yandex_vpc_subnet.internal-c: Létrehozás...
yandex_vpc_subnet.internal-a: Létrehozás befejezve 6 másodperc után [id=e9b1dad6mgoj2v4funog]
yandex_vpc_subnet.internal-b: Létrehozás befejezve 7 másodperc után [id=e2liv5i4amu52p64ac9p]
yandex_vpc_subnet.internal-c: Még létrehozás alatt... [10 másodperc eltelt]
yandex_vpc_subnet.internal-c: Létrehozás befejezve 10 másodperc után [id=b0c2qhsj2vranoc9vhcq]

Alkalmazás befejezve! Erőforrások: 4 hozzáadva, 0 megváltoztatva, 0 elpusztítva.

Remek! Létrehoztuk a hálózatunkat, és most készen állunk belső szolgáltatásaink létrehozására.

Virtuális gépek létrehozása

Az alkalmazás teszteléséhez elegendő lesz két virtuális gépet létrehozni — az első a alkalmazás összeszerelésére és futtatására szükséges, a második a kafka futtatásához, amelyet az bejövő üzenetek tárolására fogunk használni. És létrehozunk még egy gépet, ahol a prometheus-t beállítjuk az alkalmazás megfigyelésére.

A virtuális gépeket ansible segítségével fogjuk beállítani, ezért a terraform futtatása előtt győződjön meg róla, hogy az ansible legújabb verziója telepítve van. És telepítse a szükséges szerepeket az ansible galaxy-ból:

vozerov@mba:~\/events\/terraform (master) $ cd ..\/ansible\/\nvozerov@mba:~\/events\/ansible (master) $ ansible-galaxy install -r requirements.yml\n- cloudalchemy-prometheus (master) már telepítve van, átugrás.\n- cloudalchemy-grafana (master) már telepítve van, átugrás.\n- sansible.kafka (master) már telepítve van, átugrás.\n- sansible.zookeeper (master) már telepítve van, átugrás.\n- geerlingguy.docker (master) már telepítve van, átugrás.\nvozerov@mba:~\/events\/ansible (master) $

Az ansible mappában található egy példa konfigurációs fájl .ansible.cfg néven, amit én használok. Lehet, hogy hasznos lesz.

Mielőtt létrehozná a virtuális gépeket, győződjön meg róla, hogy az ssh-agent fut, és az ssh kulcs hozzá van adva, különben a terraform nem tud csatlakozni a létrehozott gépekhez. Természetesen én is belefutottam egy hibába os x-en: https://github.com/ansible/ansible/issues/32499#issuecomment-341578864. Annak érdekében, hogy ne ismétlődjön meg ilyen történet, a Terraform futtatása előtt adjon hozzá egy kis változót az env-hez:

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

A terrafom mappában létrehozzuk a szükséges erőforrásokat:

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: Az állapot frissítése... [id=enp2g2rhile7gbqlbrkr]
data.yandex_compute_image.ubuntu_image: Az állapot frissítése...
yandex_vpc_subnet.internal-a: Az állapot frissítése... [id=e9b1dad6mgoj2v4funog]

Egy végrehajtási terv készült, amely az alábbiakban látható.
Az erőforrás műveletei a következő szimbólumokkal jelölve:
  + létrehozás

... kihagyva ...

Terv: 3 hozzáadni, 0 megváltoztatni, 0 megsemmisíteni.

... kihagyva ...

Ha minden sikeresen befejeződött (ahogy az lennie kell), három virtuális gépünk lesz:

  1. build — a teszteléshez és az alkalmazás összeállításához használt gép. A Dockert automatikusan telepítette az ansible.
  2. monitoring — a megfigyeléshez használt gép — erre telepítve van a prometheus & grafana. A belépési adatok: admin / admin.
  3. kafka — egy kis gép telepített kafka-val, amely a 9092-es porton érhető el.

Bizonyosodjunk meg róla, hogy mind ott vannak:

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

Az erőforrások a helyén vannak, és innen kinyerhetjük az ip-címeket. Mindenhol használni fogom az ip-címeket az ssh-n keresztüli csatlakozáshoz és az alkalmazás teszteléséhez. Ha van fiókod a cloudflare-en, amely a terraformhoz csatlakozik — nyugodtan használd az újonnan létrehozott DNS-neveket.
Egyébként a virtuális gép létrehozásakor belső ip-t és belső DNS-nevet is kapunk, így a hálózaton belüli szerverekhez név alapján is hozzáférhetünk:

ubuntu@build:~$ ping kafka.ru-central1.internal
PING kafka.ru-central1.internal (172.16.1.31) 56(84) bájt adat.
64 bájt a kafka.ru-central1.internal-tól (172.16.1.31): icmp_seq=1 ttl=63 time=1.23 ms
64 bájt a kafka.ru-central1.internal-tól (172.16.1.31): icmp_seq=2 ttl=63 time=0.625 ms
^C
--- kafka.ru-central1.internal ping statisztikák ---
2 csomag került küldésre, 2 érkezett, 0% csomagveszteség, idő 1001ms
rtt min/avg/max/mdev = 0.625/0.931/1.238/0.308 ms

Ez hasznos lesz számunkra a kafka endpoint-jának megadásához az alkalmazás számára.

Összeállítjuk az alkalmazást

Remek, a szerverek megvannak, az alkalmazás megvan — már csak össze kell állítani és közzé kell tenni. Az összeállításhoz a hagyományos docker build-t fogjuk használni, az image tárhelyeként pedig a yandex szolgáltatását, a container registry-t vesszük igénybe. De mindent a maga helyén.

Átmásoljuk az alkalmazást a build gépre, bejelentkezünk ssh-n keresztül és létrehozzuk a képet:

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

A felével készen vagyunk — most ellenőrizhetjük alkalmazásunk működését, ha elindítjuk és a kafka-ra irányítjuk:

ubuntu@build:~\/app$ sudo docker run --name app -d -p 8080:8080 app \/app\/app -kafka=kafka.ru-central1.internal:9092<\n\nA helyi gépről teszt eseményt küldhetünk, és megnézhetjük a választ:\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) $

Az alkalmazás sikeresen jelezte a felvételt és megadta a partíció és az offset azonosítóját, ahová az üzenet került. Most már csak annyit kell tennünk, hogy létrehozunk egy registry-t az Yandex.Cloud-ban, és feltöltjük oda a képet (hogyan tehetjük ezt három sorral, azt a registry.tf fájl írja le). Hozzuk létre a tárolót:

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

A konténer registry-hez való hitelesítésnek több módja van — oauth token, iam token vagy szolgáltatói fiók kulcs segítségével. Részletesebben ezekről a módszerekről a dokumentációban olvashat. https://cloud.yandex.ru/docs/container-registry/operations/authentication. A szolgáltatói fiók kulcsát fogjuk használni, ezért létrehozunk egy fiókot:

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... skipped ...\n\nApply complete! Resources: 3 added, 0 changed, 0 destroyed.

Most már csak annyira van szükség, hogy készítsünk egy kulcsot:

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

Megkapjuk a tárolónk id-jét, átkonvertáljuk a kulcsot, és bejelentkezünk:

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:~$

A kép regisztrálásához szükségünk lesz a container registry azonosítójára, amelyet az yc segédprogramból kaphatunk:

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

Ezután új névvel jelöljük meg az imázst és feltöltjük:

ubuntu@build:~$ sudo docker tag app cr.yandex/crpdgj6c9umdhgaqjfmm/events:v1
ubuntu@build:~$ sudo docker push cr.yandex/crpdgj6c9umdhgaqjfmm/events:v1
A push a következő repository-ra vonatkozik [cr.yandex/crpdgj6c9umdhgaqjfmm/events]
8c286e154c6e: Feltöltve
477c318b05cb: Feltöltve
beee9f30bc1f: Feltöltve
v1: digest: sha256:1dd5aaa9dbdde2f60d833be0bed1c352724be3ea3158bcac3cdee41d47c5e380 méret: 946

Bizonyosodhatsz arról, hogy az imázs sikeresen feltöltődött:

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

Egyébként, ha telepíted a yc eszközt egy linux gépre, akkor használhatod a parancsot

yc container registry configure-docker

a Docker beállításához.

Zárás

Nagyon sok munkát végeztünk, és ennek eredményeként:

  1. Kidolgoztuk jövőbeli szolgáltatásunk architektúráját.
  2. Megírtuk a golang alkalmazást, amely megvalósítja üzleti logikánkat.
  3. Összegyűjtöttük azt, és elkészítettük egy privát container registry-be.

A következő részben érdekesebbé válik — az alkalmazásunkat a produkciós környezetbe fogjuk küldeni, és végre terhelést indítunk rá. Ne kapcsolj el!

Ez az anyag megtekinthető a REBRAIN & Yandex.Cloud nyílt gyakorlati foglalkozás videójában: 10 000 kérést fogadunk másodpercenként a Yandex Cloud-on — https://youtu.be/cZLezUm0ekE

Ha érdekel, hogy online részt vegyél ilyen eseményeken és valós időben kérdéseket tegyél fel, csatlakozz a DevOps by REBRAIN csatornához.

Külön köszönetet szeretnénk mondani a Yandex.Cloud-nak, hogy lehetőséget biztosítottak egy ilyen esemény lebonyolítására. Itt a linkjük — https://cloud.yandex.ru/prices

Ha felhőbe szeretne költözni, vagy kérdései vannak az infrastruktúrával kapcsolatban, nyugodtan küldje el a jelentkezését..

P.S. Havonta 2 ingyenes auditunk van, lehet, hogy éppen az Ön projektje lesz az egyik.

Forrás: habr.com

Megbízható hosting vásárlása weboldalak számára, DDoS védelemmel, VPS VDS szerverek. 🔥 Megbízható webtárhely vásárlása DDoS védelemmel, VPS VDS szerverek | ProHoster