أول خدمة في البدوي الأولى أطلقت في سبتمبر 2016. في الوقت الحالي ، استخدمه كمبرمج ودعم كمسؤول عن مجموعتي Nomad - أحدهما "منزلي" لمشاريعي الشخصية (6 أجهزة افتراضية صغيرة في Hetzner Cloud و ArubaCloud في 5 مراكز بيانات مختلفة في أوروبا) والثاني يعمل واحدًا (حوالي 40 خادمًا فعليًا وماديًا خاصًا) في اثنين من مراكز البيانات).
على مر الزمن الماضي ، تراكمت الكثير من الخبرة مع بيئة نوماد ، في المقال سوف أصف المشاكل التي واجهتها نوماد وكيفية التعامل معها.

يجعل Yamal nomad خدمة التسليم المستمر كمثال لبرنامج National Geographic Russia
1. عدد عقد الخادم لكل مركز بيانات
الحل: عقدة خادم واحدة تكفي لمركز بيانات واحد.
لا تشير الوثائق بوضوح إلى عدد عقد الخادم المطلوبة في مركز بيانات واحد. يشار فقط إلى أن هناك حاجة إلى 3-5 العقد لكل منطقة ، وهو أمر منطقي لتوافق بروتوكول الطوافة.

في البداية ، خططت لعقد 2-3 خوادم في كل مركز بيانات لتوفير التكرار.
عند استخدامه اتضح:
- هذا ببساطة غير مطلوب ، لأنه في حالة فشل العقدة في مركز البيانات ، سيتم لعب دور عقدة الخادم لوكلاء مركز البيانات هذا بواسطة عقدات خادم أخرى في المنطقة.
- اتضح أنه إذا لم يتم حل المشكلة 8. عند إعادة انتخاب المعالج ، يمكن أن تحدث حالات عدم تناسق وسيعاد Nomad إعادة تشغيل جزء من الخدمات.
2. موارد الخادم لعقدة الخادم
الحل: جهاز ظاهري صغير يكفي لعقدة الخادم. على نفس الخادم ، يُسمح بتشغيل خدمات أخرى غير كثيفة الاستخدام للموارد.
يعتمد استهلاك ذاكرة البرنامج الخفي على عدد المهام قيد التشغيل. استهلاك وحدة المعالجة المركزية - استنادًا إلى عدد المهام وعدد الخوادم / الوكلاء في المنطقة (وليس خطيًا).
في حالتنا: بالنسبة لـ 300 مهمة قيد التشغيل ، يبلغ استهلاك الذاكرة حوالي 500 ميجابايت للعقدة الرئيسية الحالية.
في مجموعة العمل ، جهاز افتراضي لعقدة الخادم: 4 وحدة المعالجة المركزية ، 6 جيجابايت من ذاكرة الوصول العشوائي.
أطلقت بالإضافة إلى ذلك: القنصل ، Etcd ، المدفن.
3. إجماع على نقص مراكز البيانات
الحل: نصنع ثلاثة مراكز بيانات افتراضية وثلاثة عقد خادم لمركزين للبيانات الفعلية.
يعتمد عمل نوماد في المنطقة على بروتوكول الطوافة. للتشغيل الصحيح ، تحتاج إلى 3 عقد خادم على الأقل في مراكز بيانات مختلفة. سيمكن هذا العملية الصحيحة مع فقد كامل للاتصال بالشبكة مع أحد مراكز البيانات.
ولكن لدينا اثنين فقط من مراكز البيانات. نتوصل إلى حل وسط: نختار مركز بيانات ، نثق به أكثر ، ونصنع عقدة خادم إضافية فيه. نقوم بذلك عن طريق إدخال مركز بيانات افتراضي إضافي ، والذي سيكون موجودًا فعليًا في نفس مركز البيانات (انظر الفقرة الفرعية 2 من المشكلة 1).
الحل البديل: نقسم مراكز البيانات إلى مناطق منفصلة.
ونتيجة لذلك ، تعمل مراكز البيانات بشكل مستقل ولا يلزم الإجماع إلا داخل مركز بيانات واحد. داخل مركز البيانات ، في هذه الحالة ، من الأفضل إنشاء 3 وحدات خادم عن طريق تطبيق ثلاثة مراكز بيانات افتراضية في واحدة فعلية.
هذا الخيار أقل ملاءمة لتوزيع المهام ، ولكنه يوفر ضمانًا بنسبة 100٪ لاستقلالية الخدمات في حالة حدوث مشاكل في الشبكة بين مراكز البيانات.
4. "الخادم" و "الوكيل" على نفس الخادم
الحل: صالح إذا كان لديك عدد محدود من الخوادم.
الوثائق البدوية تقول أن القيام بذلك أمر غير مرغوب فيه. ولكن إذا لم تكن لديك الفرصة لتخصيص أجهزة افتراضية منفصلة لعُقد الخادم ، فيمكنك وضع الخوادم وعقد الوكلاء على نفس الخادم.
التشغيل في نفس الوقت يعني بدء تشغيل البرنامج الخفي للبدائل في وضع العميل ووضع الخادم.
ماذا يهدد هذا؟ مع الحمل الثقيل على وحدة المعالجة المركزية لهذا الخادم ، ستعمل عقدة خادم Nomad بشكل غير مستقر ، وفقدان الإجماع ونبضات القلب ، وعمليات إعادة تحميل الخدمة ممكنة.
لتجنب ذلك ، نقوم بزيادة الحدود من وصف المشكلة رقم 8.
5. تنفيذ مساحات الأسماء
الحل: ربما من خلال تنظيم مركز بيانات افتراضي.
في بعض الأحيان تحتاج إلى تشغيل جزء من الخدمات على خوادم منفصلة.
الحل هو الأول ، البسيط ، ولكنه أكثر طلبًا على الموارد. نقسم جميع الخدمات إلى مجموعات وفقًا للغرض منها: الواجهة الأمامية ، الواجهة الخلفية ، ... إضافة سمات وصفية إلى الخوادم ، ووصف الخصائص المراد تشغيلها لجميع الخدمات.
الحل الثاني بسيط. نضيف خوادم جديدة ، ونصف سمات التعريف الخاصة بها ، ونصف سمات الإطلاق هذه على الخدمات الضرورية ، بينما تفرض جميع الخدمات الأخرى حظراً على التشغيل على الخوادم بهذه السمة.
الحل الثالث معقد. نقوم بإنشاء مركز بيانات افتراضي: قم بإطلاق القنصل لمركز بيانات جديد ، وإطلاق عقدة خادم Nomad لمركز البيانات هذا ، دون أن ننسى عدد عقد الخادم لهذه المنطقة. يمكنك الآن تشغيل الخدمات الفردية في مركز البيانات الافتراضي المخصص هذا.
6. التكامل مع المدفن
الحل: تجنب البدوي <-> قبو دائرية التبعيات.
لا ينبغي أن تحتوي Vault Launched على أي تبعيات على Nomad. يفضل أن يشير عنوان Vault المسجّل في Nomad مباشرةً إلى Vault ، دون طبقات من الموازنات (ولكن صالحة). يمكن إجراء حجز المدفن في هذه الحالة عبر DNS - قنصل DNS أو خارجي.
إذا تمت كتابة بيانات Vault في ملفات التكوين Nomad ، فإن Nomad يحاول الوصول إلى Vault عند بدء التشغيل. إذا كان الوصول غير ناجح ، فإن Nomad يرفض البدء.
لقد ارتكبت خطأً بسبب التبعية الدورية منذ فترة طويلة ، وهذا ما أدى إلى تدمير مجموعة البدوي لفترة وجيزة تقريبًا. تم إطلاق Vault بشكل صحيح ، بغض النظر عن Nomad ، لكن Nomad نظر إلى عنوان Vault من خلال الموازنات التي كانت تعمل في Nomad نفسها. تسببت إعادة تكوين وإعادة تشغيل عقد خادم Nomad في إعادة تشغيل خدمات الموازن ، مما أدى إلى فشل في بدء عقد الخادم بنفسه.
7. إطلاق خدمات حكومية مهمة
الحل: صحيح ، لكنني لا.
هل من الممكن تشغيل PostgreSQL ، ClickHouse ، Redis Cluster ، RabbitMQ ، MongoDB عبر Nomad؟
تخيل أن لديك مجموعة من الخدمات المهمة ، التي يرتبط عملها بمعظم الخدمات الأخرى. على سبيل المثال ، قاعدة بيانات في PostgreSQL / ClickHouse. أو التخزين العام على المدى القصير في Redis Cluster / MongoDB. أو ناقل بيانات في Redis Cluster / RabbitMQ.
جميع هذه الخدمات في شكل ما تنفذ مخططًا للتسامح مع الأخطاء: Stolon / Patroni for PostgreSQL ، وتنفيذ مجموعة خاصة بها في Redis Cluster ، وتنفيذ نظام المجموعة الخاص بها في RabbitMQ و MongoDB و ClickHouse.
نعم ، يمكن إطلاق كل هذه الخدمات من خلال Nomad بالإشارة إلى خوادم محددة ، ولكن لماذا؟
بالإضافة إلى - سهولة التشغيل ، تنسيق نصي واحد ، مثل الخدمات الأخرى. لا داعي للقلق مع البرامج النصية ansible / أي شيء آخر.
ناقص هو نقطة إضافية من الفشل ، والتي لا تعطي أي مزايا. أنا شخصياً أسقطت مجموعة نوماد بالكامل مرتين لأسباب مختلفة: مرة واحدة "المنزل" ، بمجرد العمل. كان هذا في المراحل الأولى من تقديم نوماد وبسبب الركود.
أيضًا ، يبدأ Nomad في التصرف بشكل سيئ وإعادة تشغيل الخدمات بسبب المشكلة رقم 8. لكن حتى لو تم حل هذه المشكلة ، يبقى الخطر قائماً.
8. إعادة تثبيت العمل والخدمة في شبكة غير مستقرة
الحل: استخدم خيارات ضبط نبضات القلب.
بشكل افتراضي ، يتم تكوين Nomad بحيث تتسبب أي مشكلة في الشبكة على المدى القصير أو تحميل وحدة المعالجة المركزية في فقدان التوافق وإعادة انتخاب المعالج أو وضع علامة على عميل الوسيلة غير قابلة للوصول. وهذا يؤدي إلى إعادة تشغيل عفوية للخدمات ونقلها إلى العقد الأخرى.
إحصائيات نظام المجموعة "home" قبل إصلاح المشكلة: يبلغ الحد الأقصى لعمر الحاوية قبل إعادة التشغيل حوالي 10 أيام. هنا ، لا يزال الأمر مثقلًا بتشغيل الوكيل والخادم على خادم واحد ووضعه في 5 مراكز بيانات مختلفة في أوروبا ، مما يعني وجود حمل كبير على وحدة المعالجة المركزية وشبكة أقل استقرارًا.
إحصائيات كتلة العمل قبل إصلاح المشكلة: الحد الأقصى لعمر الحاوية قبل إعادة التشغيل أكثر من شهرين. كل شيء جيد نسبياً هنا بسبب الخوادم المنفصلة لعُقد خادم Nomad والشبكة الممتازة بين مراكز البيانات.
القيم الافتراضية
heartbeat_grace = "10s" min_heartbeat_ttl = "10s" max_heartbeats_per_second = 50.0
اذا حكمنا من خلال الكود: في هذا التكوين ، يتم إجراء نبضة القلب كل 10 ثوانٍ. مع فقدان اثنين من نبضات القلب ، تبدأ إعادة انتخاب السيد أو نقل الخدمات من عقدة الوكيل. الإعدادات المثيرة للجدل ، في رأيي. نقوم بتحريرها حسب التطبيق.
إذا كانت لديك جميع الخدمات التي تعمل في حالات متعددة وقمت بتوزيعها بواسطة مراكز البيانات ، فعلى الأرجح ، لا يهمك فترة طويلة لتحديد عدم إمكانية الوصول إلى الخادم (حوالي 5 دقائق ، في المثال أدناه) - نحن نجعل الفترة الزمنية لنبضات القلب أقل تكرارًا وفترة أطول من تحديد إمكانية الوصول. هذا مثال على إعداد نظام المجموعة المنزلية:
heartbeat_grace = "300s" min_heartbeat_ttl = "30s" max_heartbeats_per_second = 10.0
إذا كان لديك اتصال جيد بالشبكة ، فإن الخوادم المنفصلة لعقد الخادم ، وفترة تحديد عدم إمكانية الوصول إلى الخادم مهمة (هناك بعض الخدمات قيد التشغيل في حالة واحدة ومن المهم نقلها بسرعة) ، ثم زيادة فترة تحديد عدم إمكانية الوصول (heartbeat_grace). اختياريا ، يمكنك القيام بمزيد من نبضات القلب (عن طريق تقليل min_heartbeat_ttl) - سيؤدي ذلك إلى زيادة الحمل على وحدة المعالجة المركزية بشكل طفيف. مثال تكوين كتلة العمل:
heartbeat_grace = "60s" min_heartbeat_ttl = "10s" max_heartbeats_per_second = 50.0
هذه الإعدادات حل المشكلة تماما.
9. بدء المهام الدورية
الحل: يمكن استخدام خدمات Nomad الدورية ، ولكن cron هو أكثر ملاءمة للدعم.
البدوي لديه القدرة على إطلاق الخدمة بشكل دوري.
زائد فقط هو بساطة هذا التكوين.
أول ناقص هو أنه إذا بدأت الخدمة بشكل متكرر ، فسوف تتناثر قائمة المهام. على سبيل المثال ، عند بدء التشغيل كل 5 دقائق ، ستتم إضافة 12 مهمة إضافية إلى القائمة كل ساعة ، حتى يتم تشغيل GC Nomad ، مما يؤدي إلى حذف المهام القديمة.
الثاني ناقص - ليس من الواضح كيفية تكوين مراقبة مثل هذه الخدمة بشكل صحيح. كيف نفهم أن الخدمة تبدأ وتفي وتؤدي مهمتها حتى النهاية؟
كنتيجة لذلك ، توصلت إلى تنفيذ "المهام" الدورية للمهام الدورية:
- يمكن أن يكون كرون منتظم في حاوية تعمل باستمرار. يعمل Cron بشكل دوري على برنامج نصي معين. يضاف بسهولة التحقق من صحة البرنامج النصي إلى مثل هذه الحاوية ، والتي تتحقق من أي علامة تقوم بإنشاء برنامج نصي قيد التشغيل.
- يمكن أن يكون حاوية تعمل باستمرار ، مع خدمة تشغيل مستمر. تم تنفيذ عملية إطلاق دورية بالفعل داخل الخدمة. يمكن بسهولة إما إضافة فحص صحة نصي أو http-healthcheck بسهولة إلى هذه الخدمة ، التي تتحقق من الحالة فورًا بواسطة "الدواخل".
في الوقت الحالي أكتب في معظم الأوقات في Go ، على التوالي ، أفضل الخيار الثاني مع http healthcheck - on Go والإطلاق الدوري ، ويتم إضافة http healthcheck'i مع بضعة أسطر من التعليمات البرمجية.
10. تقديم خدمات زائدة عن الحاجة
الحل: لا يوجد حل بسيط. هناك خياران أكثر صعوبة.
يتمثل مخطط التوفير الذي يوفره مطورو Nomad في دعم عدد الخدمات قيد التشغيل. أنت تقول أن البدو "أطلقوا لي 5 حالات من الخدمة" وبدأهم في مكان ما هناك. لا توجد سيطرة على التوزيع. يمكن تشغيل المثيلات على نفس الخادم.
إذا تعطل الخادم ، يتم نقل المثيلات إلى خوادم أخرى. أثناء نقل المثيلات ، لا تعمل الخدمة. هذا خيار احتياطي سيء.
نحن نفعل ذلك بشكل صحيح:
- نقوم بتوزيع المثيلات على الخوادم من خلال متميز_أوائل .
- نقوم بتوزيع المثيلات عبر مراكز البيانات. لسوء الحظ ، فقط عن طريق إنشاء نسخة من البرنامج النصي للنموذج service1 ، و service2 مع نفس المحتويات ، وأسماء مختلفة ، ومؤشر على الإطلاق في مراكز بيانات مختلفة.
في Nomad 0.9 ، ستظهر وظيفة تعمل على حل هذه المشكلة: سيكون من الممكن توزيع الخدمات بنسبة مئوية بين الخوادم ومراكز البيانات.
11. الويب UI البدوي
الحل: واجهة المستخدم المدمجة أمر فظيع ، hashi-ui جميل.
يؤدي عميل وحدة التحكم معظم الوظائف المطلوبة ، ولكن في بعض الأحيان تريد أن ترى الرسومات ، اضغط على الأزرار ...
البدوي لديه واجهة مستخدم مدمجة. أنها ليست مريحة للغاية (حتى أسوأ من وحدة التحكم).

البديل الوحيد الذي أعرفه هو hashi-ui .

في الواقع ، الآن أنا شخصياً أحتاج إلى عميل وحدة التحكم فقط من أجل "تشغيل البدو". وحتى هذه الخطط لنقلها إلى CI.
12. دعم لزيادة الاشتراك من الذاكرة
الحل: لا.
في الإصدار الحالي من Nomad ، يجب عليك تحديد حد ذاكرة صارم للخدمة. في حالة تجاوز الحد ، سيتم قتل الخدمة على يد OOM Killer.
يتم زيادة الاشتراك عندما يمكن تحديد حدود الخدمة "من وإلى." تتطلب بعض الخدمات ذاكرة أكبر عند بدء التشغيل أكثر من التشغيل العادي. قد تستهلك بعض الخدمات ذاكرة أكثر من المعتاد لفترة قصيرة.
يعد اختيار التقييد الصارم أو اللين موضوعًا للمناقشة ، ولكن ، على سبيل المثال ، يسمح Kubernetes للمبرمج بالاختيار. لسوء الحظ ، في الإصدارات الحالية من البدوي لا يوجد مثل هذا الاحتمال. أعترف أنه سيظهر في الإصدارات المستقبلية.
13. تنظيف الخادم من خدمات البدوي
الحل:
sudo systemctl stop nomad mount | fgrep alloc | awk '{print $3}' | xargs -I QQ sudo umount QQ sudo rm -rf /var/lib/nomad sudo docker ps | grep -v '(-1|-2|...)' | fgrep -v IMAGE | awk '{print $1}' | xargs -I QQ sudo docker stop QQ sudo systemctl start nomad
في بعض الأحيان "هناك خطأ ما." على الخادم ، يقتل عقدة الوكيل ويرفض البدء. أو عقدة الوكيل توقف عن الاستجابة. أو العقدة وكيل "يفقد" الخدمات على هذا الخادم.
يحدث هذا في بعض الأحيان مع الإصدارات القديمة من Nomad ، والآن هذا إما لا يحدث ، أو نادرًا جدًا.
ما هو الأسهل في هذه الحالة ، بالنظر إلى أن خادم التصريف لن ينتج النتيجة المرجوة؟ نقوم بتنظيف الخادم يدويًا:
- وقف وكيل الرحل.
- جعل umount على جبل يخلق.
- احذف جميع بيانات الوكيل.
- نقوم بإزالة جميع الحاويات عن طريق تصفية حاويات الخدمة (إن وجدت).
- نبدأ الوكيل.
14. ما هي أفضل طريقة لنشر البدوي؟
الحل: بالطبع ، من خلال القنصل.
القنصل في هذه الحالة ليس بأي حال من الأحوال طبقة إضافية ، ولكنه خدمة تناسب عضويا البنية التحتية ، والتي توفر مزايا أكثر من سلبيات: DNS ، تخزين KV ، البحث عن الخدمات ، ومراقبة توفر الخدمة ، والقدرة على تبادل المعلومات بأمان.
بالإضافة إلى ذلك ، تتكشف بنفس سهولة نوماد نفسه.
15. أيهما أفضل - البدوي أو Kubernetes؟
الحل: يعتمد على ...
في السابق ، كنت أفكر أحيانًا في بدء عملية الترحيل إلى Kubernetes - كنت منزعجة جدًا من إعادة التشغيل التلقائي للخدمات (انظر المشكلة رقم 8). ولكن بعد الحل الكامل للمشكلة ، أستطيع أن أقول: البدوي يناسبني في الوقت الحالي.
من ناحية أخرى: لدى Kubernetes أيضًا إعادة تحميل شبه تلقائية للخدمات - عندما يعيد جدولة Kubernetes إعادة توزيع الحالات حسب الحمل. هذا ليس رائعًا جدًا ، ولكن هناك على الأرجح تكوينه.
مزايا Nomad: البنية التحتية سهلة النشر للغاية ، نصوص بسيطة ، وثائق جيدة ، دعم مدمج للقنصل / Vault ، والذي بدوره يوفر: حل بسيط لمشكلة تخزين كلمة المرور ، DNS مدمج ، عمليات فحص سهلة التركيب.
إيجابيات Kubernetes: الآن هو "المعيار الفعلي". توثيق جيد ، العديد من الحلول الجاهزة ، مع وصف جيد وتوحيد الإطلاق.
لسوء الحظ ، ليس لدي نفس الخبرة الكبيرة في Kubernetes للإجابة بشكل لا لبس فيه على السؤال - ما الذي يجب استخدامه للمجموعة الجديدة. يعتمد على الاحتياجات المخطط لها.
إذا كان لديك الكثير من مساحات الأسماء المخططة (المشكلة رقم 5) أو تستهلك خدماتك المحددة الكثير من الذاكرة في البداية ، ثم حررها (المشكلة رقم 12) - بالتأكيد Kubernetes ، لأن لم يتم حل هاتين المشكلتين في Nomad بشكل كامل أو غير مريح.