كيف قمنا بترحيل أكثر من 700 خادم إلى Salt
لفترة طويلة ، كنا راضين عن التكوين المعقد والمرهق مع مستودعات 2 Git ، حيث يتم تخزين جزء من البيانات في MySQL ، والجزء الآخر هو Puppet 3.8. لكن احتياجاتنا نمت تدريجياً ، وزاد عدد الخدمات ، وانخفض أداء التكوين. ثم حددنا لأنفسنا مهمة تحسين التكوين ، وتحسين جميع البيانات والأدوات المتاحة.
اختار فريقنا التكوين المناسب لأنفسهم في 3 مراحل. نشارك تجربتنا في تحسين الملح وكيفية التقديم والتخصيص دون بذل جهد إضافي.
ملاحظة: وجدنا في Habré مقالات رائعة لزملائنا ، لذلك لن نتطرق إلى القضايا التي تم تناولها بالفعل. نوصي بشدة بقراءة:
ما هو الجيد في SaltStack ، وما هي المهام التي يمكن حلها - مقال منptsecurity، التقنيات الإيجابية.
التثبيت والإطلاق والأوامر الأولى والإلمام بالوظائف - مقال المؤلفالزرقه 007...
الملح هو نظام إدارة التكوين والتنفيذ عن بعد. إطار عمل بنية أساسية مفتوح المصدر مكتوب بلغة Python.

لماذا الملح؟
تعتبر Salt و Ansible و Puppet و Chef خيارات مناسبة لاختيار أداة إدارة التكوين. اخترنا الملح لأننا أعطينا الأولوية للفوائد التالية:
- نمطية ، توفر API في الإصدار المجاني ، على عكس Ansible.
- Python ، مما يعني أنه يمكنك بسهولة فهم أي مكون وكتابة الوظيفة المفقودة بنفسك.
- أداء عالي وقابلية التوسع. يقوم المعالج بإنشاء اتصال دائم مع التوابع باستخدام ZeroMQ لتحقيق أقصى أداء.
- المفاعلات هي نوع من المشغلات التي يتم تنفيذها عند ظهور رسالة معينة في ناقل الرسائل.
- التزامن - القدرة على بناء علاقات معقدة وتنفيذ الإجراءات في تسلسل محدد ، على سبيل المثال ، تكوين موازن التحميل أولاً ، ثم مجموعة خادم الويب.
- الدمية والشيف مكتوبان في روبي. لا يمتلك فريقنا متخصصًا كفؤًا للعمل مع لغة البرمجة هذه ، ولكن لغة Python معروفة جيدًا وغالبًا ما نستخدمها.
- بالنسبة لتلك الفرق التي استخدمت Ansible من قبل ، ستكون القدرة على استخدام كتيبات اللعب Ansible ذات صلة. سيسمح لك ذلك بالانتقال إلى الملح دون ألم.
ملاحظة:
نحن نستخدم الملح منذ عامين تقريبًا وننصحك بالاهتمام بالنقاط التالية:
- Salt, , . , . , SaltStack .
- SaltStack . , . : , . , cmd.run file.managed, .

, , , .
. .
معطى:
إذن ، التكوين الأولي لدينا هو:
- 2 مستودعات Git (أحدهما للمهندسين والمسؤولين ؛ والثاني مخصص للخوادم شديدة الأهمية ، وهو متاح فقط للمسؤولين) ؛
- قطعة من البيانات في MySQL ؛
- الجزء الآخر - في Puppet 3.8 (تم الإفراط في الإرث ، وعدم استخدام Hiera - تخزين القيمة الرئيسية).
الهدف: نقل نظام إدارة التكوين إلى Salt ، وزيادة أدائه ، وجعل إدارة الخادم أكثر ملاءمة ومفهومة.
الحل:
أولاً وقبل كل شيء ، بدأنا في ترحيل التكوين الأصلي إلى Salt من خوادم خدمة منفصلة غير مهمة ، وفي نفس الوقت التخلص من التعليمات البرمجية القديمة.
ثم قمنا بإعداد التكوين لخوادم VDS. في حالتنا ، هذه ملفات تعريف لخوادم الخدمة وخوادم التطوير وخوادم العملاء.
كانت المشكلة الرئيسية عند التبديل من Puppet إلى Salt هي نظام تشغيل قديم (في عام 2018 ، كان هناك Ubuntu 12.04 و 14.04). قبل الترحيل ، كان من الضروري تحديث نظام التشغيل وعدم التأثير على تشغيل الخدمة / الخادم. بخلاف ذلك ، كان كل شيء سهلاً بدرجة كافية: شارك الزملاء تدريجياً في العملية.
من بين المزايا الرئيسية ، لاحظ الفريق ، على سبيل المثال ، بناء جملة أكثر قابلية للفهم. اتفقت أنا وزملائي على استخدام نصائح أفضل الممارسات في Salt ، لكننا أكملتها بتوصياتنا الخاصة التي تعكس خصوصياتنا.
قام الفريق أيضًا بتقييم طرق توصيل التكوين: الدفع ("الدفع" الرئيسي) والسحب ("العميل" يسحب "). يساعد وضع Masterless إذا كنت بحاجة إلى اختبار شيء بسيط وفي نفس الوقت عدم العبث بمستودع Git. يتيح لك تشغيل العميل في وضع Masterless استخدام إدارة تكوين الملح على جهاز واحد دون الحاجة إلى الانتقال إلى Salt master على جهاز آخر. التكوين محلي بالكامل.
حتى 300 تابع مع مثل هذا الحل ، لم تكن لدينا مشاكل خطيرة. التكوين الرئيسي في ذلك الوقت هو VDS مع 6 مراكز و 4 جيجابايت من الذاكرة.
ومع ذلك ، بمجرد وصول عدد التوابع إلى 300 ، زاد متوسط التحميل (متوسط حمل النظام) إلى 3.5-4 ، وتباطأ النظام كثيرًا. في السابق ، كان الأمر state.apply يستغرق 30-40 ثانية ، لكنه الآن يستغرق 18 دقيقة!
كانت هذه النتيجة بالطبع غير مقبولة بالنسبة لنا. علاوة على ذلك ، كتب خبراء من شركات أخرى عن قصص نجاح مع 10000 تابع. بدأنا في معرفة ما هو الأمر.
لم تعط ملاحظات السيد إجابة لا لبس فيها على السؤال. كانت هناك ذاكرة كافية ، ولم يتم تحميل الشبكة ، وتم استخدام القرص بنسبة 10٪. كنا نظن أن اللوم يقع على GitLab ، لكن لم يكن اللوم أيضًا.
يبدو أنه لم يكن هناك طاقة كافية للمعالج: عند إضافة النوى ، انخفض متوسط التحميل بشكل طبيعي ، وتم تنفيذ الأمر state.apply ، على الرغم من أنه أسرع ، حوالي 5-7 دقائق ، ولكن ليس بالسرعة التي أردناها.
أدت إضافة العمال إلى حل المشكلة جزئيًا ، لكنها أدت إلى زيادة استهلاك الذاكرة بشكل كبير.
ثم قررنا تحسين التكوين نفسه.
المرحلة 1
نظرًا لأن الأعمدة عبارة عن تخزين محمي ، فإن الوصول إلى التخزين مرتبط بعمليات التشفير ، وعليك أن تدفع مقابل الوصول إليها مع وقت وحدة المعالجة المركزية. لذلك ، قمنا بتقليل عدد المكالمات إلى الأعمدة: تم أخذ نفس البيانات مرة واحدة فقط ؛ إذا كانت هناك حاجة إليها في مكان آخر ، فقد تم الوصول إليها عن طريق الاستيراد ({٪ - من ملف تعريف الاستيراد 'defaults / pillar.sls'٪}).
يتم تطبيق التكوين مرة كل ساعة ، ويتم اختيار وقت التنفيذ بشكل عشوائي. بعد تحليل عدد المهام التي يتم إجراؤها في الدقيقة ومدى توزيعها بالتساوي على مدار الساعة ، اكتشفنا: في بداية الساعة ، من الدقيقة الأولى إلى الدقيقة الثامنة ، تمر معظم المهام ، وفي الدقيقة الرابعة والثلاثين ، لا شيء! كتبنا عداءًا مر على كل التوابع مرة واحدة في الأسبوع وقمنا بتوزيع المهام بالتساوي. بفضل هذا النهج ، أصبح الحمل موحدًا ، بدون قفزات.
كانت هناك اقتراحات للانتقال إلى خادم حديدي ، لكن في ذلك الوقت لم يكن موجودًا و ... قمنا بحل المشكلة بطريقة مختلفة. أضفنا بعض الذاكرة ووضعنا ذاكرة التخزين المؤقت بالكامل فيها. بالنظر إلى لوحة معلومات Grafana ، اعتقدنا أولاً أن خبير الملح لا يعمل ، حيث انخفض متوسط التحميل إلى 0.5. تحققنا من وقت تنفيذ state.apply وفوجئنا أيضًا - 20-30 ثانية. كان انتصارا!
المرحلة الثانية
بعد ستة أشهر ، ارتفع عدد التوابع إلى 650 ، و ... جاء تدهور الأداء مرة أخرى. ينمو الرسم البياني لمتوسط التحميل مع عدد التوابع.
أول شيء فعلناه: تمكين ذاكرة التخزين المؤقت للعمود ، وضبط العمر على ساعة واحدة (pillar_cache_ttl: 3600). لقد أدركنا أن التزاماتنا الآن لن تكون فورية وسيتعين علينا الانتظار حتى يقوم السيد بتحديث ذاكرة التخزين المؤقت.
نظرًا لأننا لم نرغب في الانتظار على الإطلاق ، فقد صنعنا خطافات في GitLab. سمح ذلك في الالتزام بالإشارة إلى العميل الذي تريد تحديث ذاكرة التخزين المؤقت له. خفضت ذاكرة التخزين المؤقت للأعمدة الحمل بشكل كبير وتقليل الوقت لتطبيق التهيئة.
المرحلة 3
لقد تأملنا قليلاً في سجلات تصحيح الأخطاء وطرحنا فرضية: ماذا لو قمنا بزيادة الفاصل الزمني للتحديث للواجهة الخلفية للملف وذاكرة التخزين المؤقت لقائمة الملفات (gitfs_update_interval، fileserver_list_cache_time)؟ تم التحديث مرة واحدة في الدقيقة واستغرق أحيانًا ما يصل إلى 15 ثانية. من خلال زيادة الفاصل الزمني للتحديث من دقيقة واحدة إلى 10 دقائق ، فزنا مرة أخرى بسرعة! انخفض مؤشر LA من 1.5 إلى 0.5. تم تقليل وقت تطبيق التكوين إلى 20 ثانية المطلوبة. على الرغم من حقيقة أن لوس أنجلوس نمت مرة أخرى بعد مرور بعض الوقت ، إلا أن سرعة تطبيق الدولة لم تتغير بشكل كبير. تمت إضافة تحديث قسري لهذه ذاكرات التخزين المؤقت إلى الخطافات الموجودة على git push.

أضفنا تحليلات إلى Elasticsearch: أعدنا كتابة elasticsearch_return المدمج ويمكننا الآن مراقبة نتائج state.apply (متوسط وقت التنفيذ وأطول حالة وعدد الأخطاء).
النتائج
الآن نحن راضون تمامًا عن أداء Salt. هناك خطط لمضاعفة عدد التوابع. لا يزال من الصعب قول كيف سيتعامل سيدنا مع مثل هذا العبء. ربما ننتقل إلى القياس الأفقي أو نجد معلمة سحرية. سيخبر الوقت!
إذا كنت تستخدم gitfs كخلفية ، فامنحها خمسة! هناك احتمالات ، أنك تمر بنفس المشاكل التي نمر بها. لذلك سنكون سعداء لمناقشة هذا الموضوع في التعليقات.