Tumatanggap kami ng 10 kaganapan sa Yandex.Cloud. Bahagi 000

Kumusta sa lahat, mga kaibigan!

* Ang artikulong ito ay batay sa REBRAIN & Yandex.Cloud open workshop, kung mas gusto mong panoorin ang video, mahahanap mo ito sa link na ito - https://youtu.be/cZLezUm0ekE

Kamakailan ay nagkaroon kami ng pagkakataong subukan ang Yandex.Cloud nang live. Dahil gusto naming suriin nang matagal at mahirap, agad naming tinalikuran ang ideya ng paglulunsad ng isang simpleng blog ng Wordpress na may cloud base - ito ay masyadong nakakabagot. Pagkatapos ng ilang pag-iisip, nagpasya kaming mag-deploy ng isang bagay na katulad ng isang arkitektura ng serbisyo sa produksyon para sa pagtanggap at pagsusuri ng mga kaganapan sa malapit na real time mode.

Talagang sigurado ako na ang karamihan sa mga online (at hindi lamang) na mga negosyo sa paanuman ay nangongolekta ng isang bundok ng impormasyon tungkol sa kanilang mga user at sa kanilang mga aksyon. Hindi bababa sa, ito ay kinakailangan para sa paggawa ng ilang mga pagpapasya - halimbawa, kung namamahala ka ng isang online na laro, maaari mong tingnan ang mga istatistika kung saan ang antas ng mga gumagamit ay madalas na natigil at nagtatanggal ng iyong laruan. O kung bakit umaalis ang mga user sa iyong site nang hindi bumibili ng anuman (hello, Yandex.Metrica).

Kaya, ang aming kuwento: kung paano kami nagsulat ng application sa golang, sinubukan ang kafka vs rabbitmq vs yqs, nagsulat ng data streaming sa isang Clickhouse cluster at na-visualize ang data gamit ang yandex datalens. Naturally, lahat ng ito ay tinimplahan ng mga kasiyahan sa imprastraktura sa anyo ng docker, terraform, gitlab ci at, siyempre, prometheus. Tara na!

Nais kong agad na gumawa ng isang reserbasyon na hindi namin mai-configure ang lahat sa isang upuan - para dito kakailanganin namin ang ilang mga artikulo sa serye. Kaunti tungkol sa istraktura:

Part 1 (binabasa mo ito). Kami ay magpapasya sa mga pagtutukoy at arkitektura ng solusyon, at magsusulat din ng isang aplikasyon sa golang.
Bahagi 2. Inilabas namin ang aming aplikasyon sa produksyon, ginagawa itong scalable at sinusubukan ang pagkarga.
Bahagi 3. Subukan nating alamin kung bakit kailangan nating mag-imbak ng mga mensahe sa isang buffer at hindi sa mga file, at ihambing din ang serbisyo ng pila ng kafka, rabbitmq at yandex.
Bahagi 4 Magde-deploy kami ng Clickhouse cluster, magsusulat ng streaming service para maglipat ng data mula sa buffer doon, at magse-set up ng visualization sa datalens.
Bahagi 5 Dalhin natin ang buong imprastraktura sa tamang hugis - i-set up ang ci/cd gamit ang gitlab ci, ikonekta ang pagsubaybay at pagtuklas ng serbisyo gamit ang prometheus at consul.

TK

Una, bumalangkas tayo ng mga tuntunin ng sanggunian - kung ano talaga ang gusto nating makuha bilang resulta.

  1. Gusto naming magkaroon ng endpoint tulad ng events.kis.im (kis.im ang pansubok na domain na gagamitin namin sa lahat ng artikulo), na dapat makatanggap ng mga kaganapan gamit ang HTTPS.
  2. Ang mga kaganapan ay isang simpleng json tulad ng: {“event”: “view”, “os”: “linux”, “browser”: “chrome”}. Sa huling yugto ay magdaragdag kami ng kaunti pang mga patlang, ngunit hindi ito gaganap ng malaking papel. Kung gusto mo, maaari kang lumipat sa protobuf.
  3. Ang serbisyo ay dapat na makapagproseso ng 10 mga kaganapan sa bawat segundo.
  4. Posibleng i-scale nang pahalang sa pamamagitan lamang ng pagdaragdag ng mga bagong pagkakataon sa aming solusyon. At magiging maganda kung maaari nating ilipat ang harap na bahagi sa iba't ibang geolocation upang mabawasan ang latency para sa mga kahilingan ng kliyente.
  5. Pagpapahintulot sa kasalanan. Ang solusyon ay dapat na sapat na matatag at magagawang makaligtas sa pagbagsak ng anumang bahagi (hanggang sa isang tiyak na bilang, siyempre).

arkitektura

Sa pangkalahatan, para sa ganitong uri ng gawain, ang mga klasikal na arkitektura ay matagal nang naimbento na nagbibigay-daan sa mahusay na pag-scale. Ang figure ay nagpapakita ng isang halimbawa ng aming solusyon.

Tumatanggap kami ng 10 kaganapan sa Yandex.Cloud. Bahagi 000

Kaya kung ano ang mayroon kami:

1. Sa kaliwa ay ang aming mga device na bumubuo ng iba't ibang mga kaganapan, maging mga manlalaro na kumukumpleto ng isang antas sa isang laruan sa isang smartphone o paggawa ng isang order sa isang online na tindahan sa pamamagitan ng isang regular na browser. Ang isang kaganapan, tulad ng tinukoy sa detalye, ay isang simpleng json na ipinadala sa aming endpoint - events.kis.im.

2. Ang unang dalawang server ay mga simpleng tagabalanse, ang kanilang mga pangunahing gawain ay:

  • Maging palaging magagamit. Upang gawin ito, maaari mong gamitin, halimbawa, keepalived, na magpapalit ng virtual IP sa pagitan ng mga node kung sakaling magkaroon ng mga problema.
  • Wakasan ang TLS. Oo, wawakasan namin ang TLS sa kanila. Una, upang ang aming solusyon ay sumunod sa mga teknikal na detalye, at pangalawa, upang maibsan ang pasanin ng pagtatatag ng naka-encrypt na koneksyon mula sa aming mga backend server.
  • Balansehin ang mga papasok na kahilingan sa mga available na backend server. Ang pangunahing salita dito ay naa-access. Batay dito, nauunawaan namin na ang mga load balancer ay dapat na masubaybayan ang aming mga server gamit ang mga application at ihinto ang pagbabalanse ng trapiko sa mga nabigong node.

3. Pagkatapos ng mga balancer, mayroon kaming mga application server na nagpapatakbo ng medyo simpleng application. Dapat itong tumanggap ng mga papasok na kahilingan sa pamamagitan ng HTTP, patunayan ang ipinadalang json at ilagay ang data sa isang buffer.

4. Ang diagram ay nagpapakita ng kafka bilang isang buffer, bagaman, siyempre, iba pang katulad na mga serbisyo ay maaaring gamitin sa antas na ito. Ihahambing natin ang Kafka, rabbitmq at yqs sa ikatlong artikulo.

5. Ang penultimate point ng aming arkitektura ay Clickhouse - isang columnar database na nagpapahintulot sa iyo na mag-imbak at magproseso ng malaking halaga ng data. Sa antas na ito, kailangan nating ilipat ang data mula sa buffer patungo sa storage system mismo (higit pa tungkol dito sa artikulo 4).

Ang disenyong ito ay nagbibigay-daan sa amin na sukatin ang bawat layer nang hiwalay nang pahalang. Ang mga backend server ay hindi makayanan - magdagdag tayo ng isa pang bagay - pagkatapos ng lahat, ang mga ito ay mga stateless na application, at samakatuwid, maaari itong gawin kahit na awtomatiko. Hindi gumagana ang Kafka-style buffer—magdagdag tayo ng higit pang mga server at ilipat ang ilan sa mga partisyon ng ating paksa sa kanila. Hindi ito kakayanin ng Clickhouse - imposible :) Sa katunayan, ikokonekta rin namin ang mga server at i-shard ang data.

Siyanga pala, kung gusto mong ipatupad ang opsyonal na bahagi ng aming mga teknikal na pagtutukoy at sukat sa iba't ibang geolocation, wala nang mas simple:

Tumatanggap kami ng 10 kaganapan sa Yandex.Cloud. Bahagi 000

Sa bawat geolocation, naglalagay kami ng load balancer na may application at kafka. Sa pangkalahatan, sapat na ang 2 server ng application, 3 kafka node at isang cloud balancer, halimbawa, cloudflare, na susuriin ang pagkakaroon ng mga node ng application at mga kahilingan sa balanse sa pamamagitan ng geolocation batay sa source IP address ng kliyente. Kaya, ang data na ipinadala ng isang kliyenteng Amerikano ay mapupunta sa mga server ng Amerika. At ang data mula sa Africa ay nasa African.

Kung gayon ang lahat ay medyo simple - ginagamit namin ang tool ng salamin mula sa set ng Kafka at kinokopya ang lahat ng data mula sa lahat ng mga lokasyon sa aming sentro ng data center na matatagpuan sa Russia. Sa panloob, pinapa-parse namin ang data at itinatala ito sa Clickhouse para sa kasunod na visualization.

Kaya, inayos namin ang arkitektura - simulan natin ang pag-alog Yandex.Cloud!

Pagsusulat ng aplikasyon

Bago ang Cloud, kailangan mo pa ring maging isang maliit na pasyente at magsulat ng isang medyo simpleng serbisyo upang iproseso ang mga papasok na kaganapan. Gagamitin namin ang golang dahil napatunayan na nito ang sarili bilang isang wika para sa pagsusulat ng mga aplikasyon sa network.

Pagkatapos gumugol ng isang oras (marahil ng ilang oras), nakakakuha kami ng ganito: https://github.com/RebrainMe/yandex-cloud-events/blob/master/app/main.go.

Ano ang mga pangunahing punto na nais kong tandaan dito:

1. Kapag sinimulan ang application, maaari mong tukuyin ang dalawang flag. Ang isa ay responsable para sa port kung saan kami ay makikinig sa mga papasok na kahilingan sa http (-addr). Ang pangalawa ay para sa address ng kafka server kung saan ire-record namin ang aming mga kaganapan (-kafka):

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

2. Ang application ay gumagamit ng sarama library ([] github.com/Shopify/sarama) upang magpadala ng mga mensahe sa kumpol ng kafka. Agad naming itinakda ang mga setting na naglalayong maximum na bilis ng pagproseso:

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

3. Ang aming application ay mayroon ding built-in na prometheus client, na kumukolekta ng iba't ibang sukatan, tulad ng:

  • bilang ng mga kahilingan sa aming aplikasyon;
  • bilang ng mga error kapag isinasagawa ang kahilingan (imposibleng basahin ang kahilingan sa post, sirang json, imposibleng sumulat sa Kafka);
  • oras ng pagproseso para sa isang kahilingan mula sa kliyente, kasama ang oras para sa pagsulat ng mensahe sa Kafka.

4. Tatlong endpoint na pinoproseso ng aming aplikasyon:

  • /status - bumalik lang ng ok para ipakita na buhay tayo. Bagama't maaari kang magdagdag ng ilang mga tseke, tulad ng pagkakaroon ng Kafka cluster.
  • /metrics - ayon sa url na ito, ibabalik ng prometheus client ang mga sukatan na nakolekta nito.
  • Ang /post ay ang pangunahing endpoint kung saan ipapadala ang mga kahilingan ng POST na may json sa loob. Sinusuri ng aming aplikasyon ang json para sa bisa at kung ok ang lahat, isinusulat nito ang data sa kumpol ng Kafka.

Gagawa ako ng reserbasyon na ang code ay hindi perpekto - maaari itong (at dapat!) makumpleto. Halimbawa, maaari mong ihinto ang paggamit ng built-in na net/http at lumipat sa mas mabilis na fasthttp. O maaari kang makakuha ng oras sa pagproseso at mga mapagkukunan ng cpu sa pamamagitan ng paglipat ng json validity check sa isang mas huling yugto - kapag ang data ay inilipat mula sa buffer patungo sa clickhouse cluster.

Bilang karagdagan sa bahagi ng pag-unlad ng isyu, agad naming naisip ang tungkol sa aming hinaharap na imprastraktura at nagpasyang i-deploy ang aming aplikasyon sa pamamagitan ng docker. Ang panghuling Dockerfile para sa pagbuo ng application ay https://github.com/RebrainMe/yandex-cloud-events/blob/master/app/Dockerfile. Sa pangkalahatan, ito ay medyo simple, ang tanging punto na nais kong bigyang pansin ay ang multistage na pagpupulong, na nagpapahintulot sa amin na bawasan ang pangwakas na imahe ng aming lalagyan.

Mga unang hakbang sa ulap

Una sa lahat, magparehistro sa cloud.yandex.ru. Matapos punan ang lahat ng kinakailangang field, gagawa kami ng account at bibigyan kami ng grant para sa isang tiyak na halaga ng pera, na maaaring magamit upang subukan ang mga serbisyo sa cloud. Kung nais mong ulitin ang lahat ng mga hakbang mula sa aming artikulo, dapat na sapat para sa iyo ang grant na ito.

Pagkatapos ng pagpaparehistro, isang hiwalay na ulap at isang default na direktoryo ang gagawin para sa iyo, kung saan maaari kang magsimulang lumikha ng mga mapagkukunan ng ulap. Sa pangkalahatan, sa Yandex.Cloud, ang ugnayan ng mga mapagkukunan ay ganito:

Tumatanggap kami ng 10 kaganapan sa Yandex.Cloud. Bahagi 000

Maaari kang lumikha ng ilang mga ulap para sa isang account. At sa loob ng cloud, gumawa ng iba't ibang mga direktoryo para sa iba't ibang mga proyekto ng kumpanya. Maaari mong basahin ang higit pa tungkol dito sa dokumentasyon - https://cloud.yandex.ru/docs/resource-manager/concepts/resources-hierarchy. Siyanga pala, madalas ko itong ire-refer sa ibaba sa text. Nang i-set up ko ang buong imprastraktura mula sa simula, nakatulong sa akin ang dokumentasyon nang higit sa isang beses, kaya ipinapayo ko sa iyo na pag-aralan ito.

Upang pamahalaan ang cloud, maaari mong gamitin ang parehong web interface at ang console utility - yc. Isinasagawa ang pag-install gamit ang isang utos (para sa Linux at Mac Os):

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

Kung ang iyong panloob na espesyalista sa seguridad ay galit tungkol sa pagpapatakbo ng mga script mula sa Internet, pagkatapos, una, maaari mong buksan ang script at basahin ito, at pangalawa, pinapatakbo namin ito sa ilalim ng aming user - nang walang mga karapatan sa ugat.

Kung gusto mong mag-install ng client para sa Windows, maaari mong gamitin ang mga tagubilin dito at pagkatapos ay isagawa yc initupang ganap na i-customize ito:

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

Sa prinsipyo, simple lang ang proseso - kailangan mo munang kumuha ng oauth token para pamahalaan ang cloud, piliin ang cloud at ang folder na iyong gagamitin.

Kung mayroon kang ilang account o folder sa loob ng parehong cloud, maaari kang lumikha ng mga karagdagang profile na may hiwalay na mga setting sa pamamagitan ng yc config profile na gumawa at lumipat sa pagitan ng mga ito.

Bilang karagdagan sa mga pamamaraan sa itaas, ang koponan ng Yandex.Cloud ay nagsulat ng isang napakahusay plugin para sa terraform para sa pamamahala ng mga mapagkukunan ng ulap. Para sa aking bahagi, naghanda ako ng isang git repository, kung saan inilarawan ko ang lahat ng mga mapagkukunan na gagawin bilang bahagi ng artikulo - https://github.com/rebrainme/yandex-cloud-events/. Interesado kami sa master branch, i-clone natin ito nang lokal:


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/

Ang lahat ng pangunahing variable na ginagamit sa terraform ay nakasulat sa main.tf file. Upang makapagsimula, gumawa ng private.auto.tfvars file sa terraform folder na may sumusunod na nilalaman:

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

Ang lahat ng mga variable ay maaaring kunin mula sa listahan ng yc config, dahil na-configure na namin ang console utility. Ipinapayo ko sa iyo na agad na magdagdag ng private.auto.tfvars sa .gitignore, upang hindi aksidenteng mag-publish ng pribadong data.

Sa private.auto.tfvars, tinukoy din namin ang data mula sa Cloudflare - upang lumikha ng mga DNS record at i-proxy ang pangunahing domain events.kis.im sa aming mga server. Kung ayaw mong gumamit ng cloudflare, pagkatapos ay tanggalin ang pagsisimula ng cloudflare provider sa main.tf at ang dns.tf file, na responsable sa paglikha ng mga kinakailangang dns record.

Sa aming trabaho pagsasamahin namin ang lahat ng tatlong pamamaraan - ang web interface, ang console utility, at terraform.

Mga virtual na network

Sa totoo lang, maaari mong laktawan ang hakbang na ito, dahil kapag lumikha ka ng bagong cloud, awtomatiko kang magkakaroon ng hiwalay na network at 3 subnet ang gagawin - isa para sa bawat availability zone. Ngunit gusto pa rin naming gumawa ng hiwalay na network para sa aming proyekto na may sariling addressing. Ang pangkalahatang diagram ng kung paano gumagana ang network sa Yandex.Cloud ay ipinapakita sa figure sa ibaba (tapat na kinuha mula sa https://cloud.yandex.ru/docs/vpc/concepts/)

Tumatanggap kami ng 10 kaganapan sa Yandex.Cloud. Bahagi 000

Kaya, lumikha ka ng isang karaniwang network kung saan ang mga mapagkukunan ay maaaring makipag-usap sa isa't isa. Para sa bawat availability zone, ang isang subnet ay nilikha gamit ang sarili nitong addressing at konektado sa pangkalahatang network. Bilang resulta, lahat ng cloud resources dito ay maaaring makipag-ugnayan, kahit na sila ay nasa iba't ibang availability zone. Ang mga mapagkukunang konektado sa iba't ibang cloud network ay makikita lamang sa pamamagitan ng mga panlabas na address. Sa pamamagitan ng paraan, paano gumagana ang mahika na ito sa loob, ay mahusay na inilarawan sa Habré.

Ang paglikha ng network ay inilarawan sa network.tf file mula sa repositoryo. Doon ay lumikha kami ng isang karaniwang pribadong network na panloob at ikinonekta ang tatlong subnet dito sa iba't ibang mga availability zone - internal-a (172.16.1.0/24), internal-b (172.16.2.0/24), internal-c (172.16.3.0/24 ).

Magsimula ng terraform at lumikha ng mga network:

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.

Malaki! Nilikha namin ang aming network at handa na kaming lumikha ng aming mga panloob na serbisyo.

Paglikha ng mga virtual machine

Upang subukan ang application, kakailanganin lamang naming lumikha ng dalawang virtual machine - kakailanganin namin ang una upang bumuo at magpatakbo ng application, ang pangalawa upang magpatakbo ng kafka, na gagamitin namin upang mag-imbak ng mga papasok na mensahe. At gagawa kami ng isa pang makina kung saan iko-configure namin ang prometheus para subaybayan ang application.

Ang mga virtual machine ay iko-configure gamit ang ansible, kaya bago simulan ang terraform, siguraduhing mayroon kang isa sa mga pinakabagong bersyon ng ansible. At i-install ang mga kinakailangang tungkulin sa ansible galaxy:

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) $

Sa loob ng ansible folder ay may isang halimbawa ng .ansible.cfg configuration file na ginagamit ko. Maaaring magamit ito.

Bago gumawa ng mga virtual machine, tiyaking mayroon kang ssh-agent na tumatakbo at may idinagdag na ssh key, kung hindi, hindi makakakonekta ang terraform sa mga nilikhang machine. Ako, siyempre, ay nakatagpo ng isang bug sa os x: https://github.com/ansible/ansible/issues/32499#issuecomment-341578864. Upang maiwasan itong mangyari muli, magdagdag ng isang maliit na variable sa env bago ilunsad ang Terraform:

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

Sa folder na may terraform lumikha kami ng mga kinakailangang mapagkukunan:

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

Kung matagumpay na natapos ang lahat (at dapat na), magkakaroon tayo ng tatlong virtual machine:

  1. build - isang makina para sa pagsubok at pagbuo ng isang application. Ang Docker ay awtomatikong na-install ng Ansible.
  2. monitoring - isang monitoring machine - prometheus & grafana na naka-install dito. Pamantayan sa pag-login / password: admin / admin
  3. Ang kafka ay isang maliit na makina na may naka-install na kafka, naa-access sa port 9092.

Siguraduhin nating lahat sila ay nasa lugar:

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

Ang mga mapagkukunan ay nasa lugar, at mula dito maaari naming makuha ang kanilang mga IP address. Sa lahat ng mga sumusunod ay gagamit ako ng mga IP address upang kumonekta sa pamamagitan ng ssh at subukan ang application. Kung mayroon kang cloudflare account na nakakonekta sa terraform, huwag mag-atubiling gumamit ng mga bagong likhang pangalan ng DNS.
Sa pamamagitan ng paraan, kapag lumilikha ng isang virtual machine, isang panloob na IP at isang panloob na pangalan ng DNS ay ibinigay, upang ma-access mo ang mga server sa loob ng network ayon sa pangalan:

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

Ito ay magiging kapaki-pakinabang para sa amin upang ipahiwatig sa application ang endpoint na may kafk.

Pagtitipon ng aplikasyon

Mahusay, may mga server, mayroong isang application - ang natitira ay upang tipunin ito at i-publish ito. Para sa build gagamitin namin ang karaniwang docker build, ngunit bilang isang imbakan ng imahe gagamit kami ng isang serbisyo mula sa Yandex - container registry. Ngunit una sa lahat.

Kinopya namin ang application sa build machine, mag-log in sa pamamagitan ng ssh at tipunin ang imahe:

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

Ang kalahati ng labanan ay tapos na - ngayon maaari naming suriin ang pag-andar ng aming application sa pamamagitan ng paglulunsad nito at pagpapadala nito sa 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) $

Ang application ay tumugon sa tagumpay ng pag-record at nagpapahiwatig ng id ng partition at offset kung saan kasama ang mensahe. Ang natitira pang gawin ay lumikha ng isang registry sa Yandex.Cloud at i-upload ang aming larawan doon (kung paano ito gawin gamit ang tatlong linya ay inilarawan sa registry.tf file). Gumawa ng storage:

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.

Mayroong ilang mga paraan upang mag-authenticate sa container registry - gamit ang isang oauth token, isang iam token, o isang service account key. Higit pang mga detalye tungkol sa mga pamamaraang ito ay matatagpuan sa dokumentasyon. https://cloud.yandex.ru/docs/container-registry/operations/authentication. Gagamitin namin ang service account key, kaya gumawa kami ng account:

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.

Ngayon ang natitira na lang ay gumawa ng susi para dito:

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

Nakatanggap kami ng impormasyon tungkol sa id ng aming imbakan, ilipat ang susi at mag-log in:

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

Upang i-upload ang larawan sa registry, kailangan namin ang container registry ID, kinuha namin ito mula sa yc utility:

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

Pagkatapos nito, i-tag namin ang aming larawan ng isang bagong pangalan at i-upload:

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

Maaari naming i-verify na matagumpay na na-load ang larawan:

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

Sa pamamagitan ng paraan, kung i-install mo ang yc utility sa isang Linux machine, maaari mong gamitin ang command

yc container registry configure-docker

upang i-configure ang docker.

Konklusyon

Nakagawa kami ng maraming pagsusumikap at bilang isang resulta:

  1. Nakabuo kami ng arkitektura ng aming serbisyo sa hinaharap.
  2. Sumulat kami ng isang application sa golang na nagpapatupad ng aming lohika sa negosyo.
  3. Kinokolekta namin ito at ibinuhos sa isang pribadong pagpapatala ng lalagyan.

Sa susunod na bahagi, magpapatuloy kami sa mga kawili-wiling bagay - ilalabas namin ang aming aplikasyon sa produksyon at sa wakas ay ilulunsad ang pagkarga dito. Huwag lumipat!

Ang materyal na ito ay nasa pag-record ng video ng bukas na workshop REBRAIN & Yandex.Cloud: Tumatanggap kami ng 10 kahilingan bawat segundo sa Yandex Cloud - https://youtu.be/cZLezUm0ekE

Kung interesado kang dumalo sa mga ganitong kaganapan online at magtanong sa real time, kumonekta sa channel ng DevOps ng REBRAIN.

Nais naming magsabi ng espesyal na pasasalamat sa Yandex.Cloud para sa pagkakataong mag-host ng naturang kaganapan. Link sa kanila - https://cloud.yandex.ru/prices

Kung kailangan mong lumipat sa cloud o may mga tanong tungkol sa iyong imprastraktura, huwag mag-atubiling mag-iwan ng kahilingan.

PS Mayroon kaming 2 libreng pag-audit bawat buwan, marahil ang iyong proyekto ay isa sa kanila.

Pinagmulan: www.habr.com

Magdagdag ng komento