Приймаємо 10 000 івентів в Яндекс.Хмарі. Частина 1

Привіт усім, друзі!

* Ця стаття написана за мотивами відкритого практикуму REBRAIN & Yandex.Cloud, якщо вам більше подобається дивитися відео, можете знайти його за цим посиланням https://youtu.be/cZLezUm0ekE

Нещодавно нам представилася можливість помацати наживо Яндекс.Хмара. Оскільки мацати хотілося довго і щільно, ми відразу відмовилися від ідеї запуску простого wordpress блогу з хмарною базою — занадто нудно. Після нетривалих роздумів вирішили розгорнути щось схоже на продакшн архітектуру сервісу для прийому та аналізу івентів у near real time режимі.

Я абсолютно впевнений, що переважна більшість онлайн (і не тільки) бізнесів так чи інакше збирають гору інформації про своїх користувачів та їхні дії. Як мінімум, це необхідно для прийняття певних рішень – наприклад, якщо ви керуєте онлайн-грою – то можете подивитися статистику, на якому рівні користувачі найчастіше застрягають та видаляють вашу іграшку. Або чому користувачі йдуть з вашого сайту так нічого і не купивши (привіт, Яндекс.Метрика).

Отже, наша історія: як ми писали програму на golang, тестували kafka vs rabbitmq vs yqs, писали стрімінг даних у Clickhouse кластер і візуалізували дані за допомогою yandex datalens. Природно, все це було приправлено інфраструктурними вишукуваннями як docker, terraform, gitlab ci і, звичайно ж, prometheus. Погнали!

Відразу хочеться обмовитися, що налаштувати все за один раз ми не зможемо — для цього нам знадобиться кілька статей у серії. Трохи про структуру:

1 частина (ви її читаєте). Ми визначимося з ТЗ та архітектурою рішення, а також напишемо додаток на golang.
2 частина. Виливаємо наш додаток на прод, робимо масштабованим та тестуємо навантаження.
3 частина. Спробуємо розібратися, навіщо нам потрібно зберігати повідомлення в буфері, а не у файлах, а також порівняємо між собою kafka, rabbitmq та yandex queue service.
4 частина. Розвертатимемо Clickhouse кластер, писатимемо стрімінг для перекладання туди даних з буфера, налаштуємо візуалізацію в datalens.
5 частина. Наведемо всю інфраструктуру в належний вигляд - налаштуємо ci/cd, використовуючи gitlab ci, підключимо моніторинг та service discovery за допомогою prometheus та consul.

ТЗ

Спершу сформулюємо техзавдання — що ми хочемо отримати на виході.

  1. Ми хочемо мати endpoint виду events.kis.im (kis.im — тестовий домен, який будемо використовувати протягом усіх статей), який має приймати event-и за допомогою HTTPS.
  2. Події - це проста json'ка виду: {"event": "view", "os": "linux", "browser": "chrome"}. На фінальному етапі ми додамо трохи більше полів, але велику роль це не зіграє. Якщо є бажання, можна переключитися на protobuf.
  3. Сервіс має вміти обробляти 10 000 подій на секунду.
  4. Повинна бути можливість масштабуватись горизонтально — простим додаванням нових інстансів у наше рішення. І буде непогано, якщо ми зможемо виносити фронт-частину у різні геолокації для зменшення latency у запитах клієнтів.
  5. Відмовостійкість. Рішення має бути досить стабільним і вміти виживати при падінні будь-яких частин (до певної кількості, звичайно).

Архітектура

Загалом для такого виду завдань давно вигадані класичні архітектури, які дозволяють ефективно масштабуватись. На малюнку наведено приклад нашого рішення.

Приймаємо 10 000 івентів в Яндекс.Хмарі. Частина 1

Отже, що ми маємо:

1. Зліва зображені наші пристрої, які генерують різні події, чи то проходження рівня гравців в іграшці на смартфоні, чи створення замовлення в інтернет-магазині через звичайний браузер. Подія, як зазначено в ТЗ, - простий json, який вирушає на наш endpoint - events.kis.im.

2. Перші два сервери - прості балансувальники, їх основні завдання:

  • Бути постійно доступними. Для цього можна використовувати, наприклад, keepalived, який перемикатиме віртуальний IP між нодами у разі проблем.
  • Термінувати TLS. Так, термінувати TLS ми саме на них. По-перше, щоб наше рішення відповідало ТЗ, а по-друге, для того, щоб зняти навантаження щодо встановлення шифрованого з'єднання з наших backend серверів.
  • Балансувати вхідні запити на доступні backend сервери. Ключове слово тут доступні. Виходячи з цього, ми приходимо до розуміння, що load balancer'и повинні вміти моніторити наші сервери з додатками і переставати балансувати трафік на ноди, що впали.

3. За балансувальниками у нас йдуть application сервера, на яких запущено досить простий додаток. Воно має вміти приймати вхідні запити по HTTP, валідувати надісланий json і складати дані в буфер.

4. Як буфер на схемі зображена kafka, хоча, звичайно, на цьому рівні можна використовувати й інші схожі сервіси. Kafka, rabbitmq та yqs ми порівняємо у третій статті.

5. Передостанньою точкою нашої архітектури є Clickhouse - колонкова база даних, яка дозволяє зберігати та обробляти величезний обсяг даних. На цьому рівні нам необхідно перенести дані з буфера, власне, до системи зберігання (про це — у 4 статті).

Така схема дозволяє незалежно горизонтально масштабувати кожен шар. Не справляються backend сервера - додамо ще - адже вони є stateless додатками, а отже, це можна зробити хоч в автоматичному режимі. Не тягне буфер у вигляді кафки - докинемо ще серверів і перенесемо на них частину партицій нашого топіка. Не справляється клікхаус - це неможливо 🙂 Насправді також докинемо серверів і зашардуємо дані.

До речі, якщо ви захочете реалізувати опціональну частину нашого ТЗ та зробити масштабування у різних геолокаціях, то немає нічого простішого:

Приймаємо 10 000 івентів в Яндекс.Хмарі. Частина 1

У кожній геолокації ми розгортаємо load balancer з application та kafka. Загалом, достатньо 2 application сервера, 3 kafka ноди та хмарного балансувальника, наприклад, cloudflare, який перевірятиме доступність нод програми та балансуватиме запити з геолокацій на основі вихідної IP-адреси клієнта. Таким чином, дані, відправлені американським клієнтом, приземляться на американських серверах. А дані з Африки – на африканських.

Далі все дуже просто - використовуємо mirror tool з набору кафки і копіюємо всі дані з усіх локацій до нашого центрального дата-центру, розташованого в Росії. Всередині ми розбираємо дані та записуємо їх у Clickhouse для подальшої візуалізації.

Отже, з архітектурою розібралися – починаємо хитати Яндекс.Хмара!

Пишемо додаток

До Хмари доведеться ще трохи потерпіти і написати досить простий сервіс для обробки вхідних подій. Використовувати ми будемо golang, тому що він дуже добре зарекомендував себе як мову для написання мережевих додатків.

Витративши годину часу (може, і кілька годин), отримуємо приблизно таку штуку: https://github.com/RebrainMe/yandex-cloud-events/blob/master/app/main.go.

Які основні моменти тут хотілося б відзначити:

1. При старті програми можна вказати два прапори. Один відповідає за порт, на якому ми слухатимемо вхідні http запити (-addr). Друга — за адресу kafka сервера, куди ми будемо записувати наші події (-kafka):

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

2. Додаток використовує бібліотеку sarama ([] github.com/Shopify/sarama) для надсилання повідомлень до kafka кластер. Ми відразу виставили налаштування, орієнтовані на максимальну швидкість обробки:

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

3. Також у наш додаток вбудований клієнт prometheus, який збирає різні метрики, такі як:

  • кількість запитів до нашої програми;
  • кількість помилок при виконанні запиту (неможливо прочитати запит, битий json, неможливо записати в кафку);
  • час обробки одного запиту від клієнта, включаючи час запису повідомлення до кафки.

4. Три endpoint'а, які обробляє наш додаток:

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

Зазначу, що код не ідеальний - його можна (і потрібно!) допилювати. Наприклад, можна відмовитися від використання вбудованого net/http і перейти на більш швидкий fasthttp. Або ж виграти час обробки та cpu ресурси, винісши перевірку валідності json на пізніший етап — коли дані перекладатимуться з буфера в клікхаус кластер.

Крім розробної сторони питання, ми одразу подумали про нашу майбутню інфраструктуру і вирішили розгортати нашу програму через docker. Підсумковий Dockerfile для складання програми https://github.com/RebrainMe/yandex-cloud-events/blob/master/app/Dockerfile. Загалом він досить простий, єдиний момент, на який хочеться звернути увагу, — це multistage складання, яке дозволяє зменшити підсумковий образ нашого контейнера.

Перші кроки у хмарі

Насамперед реєструємось на cloud.yandex.ru. Після заповнення всіх необхідних полів нам створять обліковий запис і видадуть грант на деяку суму грошей, яку можна використовувати для тестування хмарних сервісів. Якщо ви захочете повторити всі кроки нашої статті, цього гранту вам повинно вистачити.

Після реєстрації для вас буде створена окрема хмара та каталог default, у якому можна почати створювати хмарні ресурси. Взагалі в Яндекс.Хмарі взаємозв'язок ресурсів виглядає так:

Приймаємо 10 000 івентів в Яндекс.Хмарі. Частина 1

На один обліковий запис ви можете створити кілька хмар. А усередині хмари зробити різні каталоги для різних проектів компанії. Докладніше про це можна почитати в документації. https://cloud.yandex.ru/docs/resource-manager/concepts/resources-hierarchy. До речі, нижче за текстом я часто на неї посилатимуся. Коли я налаштовував всю інфраструктуру з нуля — документація рятувала мене неодноразово, тож раджу повивчати.

Для керування хмарою можна використовувати як веб-інтерфейс, так і консольну утиліту - yc. Установка виконується однією командою (для Linux та Mac Os):

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

Якщо з приводу запуску скриптів з інтернету всередині вас розбушувався внутрішній безпечник — то, по-перше, можете відкрити скриптик і прочитати його, а по-друге, ми запускаємо його під своїм користувачем без рутових прав.

Якщо ви хочете встановити клієнта для windows, то можна скористатися інструкцією тут і потім виконати yc init, щоб повністю її налаштувати:

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

В принципі, процес нескладний - спочатку потрібно отримати oauth токен для управління хмарою, вибрати хмару та папку, яку будете використовувати.

Якщо у вас є кілька облікових записів або папок всередині однієї хмари, можна створити додаткові профілі з окремими налаштуваннями через yc config profile create і перемикатися між ними.

Крім перерахованих вище способів, команда Яндекс.Хмари написала дуже хороший плагін для terraform для керування хмарними ресурсами. Зі свого боку, я підготував git-репозиторій, де описав усі ресурси, які будуть створені в рамках статті. https://github.com/rebrainme/yandex-cloud-events/. Нас цікавить гілка master, схиляємо її собі локально:


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/

Усі основні змінні, що використовуються в terraform, прописані у файлі main.tf. Для початку роботи створюємо в папці terraform файл private.auto.tfvars такого змісту:

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

Усі змінні можна взяти з yc config list, оскільки консольну утиліту ми вже налаштували. Раджу відразу додати private.auto.tfvars до .gitignore, щоб ненароком не опублікувати приватні дані.

У private.auto.tfvars ми також вказали дані від Cloudflare – для створення dns-записів та проксіювання основного домену events.kis.im на наші сервери. Якщо ви не хочете використовувати cloudflare, видаліть ініціалізацію провайдера cloudflare в main.tf і файл dns.tf, який відповідає за створення необхідних dns записів.

Ми у своїй роботі комбінуватимемо всі три способи — і веб-інтерфейс, і консольну утиліту, і terraform.

Віртуальні мережі

Чесно кажучи, цей крок можна було б пропустити, оскільки при створенні нової хмари у вас автоматично створиться окрема мережа і 3 підмережі — по одній на кожну зону доступності. Але все ж таки хотілося б зробити для нашого проекту окрему мережу зі своєю адресацією. Загальна схема роботи мережі в Яндекс.Хмарі представлена ​​на малюнку нижче (чесно взята з https://cloud.yandex.ru/docs/vpc/concepts/)

Приймаємо 10 000 івентів в Яндекс.Хмарі. Частина 1

Отже, ви створюєте спільну мережу, всередині якої ресурси можуть спілкуватися між собою. Для кожної зони доступності робиться підмережа зі своєю адресацією та підключається до спільної мережі. У результаті всі хмарні ресурси в ній можуть спілкуватися, навіть перебуваючи в різних зонах доступності. Ресурси, підключені до різних мереж, можуть побачити один одного тільки через зовнішні адреси. До речі, як ця магія працює всередині, було добре описано на Хабре.

Створення мережі описано у файлі network.tf із репозиторію. Там ми створюємо одну спільну приватну мережу internal та підключаємо до неї три підмережі у різних зонах доступності — internal-a (172.16.1.0/24), internal-b (172.16.2.0/24), internal-c (172.16.3.0/24) ).

Ініціалізуємо terraform і створюємо мережі:

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.

Чудово! Ми зробили свою мережу, і тепер готові до створення наших внутрішніх сервісів.

Створення віртуальних машин

Для тестування програми нам буде достатньо створити дві віртуалки – перша нам знадобиться для складання та запуску програми, друга – для запуску kafka, яку ми будемо використовувати для зберігання вхідних повідомлень. І створимо ще одну машинку, де налаштуємо prometheus для моніторингу програми.

Налаштовуватись віртуалки будуть за допомогою ansible, так що перед запуском terraform переконайтеся, що у вас стоїть одна з останніх версій ансибла. І встановіть необхідні ролі з 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) $

У папці ansible є приклад конфігураційного файлу .ansible.cfg, який використовую я. Можливо, знадобиться.

Перед тим, як створювати віртуалки, переконайтеся, що у вас запущений ssh-agent і доданий ssh ​​ключик, інакше terraform не зможе підключитися до створених машинок. Я, звичайно, наткнувся на багу в os x: https://github.com/ansible/ansible/issues/32499#issuecomment-341578864. Щоб у вас не повторилася така історія, перед запуском Terraform додайте невелику змінну env:

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

У папці з тераформом створюємо необхідні ресурси:

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

Якщо все завершилося вдало (а так і має бути), то у нас з'являться три віртуальні машини:

  1. build - машинка для тестування та складання програми. Docker був встановлений автоматично ansible'ом.
  2. monitoring – машинка для моніторингу – на неї встановлений prometheus & grafana. Логін/пароль стандартний: admin/admin
  3. kafka - невелика машинка із встановленою kafka, доступна по порту 9092.

Переконаємося, що всі вони на місці:

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

Ресурси на місці, і звідси можемо витягнути їх IP-адреси. Скрізь далі я використовуватиму ip-адреси для підключення по ssh і тестування програми. Якщо у вас є обліковий запис на cloudflare, підключений до terraform, сміливо використовуйте свіжостворені DNS-імена.
До речі, при створенні віртуалці видається внутрішній IP і внутрішнє DNS-ім'я, так що звертатися до серверів всередині мережі можна за іменами:

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

Це нам знадобиться для вказівки додатку endpoint'а з kafk'ою.

Збираємо додаток

Відмінно, сірвачки є, додаток є - залишилося тільки його зібрати та опублікувати. Для складання будемо використовувати звичайний docker build, а ось як сховище образів візьмемо сервіс від яндекса - container registry. Але про все по порядку.

Копіюємо на build машинку додаток, заходимо по ssh і збираємо образ:

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

Півсправи зроблено — тепер можна перевірити працездатність нашої програми, запустивши її та направивши на 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) $

Додаток відповів успіхом запису та вказівкою id партиції та офсету, до якого потрапило повідомлення. Справа за малим - створити registry в Яндекс.Хмарі і закинути туди наш образ (як це зробити за допомогою трьох рядків, описано в файлі registry.tf). Створюємо сховище:

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.

Для аутентифікації в container registry є кілька способів - за допомогою oauth токена, iam токена або ключа сервісного облікового запису. Докладніше про ці способи — у документації https://cloud.yandex.ru/docs/container-registry/operations/authentication. Ми будемо використовувати ключ сервісного облікового запису, тому створюємо обліковий запис:

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.

Тепер залишилося зробити для нього ключик:

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

Отримуємо інформацію про ID нашого сховища, перекидаємо ключ і авторизуємося:

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

Для завантаження образу в реєстр нам знадобиться ID container registry, беремо його з утиліти yc:

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

Після цього тегуємо наш образ новим ім'ям та завантажуємо:

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

Можемо переконатися, що образ успішно завантажився:

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

До речі, якщо ви встановите утиліту yc на машинку з linux, можете використовувати команду

yc container registry configure-docker

для налаштування докеру.

Висновок

Ми виконали велику і важку роботу і в результаті:

  1. Вигадали архітектуру нашого майбутнього сервісу.
  2. Написали програму на golang, яка реалізує нашу бізнес-логіку.
  3. Зібрали його та вилили у приватний container registry.

У наступній частині перейдемо до цікавого - виллємо наш додаток у production і нарешті запустимо на нього навантаження. Не перемикайтеся!

Цей матеріал є у відеозаписі відкритого практикуму REBRAIN & Yandex.Cloud: Приймаємо 10 000 запитів на секунду на Яндекс Хмара https://youtu.be/cZLezUm0ekE

Якщо вам цікаво відвідувати такі заходи онлайн та ставити запитання в режимі реального часу, підключайтесь до каналу DevOps by REBRAIN.

Окреме спасибі хочемо сказати Yandex.Cloud за можливість проведення такого заходу. Посилання на них https://cloud.yandex.ru/prices

Якщо вам потрібен переїзд у хмару або є питання щодо вашої інфраструктури, сміливо залишайте заявку.

PS У нас є 2 безкоштовних аудиту на місяць, можливо, саме ваш проект буде серед них.

Джерело: habr.com

Додати коментар або відгук