ما 10 رویداد را در Yandex.Cloud می پذیریم. قسمت 000

سلام به همه دوستان!

* این مقاله بر اساس کارگاه باز REBRAIN & Yandex.Cloud است، اگر ترجیح می دهید ویدیو را تماشا کنید، می توانید آن را در این لینک پیدا کنید - https://youtu.be/cZLezUm0ekE

اخیراً این فرصت را داشتیم که Yandex.Cloud را به صورت زنده امتحان کنیم. از آنجایی که می خواستیم طولانی و سخت کاوش کنیم، بلافاصله ایده راه اندازی یک وبلاگ ساده وردپرس با یک پایگاه ابری را کنار گذاشتیم - خیلی کسل کننده بود. پس از اندکی تفکر، تصمیم گرفتیم چیزی شبیه به معماری خدمات تولید را برای دریافت و تجزیه و تحلیل رویدادها در حالت تقریباً واقعی به کار ببریم.

من کاملاً مطمئن هستم که اکثریت قریب به اتفاق مشاغل آنلاین (و نه تنها) به نوعی کوهی از اطلاعات را در مورد کاربران و اقدامات آنها جمع آوری می کنند. حداقل، این برای تصمیم گیری های خاص ضروری است - به عنوان مثال، اگر یک بازی آنلاین را مدیریت می کنید، می توانید به آماری نگاه کنید که کاربران اغلب در چه سطحی گیر می کنند و اسباب بازی شما را حذف می کنند. یا اینکه چرا کاربران بدون خرید چیزی سایت شما را ترک می کنند (سلام، Yandex.Metrica).

بنابراین، داستان ما: چگونه یک برنامه را به زبان گلنگ نوشتیم، کافکا را در مقابل rabbitmq در مقابل yqs آزمایش کردیم، جریان داده را در یک خوشه Clickhouse نوشتیم و داده ها را با استفاده از yandex datalens تجسم کردیم. طبیعتاً همه اینها با لذت های زیرساختی به شکل docker، terraform، gitlab ci و البته پرومتئوس چاشنی شد. بیا بریم!

من می خواهم فوراً رزرو کنم که نمی توانیم همه چیز را در یک جلسه پیکربندی کنیم - برای این کار به چندین مقاله در مجموعه نیاز خواهیم داشت. کمی در مورد ساختار:

قسمت 1 (شما در حال خواندن آن هستید). ما در مورد مشخصات و معماری راه حل تصمیم خواهیم گرفت و همچنین یک برنامه کاربردی به زبان گلانگ می نویسیم.
قسمت 2. ما برنامه خود را وارد مرحله تولید می کنیم، آن را مقیاس پذیر می کنیم و بار را آزمایش می کنیم.
قسمت 3. بیایید سعی کنیم بفهمیم که چرا باید پیام ها را در یک بافر ذخیره کنیم نه در فایل ها، و همچنین سرویس صف کافکا، rabbitmq و yandex را با هم مقایسه کنیم.
قسمت 4 ما یک خوشه Clickhouse مستقر خواهیم کرد، یک سرویس استریم برای انتقال داده ها از بافر در آنجا می نویسیم، و تجسم را در datalens راه اندازی می کنیم.
قسمت 5 بیایید کل زیرساخت را به شکل مناسبی درآوریم - ci/cd را با استفاده از gitlab ci راه‌اندازی کنیم، نظارت و کشف سرویس را با استفاده از پرومتئوس و کنسول متصل کنیم.

TK

ابتدا، اجازه دهید شرایط مرجع را فرموله کنیم - دقیقاً در نتیجه چه چیزی می خواهیم به دست آوریم.

  1. ما می خواهیم یک نقطه پایانی مانند events.kis.im داشته باشیم (kis.im دامنه آزمایشی است که در تمام مقالات استفاده خواهیم کرد)، که باید رویدادها را با استفاده از HTTPS دریافت کند.
  2. رویدادها یک json ساده هستند مانند: {"رویداد": "نما"، "os": "linux"، "browser": "chrome"}. در مرحله نهایی، ما کمی بیشتر زمینه ها را اضافه خواهیم کرد، اما این نقش مهمی نخواهد داشت. در صورت تمایل می توانید به protobuf تغییر دهید.
  3. این سرویس باید قادر به پردازش 10 رویداد در ثانیه باشد.
  4. می‌توان با افزودن نمونه‌های جدید به راه‌حل، مقیاس افقی را ممکن کرد. و اگر بتوانیم قسمت جلویی را به موقعیت‌های جغرافیایی مختلف منتقل کنیم تا تأخیر درخواست‌های مشتری را کاهش دهیم، خوب خواهد بود.
  5. تحمل خطا. محلول باید به اندازه کافی پایدار باشد و بتواند از سقوط هر قسمتی (البته تا تعداد مشخصی) جان سالم به در ببرد.

معماری

به طور کلی، برای این نوع کارها، معماری های کلاسیک از دیرباز ابداع شده اند که امکان مقیاس بندی کارآمد را فراهم می کنند. شکل نمونه ای از راه حل ما را نشان می دهد.

ما 10 رویداد را در Yandex.Cloud می پذیریم. قسمت 000

بنابراین آنچه داریم:

1. در سمت چپ دستگاه‌های ما هستند که رویدادهای مختلفی را ایجاد می‌کنند، خواه بازیکنانی که سطح یک اسباب‌بازی را در تلفن هوشمند تکمیل می‌کنند یا در یک فروشگاه آنلاین از طریق یک مرورگر معمولی سفارش ایجاد می‌کنند. یک رویداد، همانطور که در مشخصات مشخص شده است، یک json ساده است که به نقطه پایانی ما - events.kis.im ارسال می شود.

2. دو سرور اول متعادل کننده های ساده هستند، وظایف اصلی آنها عبارتند از:

  • دائما در دسترس باشید. برای این کار می‌توانید به عنوان مثال از keepalived استفاده کنید که در صورت بروز مشکل، آی‌پی مجازی را بین گره‌ها تغییر می‌دهد.
  • TLS را خاتمه دهید. بله، ما TLS را به آنها خاتمه می دهیم. اولاً برای اینکه راه حل ما با مشخصات فنی مطابقت داشته باشد و ثانیاً به منظور برداشتن بار ایجاد یک اتصال رمزگذاری شده از سرورهای باطن ما.
  • توازن درخواست های دریافتی به سرورهای باطن موجود. کلمه کلیدی در اینجا قابل دسترسی است. بر این اساس، ما به این درک می رسیم که متعادل کننده های بار باید بتوانند سرورهای ما را با برنامه ها نظارت کنند و تعادل ترافیک به گره های خراب را متوقف کنند.

3. بعد از متعادل کننده ها، سرورهای برنامه داریم که یک برنامه نسبتاً ساده را اجرا می کنند. باید بتواند درخواست های دریافتی را از طریق HTTP بپذیرد، json ارسال شده را تایید کند و داده ها را در یک بافر قرار دهد.

4. نمودار کافکا را به عنوان یک بافر نشان می دهد، البته در این سطح می توان از خدمات مشابه دیگری نیز استفاده کرد. در مقاله سوم به مقایسه کافکا، rabbitmq و yqs خواهیم پرداخت.

5. نقطه ماقبل آخر معماری ما Clickhouse است - یک پایگاه داده ستونی که به شما امکان ذخیره و پردازش حجم عظیمی از داده ها را می دهد. در این سطح، ما باید داده ها را از بافر به خود سیستم ذخیره سازی منتقل کنیم (در این مورد در مقاله 4 بیشتر توضیح داده شده است).

این طراحی به ما اجازه می دهد تا هر لایه را به طور مستقل به صورت افقی مقیاس کنیم. سرورهای Backend نمی توانند با آن کنار بیایند - اجازه دهید یک چیز دیگر اضافه کنیم - به هر حال، آنها برنامه های بدون حالت هستند، و بنابراین، می توان این کار را حتی به صورت خودکار انجام داد. بافر به سبک کافکا کار نمی کند - بیایید سرورهای بیشتری اضافه کنیم و برخی از پارتیشن های موضوع خود را به آنها منتقل کنیم. Clickhouse نمی تواند از عهده آن برآید - غیرممکن است :) در واقع، ما سرورها را نیز به هم متصل می کنیم و داده ها را تقسیم می کنیم.

به هر حال، اگر می خواهید بخش اختیاری مشخصات فنی و مقیاس ما را در موقعیت های جغرافیایی مختلف پیاده سازی کنید، هیچ چیز ساده تر نیست:

ما 10 رویداد را در Yandex.Cloud می پذیریم. قسمت 000

در هر موقعیت جغرافیایی یک بار متعادل کننده با برنامه کاربردی و کافکا را مستقر می کنیم. به طور کلی، 2 سرور برنامه، 3 گره کافکا و یک متعادل کننده ابر، به عنوان مثال، cloudflare کافی است که در دسترس بودن گره های برنامه و درخواست های تعادل را بر اساس موقعیت جغرافیایی بر اساس آدرس IP منبع مشتری بررسی می کند. بنابراین، داده های ارسال شده توسط یک مشتری آمریکایی بر روی سرورهای آمریکایی قرار می گیرد. و داده های آفریقا به زبان آفریقایی است.

سپس همه چیز بسیار ساده است - ما از ابزار آینه ای از مجموعه کافکا استفاده می کنیم و تمام داده ها را از همه مکان ها به مرکز داده مرکزی خود واقع در روسیه کپی می کنیم. در داخل، داده ها را تجزیه می کنیم و برای تجسم بعدی در Clickhouse ثبت می کنیم.

بنابراین، ما معماری را مرتب کردیم - بیایید شروع به تکان دادن Yandex.Cloud کنیم!

نوشتن یک برنامه

قبل از Cloud، هنوز باید کمی صبور باشید و یک سرویس نسبتاً ساده برای پردازش رویدادهای دریافتی بنویسید. ما از golang استفاده خواهیم کرد زیرا به خوبی خود را به عنوان زبانی برای نوشتن برنامه های شبکه ثابت کرده است.

پس از صرف یک ساعت (شاید چند ساعت)، چیزی شبیه به این دریافت می کنیم: https://github.com/RebrainMe/yandex-cloud-events/blob/master/app/main.go.

نکات اصلی که در اینجا می خواهم به آن اشاره کنم چیست:

1. هنگام راه اندازی برنامه، می توانید دو پرچم را مشخص کنید. یکی مسئول پورتی است که در آن به درخواست های http دریافتی (-addr) گوش می دهیم. مورد دوم مربوط به آدرس سرور کافکا است که در آن رویدادهای خود را ثبت خواهیم کرد (-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) برای ارسال پیام به خوشه کافکا. ما بلافاصله تنظیمات را با هدف حداکثر سرعت پردازش تنظیم کردیم:

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

3. برنامه ما همچنین دارای یک کلاینت داخلی پرومتئوس است که معیارهای مختلفی را جمع آوری می کند، مانند:

  • تعداد درخواست ها به برنامه ما؛
  • تعداد خطاها هنگام اجرای درخواست (غیر ممکن برای خواندن درخواست پست، json شکسته، نوشتن به کافکا غیرممکن است).
  • زمان پردازش برای یک درخواست مشتری، از جمله زمان نوشتن پیام به کافکا.

4. سه نقطه پایانی که برنامه ما پردازش می کند:

  • وضعیت / وضعیت - به سادگی ok را برگردانید تا نشان دهید که ما زنده هستیم. اگرچه می‌توانید برخی از بررسی‌ها را اضافه کنید، مانند در دسترس بودن خوشه کافکا.
  • /metrics - طبق این url، مشتری prometheus معیارهایی را که جمع آوری کرده است برمی گرداند.
  • /post نقطه پایانی اصلی است که درخواست‌های POST با json داخل آن ارسال می‌شود. برنامه ما اعتبار json را بررسی می کند و اگر همه چیز خوب باشد، داده ها را در خوشه کافکا می نویسد.

من رزرو می کنم که کد کامل نیست - می تواند (و باید!) تکمیل شود. به عنوان مثال، می توانید استفاده از net/http داخلی را متوقف کنید و به http سریعتر تغییر دهید. یا می توانید با انتقال بررسی اعتبار json به مرحله بعدی - زمانی که داده ها از بافر به خوشه کلیک هاوس منتقل می شوند - زمان پردازش و منابع cpu را به دست آورید.

علاوه بر جنبه توسعه موضوع، بلافاصله به زیرساخت های آینده خود فکر کردیم و تصمیم گرفتیم برنامه خود را از طریق docker مستقر کنیم. Dockerfile نهایی برای ساخت برنامه است https://github.com/RebrainMe/yandex-cloud-events/blob/master/app/Dockerfile. به طور کلی، بسیار ساده است، تنها نکته ای که می خواهم به آن توجه کنم مونتاژ چند مرحله ای است که به ما امکان می دهد تصویر نهایی ظرف خود را کاهش دهیم.

اولین قدم ها در ابر

اول از همه ثبت نام کنید cloud.yandex.ru. پس از پر کردن تمام فیلدهای لازم، یک حساب کاربری ایجاد می شود و به مبلغ مشخصی کمک مالی داده می شود که می تواند برای آزمایش خدمات ابری استفاده شود. اگر می خواهید تمام مراحل مقاله ما را تکرار کنید، این کمک هزینه باید برای شما کافی باشد.

پس از ثبت نام، یک ابر جداگانه و یک فهرست پیش فرض برای شما ایجاد می شود که در آن می توانید شروع به ایجاد منابع ابری کنید. به طور کلی، در Yandex.Cloud، رابطه منابع به این صورت است:

ما 10 رویداد را در Yandex.Cloud می پذیریم. قسمت 000

شما می توانید چندین ابر برای یک حساب ایجاد کنید. و در داخل ابر، دایرکتوری های مختلف برای پروژه های مختلف شرکت ایجاد کنید. شما می توانید در مورد این در اسناد بیشتر بخوانید - https://cloud.yandex.ru/docs/resource-manager/concepts/resources-hierarchy. به هر حال، من اغلب در زیر در متن به آن اشاره خواهم کرد. وقتی کل زیرساخت را از ابتدا تنظیم کردم، اسناد بیش از یک بار به من کمک کرد، بنابراین به شما توصیه می کنم آن را مطالعه کنید.

برای مدیریت ابر، می توانید هم از رابط وب و هم از ابزار کنسول - yc استفاده کنید. نصب با یک دستور (برای لینوکس و مک او اس) انجام می شود:

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

اگر متخصص امنیت داخلی شما در مورد اجرای اسکریپت ها از اینترنت عصبانی است، اولاً می توانید اسکریپت را باز کرده و بخوانید و ثانیاً ما آن را تحت کاربر خود اجرا می کنیم - بدون حقوق ریشه.

اگر می خواهید یک کلاینت برای ویندوز نصب کنید، می توانید از دستورالعمل ها استفاده کنید اینجا و سپس اجرا کنید 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 ایجاد کنید و بین آن‌ها جابه‌جا شوید.

علاوه بر روش های فوق، تیم Yandex.Cloud بسیار خوب نوشت پلاگین برای terraform برای مدیریت منابع ابری به نوبه خود، من یک مخزن git آماده کردم که در آن تمام منابعی که به عنوان بخشی از مقاله ایجاد می شود را شرح دادم - https://github.com/rebrainme/yandex-cloud-events/. ما به شاخه اصلی علاقه مندیم، بیایید آن را به صورت محلی شبیه سازی کنیم:


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 نوشته شده اند. برای شروع، یک فایل private.auto.tfvars در پوشه terraform با محتوای زیر ایجاد کنید:

# 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 گرفت، زیرا ما قبلاً ابزار کنسول را پیکربندی کرده ایم. من به شما توصیه می کنم بلافاصله private.auto.tfvars را به .gitignore اضافه کنید تا به طور تصادفی داده های خصوصی را منتشر نکنید.

در private.auto.tfvars ما همچنین داده هایی را از Cloudflare مشخص کردیم - برای ایجاد رکوردهای DNS و پروکسی دامنه اصلی events.kis.im در سرورهای ما. اگر نمی‌خواهید از cloudflare استفاده کنید، مقدار اولیه ارائه‌دهنده cloudflare را در main.tf و فایل dns.tf را که وظیفه ایجاد رکوردهای dns لازم را بر عهده دارد، حذف کنید.

در کار خود ما هر سه روش را ترکیب خواهیم کرد - رابط وب، ابزار کنسول و terraform.

شبکه های مجازی

صادقانه بگویم، می توانید از این مرحله صرف نظر کنید، زیرا وقتی یک ابر جدید ایجاد می کنید، به طور خودکار یک شبکه جداگانه و 3 زیرشبکه ایجاد خواهید کرد - یکی برای هر منطقه در دسترس بودن. اما ما همچنان دوست داریم یک شبکه مجزا برای پروژه خود با آدرس دهی خودش بسازیم. نمودار کلی نحوه عملکرد شبکه در Yandex.Cloud در شکل زیر نشان داده شده است (صادقانه برگرفته از https://cloud.yandex.ru/docs/vpc/concepts/)

ما 10 رویداد را در Yandex.Cloud می پذیریم. قسمت 000

بنابراین، شما یک شبکه مشترک ایجاد می کنید که در آن منابع می توانند با یکدیگر ارتباط برقرار کنند. برای هر منطقه دسترسی، یک زیر شبکه با آدرس دهی خاص خود ایجاد می شود و به شبکه عمومی متصل می شود. در نتیجه، تمام منابع ابری موجود در آن می توانند با هم ارتباط برقرار کنند، حتی اگر در مناطق در دسترس بودن متفاوت باشند. منابع متصل به شبکه های ابری مختلف فقط از طریق آدرس های خارجی می توانند یکدیگر را ببینند. به هر حال، چگونه این جادو در داخل کار می کند، در هابره به خوبی توصیف شد.

ایجاد شبکه در فایل network.tf از مخزن توضیح داده شده است. در آنجا ما یک شبکه خصوصی مشترک داخلی ایجاد می کنیم و سه زیرشبکه را در مناطق در دسترس متفاوت به آن متصل می کنیم - داخلی-a (172.16.1.0/24)، داخلی-b (172.16.2.0/24)، داخلی-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 که از آن برای ذخیره پیام های دریافتی استفاده می کنیم، نیاز داریم. و ما ماشین دیگری ایجاد خواهیم کرد که در آن پرومته را برای نظارت بر برنامه پیکربندی می کنیم.

ماشین‌های مجازی با استفاده از ansible پیکربندی می‌شوند، بنابراین قبل از شروع terraform، مطمئن شوید که یکی از آخرین نسخه‌های ansible را دارید. و نقش های لازم را با 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

در پوشه با terraform منابع لازم را ایجاد می کنیم:

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. مانیتورینگ - دستگاه مانیتورینگ - پرومتئوس و گرانا روی آن نصب شده است. استاندارد ورود / رمز عبور: admin / admin
  3. کافکا یک ماشین کوچک با کافکا نصب شده است که در پورت 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

این برای ما مفید خواهد بود که نقطه پایانی را با kafk به برنامه نشان دهیم.

مونتاژ برنامه

عالی است، سرورهایی وجود دارد، یک برنامه کاربردی وجود دارد - تنها چیزی که باقی می ماند مونتاژ آن و انتشار آن است. برای ساخت از ساخت داکر معمولی استفاده می کنیم، اما به عنوان ذخیره سازی تصویر از سرویس Yandex - رجیستری کانتینر استفاده می کنیم. اما اول از همه.

ما برنامه را در ماشین ساخت کپی می کنیم، از طریق 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

نیمی از نبرد انجام شده است - اکنون می توانیم عملکرد برنامه خود را با راه اندازی و ارسال آن به کافکا بررسی کنیم:

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

برنامه با موفقیت در ضبط پاسخ داد و شناسه پارتیشن و افستی که پیام در آن گنجانده شده بود را نشان داد. تنها کاری که باید انجام دهید این است که یک رجیستری در Yandex.Cloud ایجاد کنید و تصویر خود را در آنجا آپلود کنید (نحوه انجام این کار با استفاده از سه خط در فایل 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.

چندین راه برای احراز هویت در رجیستری کانتینر وجود دارد - با استفاده از یک نشانه 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

ما اطلاعات مربوط به شناسه فضای ذخیره سازی خود را دریافت می کنیم، کلید را منتقل می کنیم و وارد می شویم:

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

برای آپلود تصویر در رجیستری، به شناسه رجیستری کانتینر نیاز داریم، آن را از ابزار 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 را روی یک ماشین لینوکس نصب کنید، می توانید از دستور استفاده کنید

yc container registry configure-docker

برای پیکربندی داکر

نتیجه

ما کار سختی انجام داده ایم و در نتیجه:

  1. ما به معماری خدمات آینده خود رسیدیم.
  2. ما برنامه ای به زبان گلانگ نوشتیم که منطق تجاری ما را پیاده سازی می کند.
  3. ما آن را جمع آوری کردیم و در یک رجیستری کانتینر خصوصی ریختیم.

در قسمت بعدی، ما به چیزهای جالب می رویم - برنامه خود را در مرحله تولید قرار می دهیم و در نهایت بار را روی آن راه اندازی می کنیم. سوئیچ نکن!

این مطالب در ضبط ویدئویی کارگاه باز REBRAIN & Yandex.Cloud است: ما 10 درخواست در ثانیه در Yandex Cloud می پذیریم - https://youtu.be/cZLezUm0ekE

اگر علاقه مند به شرکت در چنین رویدادهایی به صورت آنلاین و پرسیدن سوالات در زمان واقعی هستید، به آن متصل شوید کانال DevOps توسط REBRAIN.

مایلیم از Yandex.Cloud به خاطر فرصت میزبانی چنین رویدادی تشکر ویژه ای داشته باشیم. پیوند به آنها - https://cloud.yandex.ru/prices

اگر نیاز به انتقال به ابر دارید یا در مورد زیرساخت خود سؤالی دارید، با خیال راحت درخواستی بگذارید.

PS ما 2 ممیزی رایگان در ماه داریم، شاید پروژه شما یکی از آنها باشد.

منبع: www.habr.com

اضافه کردن نظر