نحن نقبل 10000 حدث في Yandex.Cloud. الجزء الأول

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



* تمت كتابة هذا المقال بناءً على ورشة العمل المفتوحة 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 فيما بينهم.

الجزء الرابع. سنقوم بنشر مجموعة Clickhouse ، وكتابة الدفق لنقل البيانات من المخزن المؤقت هناك ، وإعداد التصور في البيانات.

الجزء الخامس. دعنا نضع البنية التحتية بأكملها في الشكل المناسب - قم بتكوين ci / cd باستخدام gitlab ci ، وقم بتوصيل المراقبة واكتشاف الخدمة باستخدام Prometheus و consul.



المعارف التقليدية



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



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


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



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







إذن ، ما لدينا:



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



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



  • . , , keepalived, IP .
  • TLS. , TLS . -, , -, , backend .
  • backend . — . , , load balancer’ .


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



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



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



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



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







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



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



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



كتابة طلب



قبل السحابة ، لا يزال يتعين عليك تحمل القليل وكتابة خدمة بسيطة إلى حد ما لمعالجة الأحداث القادمة. سوف نستخدم كلمة 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. يستخدم التطبيق مكتبة سراما ( [] 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 — endpoint, POST json . json — -.


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



بالإضافة إلى جانب التطوير من المشكلة ، فكرنا على الفور في بنيتنا التحتية المستقبلية وقررنا نشر تطبيقنا عبر عامل الإرساء. ملف Docker النهائي لإنشاء التطبيق هو https://github.com/RebrainMe/yandex-cloud-events/blob/master/app/Dockerfile . بشكل عام ، الأمر بسيط للغاية ، النقطة الوحيدة التي أود لفت الانتباه إليها هي التجميع متعدد المراحل ، والذي يسمح لنا بتقليل الصورة النهائية لحاوياتنا.



الخطوات الأولى في السحابة



بادئ ذي بدء ، نسجل في cloud.yandex.ru . بعد ملء جميع الحقول المطلوبة ، سننشئ حسابًا ونمنح منحة بمبلغ معين من المال يمكن استخدامه لاختبار الخدمات السحابية. إذا كنت تريد تكرار جميع الخطوات الواردة في مقالتنا ، فيجب أن تكون هذه المنحة كافية لك.



بعد التسجيل ، سيتم إنشاء سحابة منفصلة ودليل افتراضي لك ، حيث يمكنك البدء في إنشاء موارد السحابة. بشكل عام ، في Yandex.Cloud ، تكون علاقة الموارد كما يلي:







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



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



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



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







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



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



انسخ التطبيق إلى آلة الإنشاء ، وانتقل إلى ssh وجمع الصورة:



vozerov@mba:~/events/terraform (master) $ cd ..
vozerov@mba:~/events (master) $ rsync -av app/ ubuntu@84.201.132.3: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 ubuntu@84.201.132.3:
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. golang, -.
  3. container registry.


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



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





إذا كنت مهتمًا بزيارة مثل هذه الأحداث عبر الإنترنت وطرح الأسئلة في الوقت الفعلي ، فاتصل بالقناة DevOps بواسطة REBRAIN .



نود أن نتقدم بشكر خاص إلى Yandex.Cloud لإتاحة الفرصة لنا لعقد مثل هذا الحدث. الرابط الخاص بهم هو https://cloud.yandex.ru/prices



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



P.S. 2 , , .



All Articles