نقبل 10 حدث في Yandex.Cloud. الجزء 000

مرحبا بالجميع والأصدقاء!

* تستند هذه المقالة إلى ورشة عمل REBRAIN & Yandex.Cloud المفتوحة ، إذا كنت تحب مشاهدة مقاطع الفيديو أكثر ، فيمكنك العثور عليها على هذا الرابط - https://youtu.be/cZLezUm0ekE

في الآونة الأخيرة ، أتيحت لنا الفرصة للشعور بأن Yandex.Cloud يعيش. نظرًا لأننا أردنا أن نشعر لفترة طويلة وبقوة ، فقد تخلينا على الفور عن فكرة بدء مدونة ووردبريس بسيطة بقاعدة سحابية - إنها مملة للغاية. بعد بعض المداولات ، قررنا نشر شيء مشابه لبنية الإنتاج للخدمة لتلقي الأحداث وتحليلها في وضع شبه الوقت الحقيقي.

أنا متأكد تمامًا من أن الغالبية العظمى من الشركات عبر الإنترنت (وليس فقط) تجمع كمًا هائلاً من المعلومات حول مستخدميها وأفعالهم بطريقة أو بأخرى. على الأقل ، يعد هذا ضروريًا لاتخاذ قرارات معينة - على سبيل المثال ، إذا كنت تدير لعبة عبر الإنترنت - يمكنك الاطلاع على إحصائيات حول المستوى الذي من المرجح أن يتعطل المستخدمون فيه ويزيلوا لعبتك. أو لماذا يغادر المستخدمون موقعك دون شراء أي شيء (مرحبًا ، Yandex.Metrica).

إذن ، قصتنا: كيف كتبنا تطبيقًا في golang ، واختبرنا kafka vs rabbitmq vs yqs ، وكتبنا تدفق البيانات إلى مجموعة Clickhouse والبيانات المرئية باستخدام بيانات yandex. وبطبيعة الحال ، كان كل هذا محنكًا بمسرات البنية التحتية في شكل عامل إرساء ، و terraform ، و gitlab ci ، وبالطبع بروميثيوس. دعنا نذهب!

أرغب في إجراء حجز على الفور لأننا لن نتمكن من إعداد كل شيء في جلسة واحدة - لهذا نحتاج إلى عدة مقالات في سلسلة. قليلا عن الهيكل:

الجزء 1 (أنت تقرأه). سنحدد الاختصاصات وبنية الحل ، وكذلك نكتب تطبيقًا بلغة golang.
2 جزء. نقوم بتحميل تطبيقنا إلى الإنتاج ، ونجعله قابلاً للتطوير ونختبر الحمل.
3 جزء. دعنا نحاول معرفة سبب حاجتنا إلى تخزين الرسائل في مخزن مؤقت ، وليس في ملفات ، وكذلك مقارنة خدمة kafka و rabbitmq و yandex queue مع بعضها البعض.
4 جزء. سنقوم بنشر مجموعة Clickhouse ، وكتابة الدفق لنقل البيانات من المخزن المؤقت هناك ، وإعداد التصور في datalens.
5 جزء. دعنا نجعل البنية التحتية بأكملها في الشكل المناسب - قم بإعداد ci / cd باستخدام gitlab ci ، وقم بتوصيل المراقبة واكتشاف الخدمة باستخدام بروميثيوس والقنصل.

TK

أولاً ، لنقم بصياغة الشروط المرجعية - ما نريد تحديدًا الحصول عليه في المخرجات.

  1. نريد أن يكون لدينا نقطة نهاية مثل events.kis.im (kis.im هو مجال الاختبار الذي سنستخدمه في جميع المقالات) التي يجب أن تقبل الأحداث باستخدام HTTPS.
  2. الأحداث عبارة عن صيغة json بسيطة للنموذج: {"event": "view"، "os": "linux"، "browser": "chrome"}. في المرحلة النهائية ، سنضيف المزيد من الحقول ، لكن هذا لن يلعب دورًا كبيرًا. إذا كنت ترغب في ذلك ، يمكنك التبديل إلى protobuf.
  3. يجب أن تكون الخدمة قادرة على معالجة 10 حدث في الثانية.
  4. يجب أن يكون من الممكن التوسع أفقيًا ببساطة عن طريق إضافة مثيلات جديدة إلى حلنا. وسيكون من الرائع أن نتمكن من نقل الجزء الأمامي إلى مواقع جغرافية مختلفة لتقليل زمن الوصول لطلبات العميل.
  5. التسامح مع الخطأ. يجب أن يكون الحل مستقرًا بدرجة كافية وأن يكون قادرًا على البقاء عند سقوط أي جزء (حتى قدر معين ، بالطبع).

هندسة معمارية

بشكل عام ، بالنسبة لهذا النوع من المهام ، تم اختراع البنى الكلاسيكية منذ فترة طويلة والتي تسمح بالتوسع الفعال. يوضح الشكل مثالاً على حلنا.

نقبل 10 حدث في Yandex.Cloud. الجزء 000

اذن ماذا عندنا:

1. على اليسار ، تظهر أجهزتنا ، والتي تولد أحداثًا مختلفة ، سواء كانت تجاوز مستوى اللاعبين في لعبة على هاتف ذكي أو إنشاء طلب في متجر عبر الإنترنت من خلال متصفح عادي. الحدث ، كما هو محدد في TOR ، عبارة عن ملف json بسيط يتم إرساله إلى نقطة النهاية الخاصة بنا - events.kis.im.

2. الخادمان الأولان عبارة عن موازين بسيطة ، مهامهما الرئيسية هي:

  • كن متاحًا باستمرار. للقيام بذلك ، يمكنك استخدام ، على سبيل المثال ، Keepalived ، والذي سيحول IP الظاهري بين العقد في حالة حدوث مشاكل.
  • إنهاء TLS. نعم ، سننهي TLS عليها. أولاً ، بحيث يتوافق حلنا مع TOR ، وثانيًا ، لإزالة عبء إنشاء اتصال مشفر من خوادمنا الخلفية.
  • موازنة الطلبات الواردة إلى خوادم الخلفية المتاحة. الكلمة الرئيسية هنا يمكن الوصول إليها. بناءً على ذلك ، توصلنا إلى أن موازنات التحميل يجب أن تكون قادرة على مراقبة خوادمنا مع التطبيقات والتوقف عن موازنة حركة المرور إلى العقد الفاشلة.

3. خلف الموازين لدينا خوادم تطبيقات تقوم بتشغيل تطبيق بسيط إلى حد ما. يجب أن تكون قادرة على قبول الطلبات الواردة عبر HTTP ، والتحقق من صحة json المرسلة وتخزين البيانات مؤقتًا.

4. يوضح الرسم التخطيطي الكافكة كمخزن مؤقت ، على الرغم من أنه ، بالطبع ، يمكن استخدام خدمات أخرى مماثلة في هذا المستوى. سنقارن كافكا و rabbitmq و yqs في المقال الثالث.

5. النقطة قبل الأخيرة في هندستنا هي Clickhouse - وهي قاعدة بيانات عمودية تسمح لك بتخزين ومعالجة كمية هائلة من البيانات. في هذا المستوى ، نحتاج إلى نقل البيانات من المخزن المؤقت إلى نظام التخزين في الواقع (المزيد عن هذا في المادة 4).

يسمح لنا هذا المخطط بقياس كل طبقة أفقيًا بشكل مستقل. لا تستطيع خوادم الواجهة الخلفية التعامل - دعنا نضيف المزيد - لأنها تطبيقات عديمة الحالة ، وبالتالي ، يمكن القيام بذلك تلقائيًا على الأقل. لا يتم سحب المخزن المؤقت على شكل kafka - فلنضيف المزيد من الخوادم وننقل جزءًا من أقسام موضوعنا إليها. لا يمكن لـ clickhouse التعامل - إنه مستحيل 🙂 في الواقع ، سنقوم أيضًا بإرساء الخوادم وتقسيم البيانات.

بالمناسبة ، إذا كنت ترغب في تنفيذ جزء اختياري من مهمتنا الفنية والتوسع في مواقع جغرافية مختلفة ، فلا يوجد شيء أسهل:

نقبل 10 حدث في Yandex.Cloud. الجزء 000

في كل موقع جغرافي ، نقوم بنشر موازن تحميل مع التطبيق و kafka. بشكل عام ، هناك خادمان للتطبيق و 2 عقد kafka وموازن السحابة ، مثل cloudflare ، كافية ، والتي ستتحقق من توفر عقد التطبيق وطلبات الموازنة حسب الموقع الجغرافي بناءً على عنوان IP المصدر للعميل. بهذه الطريقة ستصل البيانات المرسلة من قبل العميل الأمريكي إلى خوادم الولايات المتحدة. والبيانات من إفريقيا موجودة في إفريقيا.

ثم كل شيء بسيط للغاية - نستخدم أداة المرآة من مجموعة كافكا ونسخ جميع البيانات من جميع المواقع إلى مركز البيانات المركزي الموجود في روسيا. في الداخل ، نقوم بتحليل البيانات ونكتبها إلى Clickhouse لتصور لاحق.

لذلك ، اكتشفنا الهندسة المعمارية - بدأنا في هز Yandex.Cloud!

كتابة طلب

قبل استخدام السحابة ، لا يزال عليك التحلي بالصبر قليلاً وكتابة خدمة بسيطة إلى حد ما لمعالجة الأحداث القادمة. سنستخدم كلمة golang ، لأنها أثبتت نفسها جيدًا كلغة لكتابة تطبيقات الشبكة.

بعد قضاء ساعة من الوقت (ربما بضع ساعات) ، نحصل على شيء مثل هذا: https://github.com/RebrainMe/yandex-cloud-events/blob/master/app/main.go.

ما هي النقاط الرئيسية التي يجب ملاحظتها هنا:

1. عند بدء تشغيل التطبيق ، يمكنك تحديد علامتين. أحدهما مسؤول عن المنفذ الذي سنستمع فيه لطلبات http الواردة (-addr). والثاني لعنوان سيرفر كافكا حيث سنكتب أحداثنا (-كافكا):

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

2. يستخدم التطبيق مكتبة السراما ([] github.com/Shopify/sarama) لإرسال رسائل إلى كتلة الكافكة. قمنا على الفور بتعيين الإعدادات التي تركز على السرعة القصوى للمعالجة:

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

3. أيضًا ، تم تضمين عميل بروميثيوس في تطبيقنا ، والذي يجمع مقاييس مختلفة ، مثل:

  • عدد الطلبات على تطبيقنا ؛
  • عدد الأخطاء عند تنفيذ الطلب (من المستحيل قراءة طلب النشر ، json معطل ، من المستحيل الكتابة إلى kafka) ؛
  • زمن معالجة طلب واحد من العميل ، بما في ذلك وقت كتابة الرسالة إلى كافكا.

4. ثلاث نقاط نهاية يعالجها تطبيقنا:

  • / الحالة - فقط عد موافق لتظهر أننا على قيد الحياة. على الرغم من أنه يمكنك إضافة بعض الشيكات ، مثل مدى توفر مجموعة كافكا.
  • / المقاييس - باستخدام عنوان url هذا ، سيعيد عميل بروميثيوس المقاييس التي جمعها.
  • / post - نقطة النهاية الرئيسية حيث ستأتي طلبات POST مع وجود json بالداخل. يقوم تطبيقنا بفحص json للتحقق من صحتها وإذا كان كل شيء على ما يرام ، فإنه يكتب البيانات إلى مجموعة kafka.

سأحجز أن الشفرة ليست مثالية - يمكن (ويجب!) أن تنتهي. على سبيل المثال ، يمكنك التوقف عن استخدام net / http المدمج والتبديل إلى fasthttp الأسرع. أو اربح وقت المعالجة وموارد وحدة المعالجة المركزية عن طريق نقل فحص صلاحية json إلى مرحلة لاحقة - عندما يتم نقل البيانات من المخزن المؤقت إلى مجموعة clickhouse.

بالإضافة إلى جانب التطوير من المشكلة ، فكرنا على الفور في بنيتنا التحتية المستقبلية وقررنا نشر تطبيقنا من خلال عامل الإرساء. ملف 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. يتم التثبيت بأمر واحد (لنظامي التشغيل 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 والتبديل بينها.

بالإضافة إلى الأساليب المذكورة أعلاه ، كتب فريق 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 - لإنشاء سجلات نظام أسماء النطاقات وتوكيل نطاق events.kis.im الرئيسي بخوادمنا. إذا كنت لا تريد استخدام cloudflare ، فقم بإزالة تهيئة موفر cloudflare في main.tf وملف dns.tf ، وهو المسؤول عن إنشاء سجلات نظام أسماء النطاقات الضرورية.

في عملنا ، سنجمع بين جميع الطرق الثلاثة - واجهة الويب ، والأداة المساعدة لوحدة التحكم ، و terraform.

الشبكات الافتراضية

لكي نكون صادقين ، كان من الممكن تخطي هذه الخطوة ، لأنه عند إنشاء سحابة جديدة ، ستقوم تلقائيًا بإنشاء شبكة منفصلة وثلاث شبكات فرعية - واحدة لكل منطقة توفر. لكن ما زلت أرغب في إنشاء شبكة منفصلة لمشروعنا بعنوانها الخاص. يظهر المخطط العام للشبكة في Yandex.Cloud في الشكل أدناه (مأخوذ بصدق من https://cloud.yandex.ru/docs/vpc/concepts/)

نقبل 10 حدث في Yandex.Cloud. الجزء 000

لذلك ، تقوم بإنشاء شبكة مشتركة يمكن من خلالها أن تتواصل الموارد مع بعضها البعض. لكل منطقة توفر ، يتم إنشاء شبكة فرعية بعنونة خاصة بها ومتصلة بشبكة مشتركة. نتيجة لذلك ، يمكن لجميع موارد السحابة الموجودة فيه التواصل ، حتى في مناطق توافر مختلفة. يمكن للموارد المتصلة بشبكات سحابية مختلفة أن ترى بعضها البعض فقط من خلال عناوين خارجية. بالمناسبة ، كيف يعمل هذا السحر في الداخل ، لقد تم وصفه جيدًا في حديث حبري.

يتم وصف إنشاء الشبكة في ملف network.tf من المستودع. هناك نقوم بإنشاء شبكة خاصة مشتركة داخلية واحدة وربط ثلاث شبكات فرعية بها في مناطق توافر مختلفة - داخلي- أ (172.16.1.0/24) ، داخلي- ب (172.16.2.0/24) ، داخلي- ج (172.16.3.0/24) ).

تهيئة التضاريس وإنشاء الشبكات:

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. وقم بتثبيت الأدوار اللازمة مع المجرة غير المرئية:

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 وإضافة مفتاح ssh ، وإلا فلن يتمكن terraform من الاتصال بالأجهزة التي تم إنشاؤها. بالطبع ، صادفت خطأ في نظام التشغيل X: https://github.com/ansible/ansible/issues/32499#issuecomment-341578864. لمنع مثل هذه القصة من تكرار نفسها ، أضف متغيرًا صغيرًا إلى env قبل بدء Terraform:

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 - Container Registry. لكن أول الأشياء أولاً.

نقوم بنسخ التطبيق إلى آلة البناء ، وننتقل عبر 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) $

استجاب التطبيق بنجاح في الكتابة وإشارة إلى معرف القسم والإزاحة التي سقطت فيها الرسالة. الشيء الوحيد المتبقي هو إنشاء سجل في 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 على جهاز Linux ، فيمكنك استخدام الأمر

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

إذا كنت بحاجة إلى الانتقال إلى السحابة أو كانت لديك أسئلة حول بنيتك التحتية ، لا تتردد في تقديم طلب.

ملاحظة: لدينا عمليتا تدقيق مجانيتان شهريًا ، وربما يكون مشروعك أحدهما.

المصدر: www.habr.com

إضافة تعليق