حدود وحدة المعالجة المركزية والاختناق
مثل العديد من مستخدمي Kubernetes الآخرين ، توصي Google بشدة بتعديل حدود وحدة المعالجة المركزية . بدون هذا التكوين ، يمكن للحاويات الموجودة في العقدة أن تستهلك كل طاقة المعالج ، الأمر الذي سيؤدي بدوره إلى توقف عمليات Kubernetes المهمة (على سبيل المثال
kubelet) عن الاستجابة للطلبات. وبالتالي ، يعد تعيين حدود وحدة المعالجة المركزية طريقة جيدة لحماية العقد الخاصة بك.
تحدد حدود المعالج للحاوية الحد الأقصى لوقت المعالج الذي يمكن استخدامه لفترة محددة (100 مللي ثانية افتراضيًا) ، ولن تتجاوز الحاوية هذا الحد مطلقًا. يستخدم Kubernetes أداة خاصة CFS Quota لخنق الحاوية ومنعها من تجاوز الحد.ومع ذلك ، في النهاية ، يحد هذا المعالج الاصطناعي من الأداء المنخفض ويزيد من وقت استجابة حاوياتك.
ماذا يمكن أن يحدث إذا لم نضع حدودًا لوحدة المعالجة المركزية؟
لسوء الحظ ، كان علينا أن نتعامل مع هذه المشكلة. كل عقدة لديها عملية مسؤولة عن إدارة الحاويات
kubelet، وقد توقفت عن الاستجابة للطلبات. عند حدوث ذلك ، ستنتقل العقدة إلى الحالة NotReady، وسيتم إعادة توجيه الحاويات منها إلى مكان آخر وستنشئ نفس المشكلات بالفعل على العقد الجديدة. ليس سيناريو مثالي ، بعبارة ملطفة.
إظهار مشاكل الاختناق والاستجابة
المقياس الأساسي لتتبع الحاويات هو
trottlingعدد مرات اختناق الحاوية الخاصة بك. لاحظنا باهتمام وجود الاختناق في بعض الحاويات ، بغض النظر عما إذا كان الحمل على المعالج أقصى أم لا. على سبيل المثال ، دعنا نلقي نظرة على إحدى واجهات برمجة التطبيقات الرئيسية لدينا:
كما ترى أدناه ، قمنا بتعيين الحد عند
800m(0.8 أو 80٪ من النواة) ، وتكون قيم الذروة في أحسن الأحوال 200m(20٪ من النواة). يبدو أننا ما زلنا نمتلك قدرًا كبيرًا من طاقة المعالج قبل اختناق الخدمة ، ولكن ...

ربما لاحظت أنه حتى عندما يكون الحمل على المعالج أقل من الحدود المحددة - أقل بكثير - لا يزال الاختناق يعمل.
في مواجهة هذا ، اكتشفنا قريبًا العديد من الموارد ( مشكلة على جيثب ، عرض تقديمي عن zadano ، منشور على omio ) حول انخفاض الأداء ووقت استجابة الخدمات بسبب الاختناق.
لماذا نرى الاختناق في ظل انخفاض استخدام وحدة المعالجة المركزية؟ تقرأ النسخة القصيرة على النحو التالي: "هناك خطأ في نواة Linux يؤدي إلى اختناق غير ضروري للحاويات بحدود معالج محددة." إذا كنت مهتما في طبيعة المشكلة، يمكنك قراءة العرض التقديمي ( الفيديو و النص المتغيرات) بواسطة ديف تشيلوك.
إزالة حدود المعالج (بحذر شديد)
بعد مناقشات مطولة ، قررنا إزالة قيود المعالج من جميع الخدمات ، والتي أثرت بشكل مباشر أو غير مباشر على الوظائف الهامة لمستخدمينا.
اتضح أن القرار صعب ، لأننا نقدر عاليا استقرار مجموعتنا. في الماضي ، جربنا بالفعل عدم استقرار مجموعتنا ، ثم استهلكت الخدمات الكثير من الموارد وأبطأت عمل العقدة بأكملها. أصبح كل شيء الآن مختلفًا بعض الشيء: كان لدينا فهم واضح لما توقعناه من مجموعاتنا ، بالإضافة إلى استراتيجية جيدة لتنفيذ التغييرات المخطط لها.
المراسلات التجارية بشأن قضية ملحة.
كيف تحمي عقدك عند إزالة القيود؟
عزل الخدمات "غير المحدودة":
في الماضي ، شهدنا دخول بعض العقد إلى حالة
notReady، ويرجع ذلك أساسًا إلى الخدمات التي كانت تستهلك الكثير من الموارد.
قررنا وضع مثل هذه الخدمات في عقد منفصلة ("مميزة") بحيث لا تتداخل مع الخدمات "المرتبطة". نتيجة لذلك ، من خلال وضع علامة على بعض العقد وإضافة معلمة تسامح إلى الخدمات "غير المرتبطة" ، اكتسبنا مزيدًا من التحكم في الكتلة ، وأصبح من السهل علينا تحديد المشكلات المتعلقة بالعقد. لتنفيذ عمليات مماثلة بنفسك ، يمكنك التعرف على الوثائق .
تعيين المعالج الصحيح وطلب الذاكرة:
الأهم من ذلك كله ، كنا نخشى أن تستهلك العملية الكثير من الموارد وأن تتوقف العقدة عن الاستجابة للطلبات. منذ الآن (بفضل Datadog) يمكننا أن نلاحظ بوضوح جميع الخدمات في مجموعتنا ، قمت بتحليل عدة أشهر من التشغيل لتلك التي خططنا لتسميتها على أنها "غير ذات صلة". أقوم ببساطة بتعيين الحد الأقصى لاستخدام وحدة المعالجة المركزية بهامش 20٪ ، وبالتالي تخصيص مساحة في العقدة في حالة محاولة k8s تعيين خدمات أخرى للعقدة.
كما ترى في الرسم البياني ، وصل أقصى حمل للمعالج إلى
242mأنوية وحدة المعالجة المركزية (0.242 نواة معالج). بالنسبة لطلب المعالج ، يكفي أن تأخذ رقمًا أكبر قليلاً من هذه القيمة. لاحظ أنه نظرًا لأن الخدمات تتمحور حول المستخدم ، فإن ذروة الحمل تتزامن مع حركة المرور.
افعل الشيء نفسه مع استخدام الذاكرة والاستفسارات ، وفويلا - أنت جاهز تمامًا! لمزيد من الأمان ، يمكنك إضافة مقياس تلقائي أفقي للقرون. وبالتالي ، في كل مرة يكون فيها الحمل على الموارد مرتفعًا ، سينشئ القياس التلقائي كبسولات جديدة ، وسيقوم kubernetes بتوزيعها على العقد ذات المساحة الخالية. في حالة عدم وجود مساحة متبقية في الكتلة نفسها ، يمكنك تعيين تنبيه لنفسك أو تكوين إضافة عقد جديدة من خلال قياسها التلقائي.
ومن السلبيات الجدير بالذكر أننا فقدنا في " كثافة الحاويات " أي عدد الحاويات العاملة في عقدة واحدة. قد يكون لدينا أيضًا الكثير من "الانغماس" في كثافة حركة المرور المنخفضة ، وهناك أيضًا احتمال أن تصل إلى حمل معالج مرتفع ، ولكن يجب أن يساعد قياس العقدة تلقائيًا في هذا الأخير.
النتائج
يسعدني نشر هذه النتائج الممتازة للتجارب خلال الأسابيع القليلة الماضية ، فقد لاحظنا بالفعل تحسينات كبيرة في الاستجابة بين جميع الخدمات المعدلة:
لقد حققنا أفضل نتيجة على صفحتنا الرئيسية ( buffer.com ) ، حيث تم تسريع الخدمة 22 مرة!
هل تم إصلاح خطأ Linux kernel؟
نعم ، تم إصلاح الخطأ بالفعل ، وتمت إضافة الإصلاح إلى نواة التوزيعات الإصدار 4.19 والإصدارات الأحدث.
ومع ذلك ، أثناء قراءة مشكلة kubernetes على github في 2 سبتمبر 2020 ، ما زلنا نواجه مراجع لبعض مشاريع Linux مع خطأ مماثل. أعتقد أن بعض توزيعات Linux لا تزال تعاني من هذا الخطأ وتعمل حاليًا على إصلاح.
إذا كان إصدار التوزيع لديك أقل من 4.19 ، فإنني أوصي بالتحديث إلى الأحدث ، ولكن يجب أن تحاول إزالة حدود المعالج على أي حال ومعرفة ما إذا كان الاختناق مستمرًا. يمكنك العثور أدناه على قائمة غير كاملة لإدارة خدمات Kubernetes وتوزيعات Linux:
- Debian: , buster, ( 2020 ). .
- Ubuntu: Ubuntu Focal Fossa 20.04
- EKS 2019 . , AMI.
- kops: 2020
kops 1.18+Ubuntu 20.04. kops , , , . . - GKE (Google Cloud): 2020 , .
ماذا لو أصلح الإصلاح مشكلة الاختناق؟
لست متأكدًا مما إذا كانت المشكلة قد تم حلها بالكامل. عندما نصل إلى الإصدار الثابت من النواة ، سأختبر الكتلة وأحدث المنشور. إذا قام شخص ما بالتحديث بالفعل ، أود مراجعة نتائجك باهتمام.
خاتمة
- إذا كنت تعمل مع حاويات Docker في نظام Linux (لا يهم Kubernetes أو Mesos أو Swarm أو أي شيء آخر) ، فقد تفقد حاوياتك الأداء بسبب الاختناق ؛
- حاول التحديث إلى أحدث إصدار من التوزيع على أمل أن يكون الخطأ قد تم إصلاحه ؛
- ستؤدي إزالة حدود المعالج إلى حل المشكلة ، ولكن هذه تقنية خطيرة يجب استخدامها بحذر شديد (من الأفضل تحديث النواة أولاً ومقارنة النتائج) ؛
- إذا قمت بإزالة حدود المعالج ، راقب استخدام المعالج والذاكرة بعناية ، وتأكد من أن موارد المعالج تتجاوز الاستهلاك ؛
- قد يكون الخيار الآمن هو مقياس البودات تلقائيًا لإنشاء قرون جديدة في حالة وجود حمل كبير على الأجهزة بحيث تقوم kubernetes بتعيينها للعقد المجانية.
آمل أن يساعدك هذا المنشور في تحسين أداء أنظمة الحاويات الخاصة بك.
ملاحظة: هنا المؤلف في مراسلات مع القراء والمعلقين (باللغة الإنجليزية).