Ne pranojmë 10 ngjarje në Yandex.Cloud. Pjesa 000

Përshëndetje të gjithëve, miq!

* Ky artikull bazohet në punëtorinë e hapur REBRAIN & Yandex.Cloud, nëse preferoni ta shikoni videon, mund ta gjeni në këtë lidhje - https://youtu.be/cZLezUm0ekE

Së fundmi patëm mundësinë të provonim Yandex.Cloud live. Meqenëse donim të hetojmë gjatë dhe vështirë, menjëherë braktisëm idenë për të nisur një blog të thjeshtë Wordpress me një bazë cloud - ishte shumë e mërzitshme. Pas disa mendimeve, vendosëm të vendosim diçka të ngjashme me një arkitekturë shërbimi prodhimi për marrjen dhe analizimin e ngjarjeve në modalitetin pothuajse në kohë reale.

Jam absolutisht i sigurt se shumica dërrmuese e bizneseve në internet (dhe jo vetëm) mbledhin disi një mal informacioni rreth përdoruesve dhe veprimeve të tyre. Së paku, kjo është e nevojshme për marrjen e vendimeve të caktuara - për shembull, nëse menaxhoni një lojë në internet, mund të shikoni statistikat në cilin nivel përdoruesit më shpesh ngecin dhe fshijnë lodrën tuaj. Ose pse përdoruesit largohen nga faqja juaj pa blerë asgjë (përshëndetje, Yandex.Metrica).

Pra, historia jonë: si shkruam një aplikacion në golang, testuam kafka kundër rabbitmq vs yqs, shkruam transmetimin e të dhënave në një grupim Clickhouse dhe vizualizuam të dhënat duke përdorur yandex datalens. Natyrisht, e gjithë kjo ishte e kalitur me kënaqësitë e infrastrukturës në formën e docker, terraform, gitlab ci dhe, natyrisht, prometheus. Shkojme!

Do të doja të bëja menjëherë një rezervim që nuk do të jemi në gjendje të konfigurojmë gjithçka në një seancë - për këtë do të na duhen disa artikuj në seri. Pak për strukturën:

Pjesa 1 (po e lexoni). Ne do të vendosim për specifikimet dhe arkitekturën e zgjidhjes, dhe gjithashtu do të shkruajmë një aplikacion në golang.
Pjesa 2. Ne e lëshojmë aplikacionin tonë në prodhim, e bëjmë atë të shkallëzueshëm dhe testojmë ngarkesën.
Pjesa 3. Le të përpiqemi të kuptojmë pse duhet të ruajmë mesazhet në një tampon dhe jo në skedarë, dhe gjithashtu të krahasojmë shërbimin e radhës kafka, rabbitmq dhe yandex.
Pjesa 4 Ne do të vendosim një grupim Clickhouse, do të shkruajmë një shërbim transmetimi për të transferuar të dhëna nga buferi atje dhe do të vendosim vizualizimin në datalens.
Pjesa 5 Le ta sjellim të gjithë infrastrukturën në formën e duhur - të konfigurojmë ci/cd duke përdorur gitlab ci, të lidhim monitorimin dhe zbulimin e shërbimit duke përdorur prometheun dhe konsullin.

TK

Së pari, le të formulojmë termat e referencës - çfarë saktësisht duam të marrim si rezultat.

  1. Ne duam të kemi një pikë fundore si events.kis.im (kis.im është domeni testues që do të përdorim në të gjithë artikujt), i cili duhet të marrë ngjarje duke përdorur HTTPS.
  2. Ngjarjet janë një json e thjeshtë si: {“event”: “view”, “os”: “linux”, “browser”: “chrome”}. Në fazën përfundimtare do të shtojmë edhe pak fusha, por kjo nuk do të luajë një rol të madh. Nëse dëshironi, mund të kaloni në protobuf.
  3. Shërbimi duhet të jetë në gjendje të përpunojë 10 ngjarje në sekondë.
  4. Duhet të jetë e mundur të shkallëzohet horizontalisht duke shtuar thjesht shembuj të rinj në zgjidhjen tonë. Dhe do të jetë mirë nëse mund ta zhvendosim pjesën e përparme në vendndodhje të ndryshme për të reduktuar vonesën për kërkesat e klientëve.
  5. Toleranca ndaj gabimeve. Zgjidhja duhet të jetë mjaft e qëndrueshme dhe të jetë në gjendje t'i mbijetojë rënies së çdo pjese (deri në një numër të caktuar, sigurisht).

Arkitekturë

Në përgjithësi, për këtë lloj detyre, prej kohësh janë shpikur arkitekturat klasike që lejojnë shkallëzim efikas. Figura tregon një shembull të zgjidhjes sonë.

Ne pranojmë 10 ngjarje në Yandex.Cloud. Pjesa 000

Pra, çfarë kemi:

1. Në të majtë janë pajisjet tona që gjenerojnë ngjarje të ndryshme, qofshin lojtarë që plotësojnë një nivel në një lodër në një smartphone ose duke krijuar një porosi në një dyqan online përmes një shfletuesi të rregullt. Një ngjarje, siç specifikohet në specifikim, është një json i thjeshtë që dërgohet në pikën tonë përfundimtare - events.kis.im.

2. Dy serverët e parë janë balancues të thjeshtë, detyrat e tyre kryesore janë:

  • Jini vazhdimisht në dispozicion. Për ta bërë këtë, mund të përdorni, për shembull, keepalived, i cili do të ndërrojë IP virtuale midis nyjeve në rast të problemeve.
  • Përfundo TLS. Po, ne do të mbyllim TLS për to. Së pari, në mënyrë që zgjidhja jonë të përputhet me specifikimet teknike, dhe së dyti, për të lehtësuar barrën e krijimit të një lidhjeje të koduar nga serverët tanë backend.
  • Balanconi kërkesat hyrëse në serverët e disponueshëm të mbështetjes. Fjala kyçe këtu është e arritshme. Bazuar në këtë, ne arrijmë të kuptojmë se balancuesit e ngarkesës duhet të jenë në gjendje të monitorojnë serverët tanë me aplikacione dhe të ndalojnë balancimin e trafikut në nyjet e dështuara.

3. Pas balancuesve, ne kemi serverë aplikacioni që ekzekutojnë një aplikacion mjaft të thjeshtë. Duhet të jetë në gjendje të pranojë kërkesat hyrëse përmes HTTP, të vërtetojë json-in e dërguar dhe të vendosë të dhënat në një buffer.

4. Diagrami tregon kafkën si tampon, megjithëse, sigurisht, shërbime të tjera të ngjashme mund të përdoren në këtë nivel. Ne do të krahasojmë Kafkën, rabbitmq dhe yqs në artikullin e tretë.

5. Pika e parafundit e arkitekturës sonë është Clickhouse - një bazë të dhënash kolone që ju lejon të ruani dhe përpunoni një sasi të madhe të dhënash. Në këtë nivel, ne duhet të transferojmë të dhëna nga buferi në vetë sistemin e ruajtjes (më shumë për këtë në artikullin 4).

Ky dizajn na lejon të shkallëzojmë çdo shtresë në mënyrë të pavarur horizontalisht. Serverët Backend nuk mund të përballojnë - le të shtojmë edhe një gjë - në fund të fundit, ata janë aplikacione pa shtetësi, dhe për këtë arsye, kjo mund të bëhet edhe automatikisht. Buferi i stilit Kafka nuk funksionon - le të shtojmë më shumë serverë dhe të transferojmë disa nga ndarjet e temës sonë tek ata. Clickhouse nuk mund ta trajtojë atë - është e pamundur :) Në fakt, ne gjithashtu do të lidhim serverët dhe do t'i ndajmë të dhënat.

Nga rruga, nëse doni të zbatoni pjesën opsionale të specifikimeve tona teknike dhe shkallës në vendndodhje të ndryshme, atëherë nuk ka asgjë më të thjeshtë:

Ne pranojmë 10 ngjarje në Yandex.Cloud. Pjesa 000

Në çdo gjeolokacion ne vendosim një balancues të ngarkesës me aplikim dhe kafka. Në përgjithësi, mjaftojnë 2 serverë aplikacioni, 3 nyje kafka dhe një balancues cloud, për shembull, cloudflare, i cili do të kontrollojë disponueshmërinë e nyjeve të aplikacionit dhe kërkesat e balancimit sipas gjeolokimit bazuar në adresën IP të burimit të klientit. Kështu, të dhënat e dërguara nga një klient amerikan do të zbresin në serverët amerikanë. Dhe të dhënat nga Afrika janë në Afrikane.

Atëherë gjithçka është mjaft e thjeshtë - ne përdorim mjetin pasqyrë nga grupi Kafka dhe kopjojmë të gjitha të dhënat nga të gjitha vendndodhjet në qendrën tonë qendrore të të dhënave që ndodhet në Rusi. Brenda, ne analizojmë të dhënat dhe i regjistrojmë në Clickhouse për vizualizim të mëvonshëm.

Pra, ne kemi renditur arkitekturën - le të fillojmë të tundim Yandex.Cloud!

Shkrimi i një aplikacioni

Përpara Cloud, duhet të jeni ende pak të durueshëm dhe të shkruani një shërbim mjaft të thjeshtë për të përpunuar ngjarjet në hyrje. Ne do të përdorim golang sepse e ka provuar veten shumë mirë si një gjuhë për të shkruar aplikacione në rrjet.

Pasi kemi kaluar një orë (ndoshta disa orë), marrim diçka si kjo: https://github.com/RebrainMe/yandex-cloud-events/blob/master/app/main.go.

Cilat janë pikat kryesore që do të doja të shënoja këtu:

1. Kur filloni aplikacionin, mund të specifikoni dy flamuj. Njëri është përgjegjës për portin në të cilin do të dëgjojmë kërkesat hyrëse http (-addr). E dyta është për adresën e serverit kafka ku do të regjistrojmë ngjarjet tona (-kafka):

addr     = flag.String("addr", ":8080", "TCP address to listen to")
kafka    = flag.String("kafka", "127.0.0.1:9092", "Kafka endpoints”)

2. Aplikacioni përdor bibliotekën sarama ([] github.com/Shopify/sarama) për të dërguar mesazhe në grupin e kafkave. Ne vendosëm menjëherë cilësimet që synojnë shpejtësinë maksimale të përpunimit:

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

3. Aplikacioni ynë ka gjithashtu një klient të integruar Prometheus, i cili mbledh metrika të ndryshme, si p.sh.

  • numri i kërkesave për aplikacionin tonë;
  • numri i gabimeve gjatë ekzekutimit të kërkesës (e pamundur të lexohet kërkesa për postim, json i prishur, i pamundur t'i shkruash Kafkës);
  • koha e përpunimit për një kërkesë nga klienti, duke përfshirë kohën për t'i shkruar një mesazh Kafkës.

4. Tre pika përfundimtare që përpunon aplikimi ynë:

  • /status - thjesht kthehuni ok për të treguar se jemi gjallë. Edhe pse mund të shtoni disa kontrolle, të tilla si disponueshmëria e grupit Kafka.
  • /metrics - sipas kësaj url, klienti Prometheus do të kthejë metrikat që ka mbledhur.
  • /post është pika kryesore fundore ku do të dërgohen kërkesat POST me json brenda. Aplikacioni ynë kontrollon json për vlefshmërinë dhe nëse gjithçka është në rregull, ai i shkruan të dhënat në grupimin Kafka.

Unë do të bëj një rezervë që kodi nuk është i përsosur - ai mund (dhe duhet!) të plotësohet. Për shembull, mund të ndaloni përdorimin e rrjetit/http të integruar dhe të kaloni në http më të shpejtë. Ose mund të fitoni kohën e përpunimit dhe burimet e procesorit duke zhvendosur kontrollin e vlefshmërisë json në një fazë të mëvonshme - kur të dhënat transferohen nga buferi në grupin e klikimeve.

Përveç anës së zhvillimit të çështjes, ne menjëherë menduam për infrastrukturën tonë të ardhshme dhe vendosëm të vendosim aplikacionin tonë nëpërmjet docker. Dockerfile përfundimtar për ndërtimin e aplikacionit është https://github.com/RebrainMe/yandex-cloud-events/blob/master/app/Dockerfile. Në përgjithësi, është mjaft e thjeshtë, e vetmja pikë që do të doja t'i kushtoja vëmendje është montimi me shumë faza, i cili na lejon të zvogëlojmë imazhin përfundimtar të kontejnerit tonë.

Hapat e parë në re

Para së gjithash, regjistrohuni në cloud.yandex.ru. Pas plotësimit të të gjitha fushave të nevojshme, do të na krijohet një llogari dhe do të na jepet një grant për një shumë të caktuar parash, e cila mund të përdoret për të testuar shërbimet cloud. Nëse dëshironi të përsërisni të gjitha hapat nga artikulli ynë, ky grant duhet të jetë i mjaftueshëm për ju.

Pas regjistrimit, për ju do të krijohet një re e veçantë dhe një direktori e paracaktuar, në të cilën mund të filloni të krijoni burime cloud. Në përgjithësi, në Yandex.Cloud, marrëdhënia e burimeve duket si kjo:

Ne pranojmë 10 ngjarje në Yandex.Cloud. Pjesa 000

Ju mund të krijoni disa re për një llogari. Dhe brenda cloud, krijoni drejtori të ndryshme për projekte të ndryshme kompanish. Ju mund të lexoni më shumë rreth kësaj në dokumentacion - https://cloud.yandex.ru/docs/resource-manager/concepts/resources-hierarchy. Meqë ra fjala, do t'i referohem shpesh më poshtë në tekst. Kur ngrita të gjithë infrastrukturën nga e para, dokumentacioni më ndihmoi më shumë se një herë, ndaj ju këshilloj ta studioni.

Për të menaxhuar renë kompjuterike, mund të përdorni si ndërfaqen e uebit ashtu edhe programin e konsolës - yc. Instalimi kryhet me një komandë (për Linux dhe Mac Os):

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

Nëse specialisti juaj i brendshëm i sigurisë është i tërbuar për ekzekutimin e skripteve nga Interneti, atëherë, së pari, mund ta hapni skriptin dhe ta lexoni atë, dhe së dyti, ne e drejtojmë atë nën përdoruesin tonë - pa të drejta rrënjësore.

Nëse dëshironi të instaloni një klient për Windows, mund të përdorni udhëzimet këtu dhe më pas ekzekutoni yc initpër ta personalizuar plotësisht:

vozerov@mba:~ $ yc init
Welcome! This command will take you through the configuration process.
Please go to https://oauth.yandex.ru/authorize?response_type=token&client_id= in order to obtain OAuth token.

Please enter OAuth token:
Please select cloud to use:
 [1] cloud-b1gv67ihgfu3bp (id = b1gv67ihgfu3bpt24o0q)
 [2] fevlake-cloud (id = b1g6bvup3toribomnh30)
Please enter your numeric choice: 2
Your current cloud has been set to 'fevlake-cloud' (id = b1g6bvup3toribomnh30).
Please choose folder to use:
 [1] default (id = b1g5r6h11knotfr8vjp7)
 [2] Create a new folder
Please enter your numeric choice: 1
Your current folder has been set to 'default' (id = b1g5r6h11knotfr8vjp7).
Do you want to configure a default Compute zone? [Y/n]
Which zone do you want to use as a profile default?
 [1] ru-central1-a
 [2] ru-central1-b
 [3] ru-central1-c
 [4] Don't set default zone
Please enter your numeric choice: 1
Your profile default Compute zone has been set to 'ru-central1-a'.
vozerov@mba:~ $

Në parim, procesi është i thjeshtë - së pari ju duhet të merrni një shenjë oauth për të menaxhuar cloud, zgjidhni renë dhe dosjen që do të përdorni.

Nëse keni disa llogari ose dosje brenda së njëjtës re, mund të krijoni profile shtesë me cilësime të veçanta nëpërmjet krijimit të profilit të konfigurimit yc dhe të kaloni ndërmjet tyre.

Përveç metodave të mësipërme, ekipi Yandex.Cloud shkroi një shumë të mirë plugin për terraform për menaxhimin e burimeve të cloud. Nga ana ime, unë përgatita një depo git, ku përshkrova të gjitha burimet që do të krijohen si pjesë e artikullit - https://github.com/rebrainme/yandex-cloud-events/. Ne jemi të interesuar për degën master, le ta klonojmë atë lokalisht:


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/

Të gjitha variablat kryesore që përdoren në terraform janë shkruar në skedarin main.tf. Për të filluar, krijoni një skedar privat.auto.tfvars në dosjen terraform me përmbajtjen e mëposhtme:

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

Të gjitha variablat mund të merren nga lista e konfigurimit yc, pasi ne kemi konfiguruar tashmë programin e konsolës. Ju këshilloj që menjëherë të shtoni private.auto.tfvars në .gitignore, në mënyrë që të mos publikoni aksidentalisht të dhënat private.

Në private.auto.tfvars ne specifikuam gjithashtu të dhëna nga Cloudflare - për të krijuar regjistrime DNS dhe për të përfaqsuar domenin kryesor events.kis.im në serverët tanë. Nëse nuk dëshironi të përdorni cloudflare, atëherë hiqni inicializimin e ofruesit të cloudflare në main.tf dhe skedarin dns.tf, i cili është përgjegjës për krijimin e regjistrimeve të nevojshme dns.

Në punën tonë ne do të kombinojmë të tre metodat - ndërfaqen në internet, programin e konsolës dhe terraformin.

Rrjetet virtuale

Për të qenë i sinqertë, mund ta kaloni këtë hap, pasi kur krijoni një re të re, automatikisht do të keni një rrjet të veçantë dhe 3 nënrrjeta të krijuara - një për çdo zonë disponueshmërie. Por ne do të dëshironim të krijonim një rrjet të veçantë për projektin tonë me adresimin e tij. Diagrami i përgjithshëm se si funksionon rrjeti në Yandex.Cloud është paraqitur në figurën më poshtë (i marrë sinqerisht nga https://cloud.yandex.ru/docs/vpc/concepts/)

Ne pranojmë 10 ngjarje në Yandex.Cloud. Pjesa 000

Pra, ju krijoni një rrjet të përbashkët brenda të cilit burimet mund të komunikojnë me njëri-tjetrin. Për çdo zonë disponueshmërie, krijohet një nënrrjet me adresimin e vet dhe lidhet me rrjetin e përgjithshëm. Si rezultat, të gjitha burimet e cloud në të mund të komunikojnë, edhe nëse ato janë në zona të ndryshme disponueshmërie. Burimet e lidhura me rrjete të ndryshme cloud mund ta shohin njëri-tjetrin vetëm përmes adresave të jashtme. Nga rruga, si funksionon kjo magji brenda, ishte përshkruar mirë në Habré.

Krijimi i rrjetit përshkruhet në skedarin network.tf nga depoja. Atje krijojmë një rrjet të përbashkët privat të brendshëm dhe lidhim tre nënrrjeta me të në zona të ndryshme disponueshmërie - brendshme-a (172.16.1.0/24), brendshme-b (172.16.2.0/24), brendshme-c (172.16.3.0/24 ).

Inicializoni terraformin dhe krijoni rrjete:

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 ...

Plan: 4 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

yandex_vpc_network.internal: Creating...
yandex_vpc_network.internal: Creation complete after 3s [id=enp2g2rhile7gbqlbrkr]
yandex_vpc_subnet.internal-a: Creating...
yandex_vpc_subnet.internal-b: Creating...
yandex_vpc_subnet.internal-c: Creating...
yandex_vpc_subnet.internal-a: Creation complete after 6s [id=e9b1dad6mgoj2v4funog]
yandex_vpc_subnet.internal-b: Creation complete after 7s [id=e2liv5i4amu52p64ac9p]
yandex_vpc_subnet.internal-c: Still creating... [10s elapsed]
yandex_vpc_subnet.internal-c: Creation complete after 10s [id=b0c2qhsj2vranoc9vhcq]

Apply complete! Resources: 4 added, 0 changed, 0 destroyed.

E shkëlqyeshme! Ne kemi krijuar rrjetin tonë dhe tani jemi gati të krijojmë shërbimet tona të brendshme.

Krijimi i makinave virtuale

Për të testuar aplikacionin, do të na duhet vetëm të krijojmë dy makina virtuale - do të na duhet e para për të ndërtuar dhe ekzekutuar aplikacionin, e dyta për të ekzekutuar kafka, të cilën do ta përdorim për të ruajtur mesazhet në hyrje. Dhe ne do të krijojmë një makinë tjetër ku do të konfigurojmë Prometheus për të monitoruar aplikacionin.

Makinat virtuale do të konfigurohen duke përdorur ansible, kështu që përpara se të filloni terraform, sigurohuni që të keni një nga versionet më të fundit të ansible. Dhe instaloni rolet e nevojshme me galaktikë ansible:

vozerov@mba:~/events/terraform (master) $ cd ../ansible/
vozerov@mba:~/events/ansible (master) $ ansible-galaxy install -r requirements.yml
- cloudalchemy-prometheus (master) is already installed, skipping.
- cloudalchemy-grafana (master) is already installed, skipping.
- sansible.kafka (master) is already installed, skipping.
- sansible.zookeeper (master) is already installed, skipping.
- geerlingguy.docker (master) is already installed, skipping.
vozerov@mba:~/events/ansible (master) $

Brenda dosjes ansible ka një shembull skedar konfigurimi .ansible.cfg që përdor. Mund të jetë e dobishme.

Përpara se të krijoni makina virtuale, sigurohuni që të keni funksionuar agjentin ssh dhe të keni shtuar një çelës ssh, përndryshe terraform nuk do të jetë në gjendje të lidhet me makinat e krijuara. Unë, natyrisht, hasa në një gabim në os x: https://github.com/ansible/ansible/issues/32499#issuecomment-341578864. Për të parandaluar që kjo të ndodhë përsëri, shtoni një variabël të vogël në env përpara se të nisni Terraform:

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

Në dosjen me terraform krijojmë burimet e nevojshme:

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: Refreshing state... [id=enp2g2rhile7gbqlbrkr]
data.yandex_compute_image.ubuntu_image: Refreshing state...
yandex_vpc_subnet.internal-a: Refreshing state... [id=e9b1dad6mgoj2v4funog]

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

... skipped ...

Plan: 3 to add, 0 to change, 0 to destroy.

... skipped ...

Nëse gjithçka përfundoi me sukses (dhe duhet të jetë), atëherë do të kemi tre makina virtuale:

  1. build - një makinë për testimin dhe ndërtimin e një aplikacioni. Docker u instalua automatikisht nga Ansible.
  2. monitorimi - një makineri monitoruese - e instaluar në të prometheus & grafana. Standardi i hyrjes / fjalëkalimit: admin / admin
  3. kafka është një makinë e vogël me kafka të instaluar, e aksesueshme në portin 9092.

Le të sigurohemi që janë të gjitha në vend:

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 |
+----------------------+------------+---------------+---------+---------------+-------------+

Burimet janë në vend, dhe prej këtu mund të marrim adresat e tyre IP. Gjatë gjithë asaj që vijon do të përdor adresat IP për t'u lidhur përmes ssh dhe për të testuar aplikacionin. Nëse keni një llogari cloudflare të lidhur me terraform, mos ngurroni të përdorni emra të sapokrijuar DNS.
Nga rruga, kur krijoni një makinë virtuale, jepet një IP e brendshme dhe një emër i brendshëm DNS, kështu që ju mund të përdorni serverët brenda rrjetit me emër:

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
--- kafka.ru-central1.internal ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.625/0.931/1.238/0.308 ms

Kjo do të jetë e dobishme për ne që t'i tregojmë aplikacionit pikën përfundimtare me kafk.

Montimi i aplikacionit

E shkëlqyeshme, ka serverë, ka një aplikacion - gjithçka që mbetet është ta montoni dhe ta publikoni. Për ndërtimin do të përdorim ndërtimin e zakonshëm të docker-it, por si një ruajtje imazhi do të përdorim një shërbim nga Yandex - regjistri i kontejnerëve. Por gjërat e para së pari.

Ne kopjojmë aplikacionin në makinën e ndërtimit, identifikohemi përmes ssh dhe mbledhim imazhin:

vozerov@mba:~/events/terraform (master) $ cd ..
vozerov@mba:~/events (master) $ rsync -av app/ [email protected]:app/

... skipped ...

sent 3849 bytes  received 70 bytes  7838.00 bytes/sec
total size is 3644  speedup is 0.93

vozerov@mba:~/events (master) $ ssh 84.201.132.3 -l ubuntu
ubuntu@build:~$ cd app
ubuntu@build:~/app$ sudo docker build -t app .
Sending build context to Docker daemon  6.144kB
Step 1/9 : FROM golang:latest AS build
... skipped ...

Successfully built 9760afd8ef65
Successfully tagged app:latest

Gjysma e betejës është bërë - tani mund të kontrollojmë funksionalitetin e aplikacionit tonë duke e lëshuar atë dhe duke e dërguar te kafka:

ubuntu@build:~/app$ sudo docker run --name app -d -p 8080:8080 app /app/app -kafka=kafka.ru-central1.internal:9092</code>

С локальной машинки можно отправить тестовый event и посмотреть на ответ:

<code>vozerov@mba:~/events (master) $ curl -D - -s -X POST -d '{"key1":"data1"}' http://84.201.132.3:8080/post
HTTP/1.1 200 OK
Content-Type: application/json
Date: Mon, 13 Apr 2020 13:53:54 GMT
Content-Length: 41

{"status":"ok","partition":0,"Offset":0}
vozerov@mba:~/events (master) $

Aplikacioni u përgjigj me sukses të regjistrimit dhe duke treguar ID-në e ndarjes dhe kompensimit në të cilin ishte përfshirë mesazhi. Gjithçka që mbetet për të bërë është të krijoni një regjistër në Yandex.Cloud dhe të ngarkoni imazhin tonë atje (si ta bëni këtë duke përdorur tre rreshta përshkruhet në skedarin registry.tf). Krijo një hapësirë ​​ruajtëse:

vozerov@mba:~/events/terraform (master) $ terraform apply -target yandex_container_registry.events

... skipped ...

Plan: 1 to add, 0 to change, 0 to destroy.

... skipped ...

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Ka disa mënyra për të vërtetuar në regjistrin e kontejnerit - duke përdorur një shenjë oauth, një shenjë iam ose një çelës llogarie shërbimi. Më shumë detaje rreth këtyre metodave mund të gjenden në dokumentacion. https://cloud.yandex.ru/docs/container-registry/operations/authentication. Ne do të përdorim çelësin e llogarisë së shërbimit, kështu që krijojmë një llogari:

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

... skipped ...

Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

Tani gjithçka që mbetet është të bëjmë një çelës për të:

vozerov@mba:~/events/terraform (master) $ yc iam key create --service-account-name docker -o key.json
id: ajej8a06kdfbehbrh91p
service_account_id: ajep6d38k895srp9osij
created_at: "2020-04-13T14:00:30Z"
key_algorithm: RSA_2048

Ne marrim informacion në lidhje me ID-në e ruajtjes sonë, transferojmë çelësin dhe identifikohemi:

vozerov@mba:~/events/terraform (master) $ scp key.json [email protected]:
key.json                                                                                                                    100% 2392   215.1KB/s   00:00

vozerov@mba:~/events/terraform (master) $ ssh 84.201.132.3 -l ubuntu

ubuntu@build:~$ cat key.json | sudo docker login --username json_key --password-stdin cr.yandex
WARNING! Your password will be stored unencrypted in /home/ubuntu/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
ubuntu@build:~$

Për të ngarkuar imazhin në regjistër, na duhet ID-ja e regjistrit të kontejnerit, e marrim atë nga programi yc:

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

Pas kësaj, ne etiketojmë imazhin tonë me një emër të ri dhe ngarkojmë:

ubuntu@build:~$ sudo docker tag app cr.yandex/crpdgj6c9umdhgaqjfmm/events:v1
ubuntu@build:~$ sudo docker push cr.yandex/crpdgj6c9umdhgaqjfmm/events:v1
The push refers to repository [cr.yandex/crpdgj6c9umdhgaqjfmm/events]
8c286e154c6e: Pushed
477c318b05cb: Pushed
beee9f30bc1f: Pushed
v1: digest: sha256:1dd5aaa9dbdde2f60d833be0bed1c352724be3ea3158bcac3cdee41d47c5e380 size: 946

Mund të verifikojmë që imazhi është ngarkuar me sukses:

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

Nga rruga, nëse instaloni mjetin yc në një makinë Linux, mund të përdorni komandën

yc container registry configure-docker

për të konfiguruar dokerin.

Përfundim

Kemi bërë shumë punë dhe si rezultat:

  1. Ne dolëm me arkitekturën e shërbimit tonë të ardhshëm.
  2. Ne kemi shkruar një aplikacion në golang që zbaton logjikën tonë të biznesit.
  3. E mblodhëm dhe e derdhëm në një regjistër privat të kontejnerëve.

Në pjesën tjetër, ne do të kalojmë te gjërat interesante - ne do të lëshojmë aplikacionin tonë në prodhim dhe më në fund do të nisim ngarkesën në të. Mos ndërroni!

Ky material është në regjistrimin video të punëtorisë së hapur REBRAIN & Yandex.Cloud: Ne pranojmë 10 kërkesa në sekondë në Yandex Cloud - https://youtu.be/cZLezUm0ekE

Nëse jeni të interesuar të merrni pjesë në ngjarje të tilla në internet dhe të bëni pyetje në kohë reale, lidheni me kanali DevOps nga REBRAIN.

Dëshirojmë t'i themi një falenderim të veçantë Yandex.Cloud për mundësinë për të organizuar një ngjarje të tillë. Lidhja me to - https://cloud.yandex.ru/prices

Nëse keni nevojë të kaloni në cloud ose keni pyetje në lidhje me infrastrukturën tuaj, mos ngurroni të lini një kërkesë.

PS Ne kemi 2 auditime falas në muaj, ndoshta projekti juaj do të jetë njëri prej tyre.

Burimi: www.habr.com

Shto një koment