Kubernetes: تسريع خدماتك عن طريق إزالة حدود وحدة المعالجة المركزية

مرة أخرى في عام 2016 نحن في Buffer تحولت إلى Kubernetes، والآن يعمل حوالي 60 عقدة (على AWS) و1500 حاوية على مجموعة k8s التي يديرها ركلة. ومع ذلك، انتقلنا إلى الخدمات الصغيرة من خلال التجربة والخطأ، وحتى بعد عدة سنوات من العمل مع k8s، ما زلنا نواجه مشكلات جديدة. في هذه التدوينة سنتحدث عنها قيود المعالج: لماذا اعتقدنا أنها ممارسات جيدة ولماذا انتهى بها الأمر إلى أنها ليست جيدة جدًا.

قيود المعالج والاختناق

مثل العديد من مستخدمي Kubernetes الآخرين، توصي Google بشدة بوضع حدود لوحدة المعالجة المركزية. بدون مثل هذا الإعداد، يمكن للحاويات الموجودة في العقدة أن تستهلك كل طاقة المعالج، الأمر الذي يؤدي بدوره إلى عمليات Kubernetes المهمة (على سبيل المثال kubelet) سيتوقف عن الاستجابة للطلبات. وبالتالي، يعد تحديد حدود وحدة المعالجة المركزية طريقة جيدة لحماية العقد الخاصة بك.

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

ماذا يمكن أن يحدث إذا لم نضع حدود المعالج؟

ولسوء الحظ، كان علينا أن نواجه هذه المشكلة بأنفسنا. كل عقدة لديها عملية مسؤولة عن إدارة الحاويات kubeletوتوقف عن الاستجابة للطلبات. العقدة، عندما يحدث هذا، سوف تذهب إلى الحالة NotReadyوسيتم إعادة توجيه الحاويات منه إلى مكان آخر وإنشاء نفس المشكلات على العقد الجديدة. ليس السيناريو المثالي، على أقل تقدير.

مظهر من مظاهر مشكلة الاختناق والاستجابة

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

Kubernetes: تسريع خدماتك عن طريق إزالة حدود وحدة المعالجة المركزية

كما ترون أدناه، لقد وضعنا الحد ل 800m (0.8 أو 80% نواة)، وقيم الذروة في أفضل حالات الوصول إليها 200m (20% الأساسية). يبدو أنه قبل اختناق الخدمة، لا يزال لدينا الكثير من قوة المعالج، ولكن...

Kubernetes: تسريع خدماتك عن طريق إزالة حدود وحدة المعالجة المركزية
ربما لاحظت أنه حتى عندما يكون حمل المعالج أقل من الحدود المحددة - أقل بكثير - فإن الاختناق لا يزال يحدث.

في مواجهة هذا، سرعان ما اكتشفنا العديد من الموارد (مشكلة على جيثب, العرض التقديمي على زادانو, نشر على omio) حول انخفاض الأداء ووقت استجابة الخدمات بسبب الاختناق.

لماذا نرى اختناقًا عند انخفاض حمل وحدة المعالجة المركزية؟ النسخة المختصرة هي: "هناك خطأ في نواة Linux يتسبب في اختناق غير ضروري للحاويات ذات حدود المعالج المحددة." إذا كنت مهتماً بطبيعة المشكلة يمكنك قراءة العرض التقديمي (فيديو и نص خيارات) بواسطة ديف تشيلوك.

إزالة قيود وحدة المعالجة المركزية (بحذر شديد)

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

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

Kubernetes: تسريع خدماتك عن طريق إزالة حدود وحدة المعالجة المركزية
المراسلات التجارية حول قضية ملحة.

كيف تحمي العقد الخاصة بك عند رفع القيود؟

عزل الخدمات "غير المقيدة":

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

قررنا وضع هذه الخدمات في عقد منفصلة ("مُسمّاة") بحيث لا تتداخل مع الخدمات "ذات الصلة". ونتيجة لذلك، من خلال وضع علامة على بعض العقد وإضافة معلمة التسامح إلى الخدمات "غير ذات الصلة"، حققنا تحكمًا أكبر في المجموعة، وأصبح من الأسهل بالنسبة لنا تحديد المشكلات المتعلقة بالعقد. لتنفيذ عمليات مماثلة بنفسك، يمكنك التعرف على نفسك توثيق.

Kubernetes: تسريع خدماتك عن طريق إزالة حدود وحدة المعالجة المركزية

تعيين المعالج الصحيح وطلب الذاكرة:

كان خوفنا الأكبر هو أن تستهلك العملية الكثير من الموارد وتتوقف العقدة عن الاستجابة للطلبات. منذ الآن (بفضل Datadog) أصبح بإمكاننا مراقبة جميع الخدمات في مجموعتنا بوضوح، وقمت بتحليل عدة أشهر من تشغيل تلك الخدمات التي خططنا لتصنيفها على أنها "غير ذات صلة". لقد قمت ببساطة بتعيين الحد الأقصى لاستخدام وحدة المعالجة المركزية بهامش 20%، وبالتالي تخصيص مساحة في العقدة في حالة محاولة k8s تعيين خدمات أخرى للعقدة.

Kubernetes: تسريع خدماتك عن طريق إزالة حدود وحدة المعالجة المركزية

كما ترون في الرسم البياني، تم الوصول إلى الحد الأقصى للحمل على المعالج 242m نوى وحدة المعالجة المركزية (0.242 نواة المعالج). بالنسبة لطلب المعالج، يكفي أن تأخذ رقما أكبر قليلا من هذه القيمة. يرجى ملاحظة أنه نظرًا لأن الخدمات تتمحور حول المستخدم، فإن قيم التحميل القصوى تتزامن مع حركة المرور.

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

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

النتائج

يسعدني نشر هذه النتائج الممتازة من التجارب التي تمت على مدار الأسابيع القليلة الماضية؛ فقد شهدنا بالفعل تحسينات كبيرة في الاستجابة عبر جميع الخدمات المعدلة:

Kubernetes: تسريع خدماتك عن طريق إزالة حدود وحدة المعالجة المركزية

حققنا أفضل النتائج على صفحتنا الرئيسية (buffer.com)، حيث تم تسريع الخدمة اثنان وعشرون مرة!

Kubernetes: تسريع خدماتك عن طريق إزالة حدود وحدة المعالجة المركزية

هل تم إصلاح خطأ Linux kernel؟

نعم، لقد تم بالفعل إصلاح الخلل وتمت إضافة الإصلاح إلى النواة التوزيعات الإصدار 4.19 وما فوق.

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

إذا كان إصدار التوزيع الخاص بك أقل من 4.19، فإنني أوصي بالتحديث إلى الإصدار الأحدث، ولكن على أي حال يجب عليك محاولة إزالة قيود المعالج ومعرفة ما إذا كان الاختناق مستمرًا. يمكنك أدناه رؤية قائمة جزئية لخدمات إدارة Kubernetes وتوزيعات Linux:

  • دبيان: إصلاح مدمج في الإصدار الأحدث من التوزيعة، المغفل، وتبدو جديدة تمامًا (أغسطس 2020 سنوات). قد يتم أيضًا إصلاح بعض الإصدارات السابقة.
  • أوبونتو: الإصلاح مدمج في الإصدار الأحدث أوبونتو فوكال فوسا 20.04
  • لقد حصلت EKS على الإصلاح حتى الآن في ديسمبر 2019. إذا كان الإصدار الخاص بك أقل من هذا، فيجب عليك تحديث AMI.
  • كوبس: من يونيو 2020 у kops 1.18+ ستكون صورة المضيف الرئيسية هي Ubuntu 20.04. إذا كان إصدار kops الخاص بك أقدم، فقد تضطر إلى الانتظار حتى يتم إصلاح المشكلة. نحن أنفسنا ننتظر الآن.
  • GKE (Google Cloud): إصلاح متكامل في يناير 2020، ولكن هناك مشاكل مع اختناق لا تزال ملحوظة.

ماذا تفعل إذا أدى الإصلاح إلى حل مشكلة الاختناق؟

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

اختتام

  • إذا كنت تعمل مع حاويات Docker ضمن Linux (بغض النظر عن Kubernetes أو Mesos أو Swarm أو غيرها)، فقد تفقد حاوياتك الأداء بسبب الاختناق؛
  • حاول التحديث إلى الإصدار الأحدث من توزيعتك على أمل أن يكون الخلل قد تم إصلاحه بالفعل؛
  • إزالة حدود المعالج ستحل المشكلة، لكن هذه تقنية خطيرة يجب استخدامها بحذر شديد (من الأفضل تحديث النواة أولاً ومقارنة النتائج)؛
  • إذا قمت بإزالة حدود وحدة المعالجة المركزية، فراقب استخدام وحدة المعالجة المركزية والذاكرة بعناية وتأكد من أن موارد وحدة المعالجة المركزية لديك تتجاوز استهلاكك؛
  • سيكون الخيار الآمن هو توسيع نطاق البودات تلقائيًا لإنشاء كبسولات جديدة في حالة التحميل العالي للأجهزة، بحيث يقوم kubernetes بتعيينها للعقد المجانية.

آمل أن يساعدك هذا المنشور على تحسين أداء أنظمة الحاويات الخاصة بك.

PS ومن يتوافق المؤلف مع القراء والمعلقين (باللغة الإنجليزية).


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

إضافة تعليق