Kubernetes: يجب أن يعمل Kubelet / Kubernetes مع Swap Enabled

تم إنشاؤها على ٦ أكتوبر ٢٠١٧  ·  94تعليقات  ·  مصدر: kubernetes/kubernetes

هل هذا تقرير خطأ أم طلب ميزة؟ :

قم بإلغاء تعليق واحد فقط ، اتركه على السطر الخاص به:

/ نوع الخطأ
/ نوع الميزة

ماذا حدث :

لا يعمل Kubelet / Kubernetes 1.8 مع تمكين Swap على أجهزة Linux.

لقد وجدت هذه المشكلة الأصلية https://github.com/kubernetes/kubernetes/issues/31676
هذا العلاقات العامة https://github.com/kubernetes/kubernetes/pull/31996
وآخر تغيير أتاحه افتراضيًا https://github.com/kubernetes/kubernetes/commit/71e8c8eba43a0fade6e4edfc739b331ba3cc658a

إذا كان Kubernetes لا يعرف كيفية التعامل مع إخلاء الذاكرة عند تمكين Swap - فيجب أن يجد طريقة لكيفية القيام بذلك ، ولكن لا يطلب التخلص من المبادلة.

يرجى اتباع kernel.org الفصل 11 إدارة المبادلة ، على سبيل المثال

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

في حالة تشغيل الكثير من تطبيقات العقدة / جافا ، رأيت دائمًا يتم تبديل الكثير من الصفحات ، لمجرد أنها لم تعد مستخدمة بعد الآن.

ما توقعت حدوثه :

يجب أن يعمل Kubelet / Kubernetes مع تمكين Swap. أعتقد أنه بدلاً من تعطيل المبادلة وعدم منح المستخدمين أي خيارات ، يجب أن تدعم kubernetes المزيد من حالات الاستخدام وأحمال العمل المختلفة ، يمكن أن يكون بعضها تطبيقات قد تعتمد على ذاكرات التخزين المؤقت.

لست متأكدًا من الكيفية التي قررت بها kubernetes ما يجب قتله من خلال إخلاء الذاكرة ، ولكن بالنظر إلى أن Linux لديه هذه الإمكانية ، فربما يجب أن يتوافق مع كيفية قيام Linux بذلك؟ https://www.kernel.org/doc/gorman/html/understand/understand016.html

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

كيفية إعادة إنتاجه (بأدنى حد ممكن وبدقة قدر الإمكان) :

قم بتشغيل kubernetes / kublet بالإعدادات الافتراضية على جهاز Linux Box

أي شيء آخر نحن بحاجة إلى معرفته؟ :

البيئة :

  • إصدار Kubernetes (استخدم kubectl version ):
  • مزود السحابة أو تكوين الأجهزة **:
  • نظام التشغيل (على سبيل المثال من / etc / os-release):
  • Kernel (على سبيل المثال uname -a ):
  • أدوات التثبيت:
  • آحرون:

/ عقدة سيج
سم مكعبmtaufenvishhderekwaynecarrdims

kinfeature sinode

التعليق الأكثر فائدة

لا تدعم المبادلة كخيار افتراضي؟ لقد فوجئت بسماع هذا - اعتقدت أن Kubernetes كانت جاهزة لوقت الذروة؟ المبادلة هي إحدى تلك الميزات.

هذا ليس اختياريًا حقًا في معظم حالات الاستخدام المفتوح - إنها الطريقة التي يتم بها تصميم نظام Unix البيئي للتشغيل ، مع قيام VMM بتبديل الصفحات غير النشطة.

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

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

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

أعتقد بصدق أن هذه الخطوة الأخيرة لتشغيل الخوادم بدون مبادلة مدفوعة بموفري PaaS الذين يحاولون إجبار الأشخاص على مثيلات ذاكرة أكبر - مع تجاهل حوالي 40 عامًا من تصميم إدارة الذاكرة. الحقيقة هي أن النواة جيدة حقًا في معرفة صفحات الذاكرة النشطة أم لا - دعها تقوم بعملها.

ال 94 كومينتر

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

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

/ نوع الميزة

derekwaynecarr شكرا لك على التوضيح! كان من الصعب الحصول على أي معلومات / وثائق لماذا يجب تعطيل المبادلة لـ kubernetes. كان هذا هو السبب الرئيسي لفتح هذا الموضوع. في هذه المرحلة ، ليس لدي أولوية عالية لهذه المسألة ، فقط أردت التأكد من أن لدينا مكانًا يمكن مناقشته فيه.

هناك المزيد من السياق في المناقشة هنا: https://github.com/kubernetes/kubernetes/issues/7294 - وجود تبادل متاح له تفاعلات غريبة وسيئة للغاية مع حدود الذاكرة. على سبيل المثال ، الحاوية التي تصل إلى حد الذاكرة الخاص بها _ ثم تبدأ في الانسكاب في المبادلة (يبدو أن هذا تم إصلاحه منذ f4edaf2b8c32463d6485e2c12b7fd776aef948bc - لن يُسمح لهم باستخدام أي مبادلة سواء كانت موجودة أم لا).

هذه حالة استخدام حرجة بالنسبة لنا أيضًا. لدينا وظيفة cron يتم تشغيلها أحيانًا باستخدام ذاكرة عالية (> 30 غيغابايت) ولا نريد تخصيص 40 غيغابايت من العقد بشكل دائم. أيضًا ، نظرًا لأننا نعمل في ثلاث مناطق (GKE) ، فسيخصص هذا 3 آلات من هذا القبيل (1 في كل منطقة). ويجب تكرار هذا التكوين في أكثر من 3 حالات إنتاج وأكثر من 10 حالات اختبار مما يجعل استخدام K8s باهظ التكلفة. نحن مضطرون إلى الحصول على 25 + 48 جيجابايت من العقد مما يؤدي إلى تكلفة باهظة !.
الرجاء تمكين المبادلة !.

حل بديل لأولئك الذين يريدون حقًا المبادلة. اذا أنت

  • ابدأ kubelet بـ --fail-swap-on=false
  • أضف المبادلة إلى العقد الخاصة بك
  • ستتمكن الحاويات التي لا تحدد متطلبات الذاكرة بشكل افتراضي من استخدام كل ذاكرة الجهاز ، بما في ذلك المبادلة.

هذا ما نفعله. أو على الأقل ، أنا متأكد من ذلك ، لم أقم بتطبيقه شخصيًا ، لكن هذا ما أجمعه.

قد تكون هذه إستراتيجية قابلة للتطبيق فقط إذا لم تحدد أي من حاوياتك متطلبات ذاكرة صريحة ...

نجري في GKE ، ولا أعرف طريقة لتعيين تلك الخيارات.

سأكون منفتحًا على التفكير في تبني zswap إذا كان بإمكان شخص ما تقييم الآثار المترتبة على عمليات إخلاء الذاكرة في kubelet.

أقوم بتشغيل Kubernetes في جهاز الكمبيوتر المحمول المحلي الخاص بي من Ubuntu ومع كل إعادة تشغيل ، يجب أن أقوم بإيقاف التبديل. كما يجب أن أقلق بشأن عدم الاقتراب من حد الذاكرة حيث تم إيقاف تشغيل المبادلة.

هل هناك أي طريقة مع كل إعادة تشغيل لست مضطرًا لإيقاف تشغيل المبادلة مثل تغيير ملف التكوين في التثبيت الحالي؟

لست بحاجة إلى تبديل العقد التي تعمل في المجموعة.

إنها مجرد تطبيقات أخرى على الكمبيوتر المحمول الخاص بي بخلاف مجموعة Kubernetes Local Dev التي تحتاج إلى التبديل ليتم تشغيلها.

$ kubectl version
Client Version: version.Info{Major:"1", Minor:"9", GitVersion:"v1.9.2", GitCommit:"5fa2db2bd46ac79e5e00a4e6ed24191080aa463b", GitTreeState:"clean", BuildDate:"2018-01-18T10:09:24Z", GoVersion:"go1.9.2", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"9", GitVersion:"v1.9.2", GitCommit:"5fa2db2bd46ac79e5e00a4e6ed24191080aa463b", GitTreeState:"clean", BuildDate:"2018-01-18T09:42:01Z", GoVersion:"go1.9.2", Compiler:"gc", Platform:"linux/amd64"}

الآن العلم لا يعمل.

# systemctl restart kubelet --fail-swap-on=false
systemctl: unrecognized option '--fail-swap-on=false'

قم بتعيين علامة Kubelet التالية: --fail-swap-on=false

في الثلاثاء ، 30 يناير 2018 الساعة 1:59 مساءً ، كتب icewheel [email protected] :

أقوم بتشغيل Kubernetes في جهاز الكمبيوتر المحمول المحلي الخاص بي من Ubuntu ومع كل إعادة تشغيل
يجب أن نفر مبادلة. كما يجب أن أقلق بشأن عدم الاقتراب من الذاكرة
حد إذا مبادلة إذا تم إيقاف تشغيله.

هل هناك أي طريقة مع كل إعادة تشغيل لست مضطرًا لإيقاف تشغيل المبادلة مثل بعض
تغيير ملف التكوين في التثبيت الحالي؟

لست بحاجة إلى تبديل العقد التي تعمل في المجموعة.

إنها مجرد تطبيقات أخرى على الكمبيوتر المحمول الخاص بي بخلاف Kubernetes Local Dev
الكتلة الذين يحتاجون إلى المبادلة ليتم تشغيلها.

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/kubernetes/kubernetes/issues/53533#issuecomment-361748518 ،
أو كتم الخيط
https://github.com/notifications/unsubscribe-auth/AA3JwQdj2skL2dSqEVyV46iCllzT-sOVks5tP5DSgaJpZM4PwnD5
.

-
مايكل توفين
جوجل SWE

شكرا mtaufen

بالنسبة للأنظمة التي تحتوي على مجموعة تمهيد التشغيل من أجلك (مثل terraform) ، قد تحتاج إلى تعديل ملف الخدمة

هذا عمل معي

sudo sed -i '/kubelet-wrapper/a \ --fail-swap-on=false \\\' /etc/systemd/system/kubelet.service

لا تدعم المبادلة كخيار افتراضي؟ لقد فوجئت بسماع هذا - اعتقدت أن Kubernetes كانت جاهزة لوقت الذروة؟ المبادلة هي إحدى تلك الميزات.

هذا ليس اختياريًا حقًا في معظم حالات الاستخدام المفتوح - إنها الطريقة التي يتم بها تصميم نظام Unix البيئي للتشغيل ، مع قيام VMM بتبديل الصفحات غير النشطة.

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

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

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

أعتقد بصدق أن هذه الخطوة الأخيرة لتشغيل الخوادم بدون مبادلة مدفوعة بموفري PaaS الذين يحاولون إجبار الأشخاص على مثيلات ذاكرة أكبر - مع تجاهل حوالي 40 عامًا من تصميم إدارة الذاكرة. الحقيقة هي أن النواة جيدة حقًا في معرفة صفحات الذاكرة النشطة أم لا - دعها تقوم بعملها.

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

تصبح المشكلات قديمة بعد 90 يومًا من الخمول.
ضع علامة على المشكلة على أنها جديدة /remove-lifecycle stale .
تتعفن المشكلات التي لا معنى لها بعد 30 يومًا إضافيًا من عدم النشاط وتغلق في النهاية.

إذا كان إغلاق هذه المشكلة آمنًا الآن ، فيرجى القيام بذلك باستخدام /close .

إرسال التعليقات إلى اختبار سيج ، kubernetes / test-infra و / أو fejta .
/ دورة الحياة التي لا معنى لها

لدي عدد كبير من قراءات القرص في عقد الكتلة الخاصة بي ( K8s Version - v1.11.2 ). قد يكون بسبب تعطيل ذاكرة المبادلة؟

https://stackoverflow.com/questions/51988566/high-number-of-disk-reads-in-kubernetes-nodes

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

srevenant أنا أتفق معك تمامًا ، يتم استخدام SWAP على ولادتهما ، وأعتقد أنني لم أر تطبيقًا خلال 15 عامًا من العمل على Linux يطلب إيقاف تشغيل SWAP.
دائمًا ما تكون مشكلة SWAP قيد التشغيل افتراضيًا عندما نقوم بتثبيت أي توزيعة Linux ، لذلك يجب أن أقوم بتشغيلها قبل تثبيت K8s وكانت تلك مفاجأة.
يعرف Linux Kernel جيدًا كيفية إدارة SWAP لزيادة أداء الخوادم بشكل خاص بشكل مؤقت عندما يكون الخادم على وشك الوصول إلى حد ذاكرة الوصول العشوائي.
هل هذا يعني أنه يجب علي إيقاف تشغيل SWAP حتى تعمل K8s بشكل جيد؟

أنا مهتم بإنجاح هذا العمل ، ولدي المهارات وعدد من الآلات للاختبار عليها. إذا كنت أرغب في المساهمة ، فأين هو أفضل مكان للبدء؟

superdave ، يرجى تجميع KEP في kubernetes / المجتمع الذي يصف كيف تريد دعم المبادلة ، وتقديمه إلى sig-node. نود الحصول على مساعدتك.

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

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

يمكنك منع ذلك عن طريق ضبط طلبات الذاكرة وفقًا للواقع الفعلي
حاجة التطبيق.

إذا كان ثلث ذاكرة التطبيق الخاص بك على أساس 2 من حيث الحجم
تخزين أبطأ ، هل سيكون قادرًا على القيام بأي عمل مفيد؟

يوم الأربعاء 26 سبتمبر 2018 الساعة 6:51 صباحًا كتب vasicvuk [email protected] :

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

-
أنت تتلقى هذا لأنك علقت.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/kubernetes/kubernetes/issues/53533#issuecomment-424604731 ،
أو كتم الخيط
https://github.com/notifications/unsubscribe-auth/AAICBqZApBscFl5aNA4IcYvlxcvPA88Tks5ueyPlgaJpZM4PwnD5
.

matthiasr يمكنك القيام بذلك عندما يكون لديك 10-50 خدمة. ولكن عندما يكون لديك Cluster يعمل على أكثر من 200 خدمة ويتم نشر نصفها باستخدام مخططات Helm الرسمية دون أي طلب ذاكرة في يدك.

ولكن بعد ذلك ، ألا تُفقد ذاكرة طلبات المشكلة التي يجب معالجتها؟

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

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

لا يؤدي تمكين المبادلة إلى تغيير سلوك kernel بشكل ملحوظ. كل ما يفعله هو توفير مساحة لمبادلة الصفحات المجهولة ، أو الصفحات المعدلة المحملة من الملفات المعينة COW.

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

هذا يجعل هذا خطأ: أنت تفشل في دعم ميزة kernel التي لا يمكن إيقاف تشغيلها بالفعل.

تضمين التغريدة

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

لا يمكنك إيقاف تشغيل المبادلة بالكامل ،

هل يمكنك تقديم بعض المراجع لهذا حتى أتمكن من تثقيف نفسي؟

ما لم تقم بتثبيت الملفات في الذاكرة (وهي قدرة يجب أن تمتلكها K8s للملفات القابلة للتنفيذ ، على الأقل) ،

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

adityakali هل من أفكار حول تأثير المبادلة في النواة عند إيقاف تشغيل المبادلة؟

هل يمكنك تقديم بعض المراجع لهذا حتى أتمكن من تثقيف نفسي؟

مثل جميع أنظمة تشغيل الذاكرة الافتراضية الحديثة ، يطلب Linux صفحات قابلة للتنفيذ من القرص إلى الذاكرة. تحت ضغط الذاكرة ، تقوم النواة بتبديل الشفرة التنفيذية الفعلية لبرنامجك إلى / من القرص تمامًا مثل أي صفحات ذاكرة أخرى ("التبديل" هو مجرد تجاهل لأنه للقراءة فقط ، ولكن الآلية هي نفسها) ، وسوف إعادة إحضارها إذا لزم الأمر مرة أخرى. ينطبق الشيء نفسه على أشياء مثل ثوابت السلسلة ، والتي عادةً ما يتم تعيينها للقراءة فقط من أقسام أخرى من الملف القابل للتنفيذ. يتم أيضًا تبديل الملفات الأخرى المميَّعة (الشائعة لأحمال العمل من نوع قاعدة البيانات) داخل + إخراج إلى ملفات النسخ ذات الصلة (تتطلب الكتابة الفعلية إذا تم تعديلها) استجابةً لضغط الذاكرة. التبادل _only_ الذي تقوم بتعطيله عن طريق "تعطيل المبادلة" هو "ذاكرة مجهولة" - الذاكرة التي _ لا _ مرتبطة بملف (أفضل الأمثلة هي هياكل البيانات "المكدسة" و "الكومة").

هناك الكثير من التفاصيل التي تجاوزتها في الوصف أعلاه بالطبع. على وجه الخصوص ، يمكن للملفات التنفيذية "قفل" أجزاء من مساحة الذاكرة الخاصة بهم في ذاكرة الوصول العشوائي باستخدام عائلة syscalls mlock ، والقيام بأشياء ذكية عبر madvise() ، يصبح الأمر معقدًا عندما تتم مشاركة نفس الصفحات بواسطة عمليات متعددة (على سبيل المثال ، libc.so) ، إلخ. أخشى أنه ليس لدي مؤشر أكثر فائدة لقراءة المزيد بخلاف تلك الصفحات ، أو أشياء عامة مثل الكتب المدرسية أو مصدر / مستندات / قائمة بريدية في لينكس.

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

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

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

لاستكشاف نقطة "مجموعة العمل ، وليس الذاكرة الظاهرية" ، ضع في اعتبارك برنامجًا يقوم بالكثير من إدخال / إخراج الملفات العادية وليس له علاقة بـ mmap. إذا كان لديك ذاكرة وصول عشوائي كافية ، فإن النواة ستخزن هياكل الدليل المستخدمة بشكل متكرر وبيانات الملف في ذاكرة الوصول العشوائي وتجنب الانتقال إلى القرص ، وستسمح لعمليات الكتابة بالاندفاع إلى ذاكرة الوصول العشوائي مؤقتًا لتحسين الكتابة على القرص. حتى برنامج "ساذج" مثل هذا سوف يتدهور من سرعات ذاكرة الوصول العشوائي إلى سرعات القرص اعتمادًا على حجم مجموعة العمل مقابل ذاكرة الوصول العشوائي المتاحة. عندما تقوم بتثبيت شيء ما في ذاكرة الوصول العشوائي دون داع (على سبيل المثال: استخدام mlock أو تعطيل المبادلة) ، فإنك تمنع النواة من استخدام تلك الصفحة من ذاكرة الوصول العشوائي الفعلية لشيء مفيد بالفعل و (إذا لم يكن لديك ذاكرة وصول عشوائي كافية لمجموعة العمل) نقل القرص I / O إلى مكان ما أكثر تكلفة.

@ superdave : أنا أيضًا مهتم بتحسين الوضع الراهن هنا. الرجاء تضمينني إذا كنت تريد زوجًا آخر من العيون لمراجعة مستند ، أو اليدين على لوحة المفاتيح.

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

@ superdave : أنا أيضًا مهتم بتحسين الوضع الراهن هنا. الرجاء تضمينني إذا كنت تريد زوجًا آخر من العيون لمراجعة مستند ، أو اليدين على لوحة المفاتيح.

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

كما أنني لست على دراية كافية بالضوابط التي لدينا لمعرفة مدى قدرتنا على التحكم في سلوك التبديل في الكبسولات / الحاويات الفردية ؛ قد يكون من المفيد أن تكون قادرًا على "إعادة ترتيب" الأشياء للاحتفاظ بها أو تبديلها ، ولكن من الواضح أن المطورين يتمتعون دائمًا بحرية محاولة إلغاء الحظر () عندما يحتاجون تمامًا إلى ضمان بقاء الأشياء على أي حال.

على أي حال ، نعم ، أريد بالتأكيد المضي قدمًا في هذا الأمر. لقد انغمست في العمل مؤخرًا (التعامل مع بعض مشكلات OOM مع خدماتنا المصغرة الخاصة بنا تحت k8s والتي كان من الممكن أن تستفيد من القدرة على التبديل تحت الحمل لأن 99 ٪ من الوقت لا يحتاجون إلى عربات RAM إلا إذا قام شخص ما بعمل كبير بشكل غير مرغوب فيه طلب) ، ولكن لا تتردد في متابعة الأمر. لم أشارك مطلقًا في عملية KEP من قبل ، لذا سأكون صديقًا للبيئة جدًا فيها ، لكن في هذه الأيام أعمل بشكل أفضل على أساس المقاطعة من عملية الاقتراع. :-)

أود أن أشير إلى أن zram يعمل عن طريق التراجع عن المقايضات. إذا لم يكن هناك مقايضات على k8 ، فلا يوجد ضغط للذاكرة ، وهو شيء تم تمكينه افتراضيًا في معظم أنظمة التشغيل بخلاف Linux (cue Windows ، MacOS).

لدينا مثيل Ubuntu على k8 يقوم بتشغيل مجموعة كبيرة من المهام كل ليلة والتي تستهلك الكثير من الذاكرة. نظرًا لأن عبء العمل لم يتم تحديده مسبقًا ، فنحن مضطرون (بشكل مكلف) إلى تخصيص 16 جيجابايت للعقدة بغض النظر عن استهلاك الذاكرة الفعلي لتجنب OOM. مع ضغط الذاكرة على خادم التطوير المحلي الخاص بنا ، تصل المهمة إلى 3 غيغابايت فقط. خلاف ذلك خلال النهار ، لا يستغرق الأمر سوى 1 جيجابايت من الذاكرة. يعد حظر المقايضات وبالتالي ضغط الذاكرة خطوة سخيفة.

أعتقد أن الشاغل الرئيسي هنا ربما يكون العزلة. يمكن لآلة نموذجية أن تستضيف عددًا كبيرًا من البودات ، وإذا ضاقت الذاكرة ، فيمكنها البدء في التبديل وتدمير أداء بعضها البعض تمامًا. إذا لم يكن هناك تبادل ، فإن العزلة أسهل بكثير.

أعتقد أن الشاغل الرئيسي هنا ربما يكون العزلة. يمكن لآلة نموذجية أن تستضيف عددًا كبيرًا من البودات ، وإذا ضاقت الذاكرة ، فيمكنها البدء في التبديل وتدمير أداء بعضها البعض تمامًا. إذا لم يكن هناك تبادل ، فإن العزلة أسهل بكثير.

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

يجب أن يؤدي تمكين المبادلة ، من تلقاء نفسه ، إلى تحسين العزلة بالفعل.

لكنها تشتري لك الكثير ، إذا قمت بتشغيل الأشياء بالطريقة التي من المفترض أن تقوم بها (والطريقة التي تدير بها Google الأشياء على Borg): يجب أن تحدد جميع الحاويات الحد الأعلى للذاكرة. يستفيد Borg من Google infra ويتعلم الحدود إذا كنت تريد ذلك (من استخدام الموارد السابقة وسلوك OOM) ، ولكن هناك حدود مع ذلك.

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

لكنها تشتري لك الكثير ، إذا قمت بتشغيل الأشياء بالطريقة التي من المفترض أن تقوم بها (والطريقة التي تدير بها Google الأشياء على Borg): يجب أن تحدد جميع الحاويات الحد الأعلى للذاكرة. يستفيد Borg من Google infra ويتعلم الحدود إذا كنت تريد ذلك (من استخدام الموارد السابقة وسلوك OOM) ، ولكن هناك حدود مع ذلك.

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

أعتقد أن المشكلة التي فشل هذا في معالجتها هي أن الحد الأعلى متغير ولا يُعرف دائمًا ببعض العمليات. تركز المشكلة التي أتعامل معها بشكل خاص على استخدام k8s لإدارة عقد عرض النماذج ثلاثية الأبعاد. اعتمادًا على الأصول الخاصة بالنموذج والمشهد الذي يتم تقديمه ، يمكن أن يختلف مقدار ذاكرة الوصول العشوائي المطلوبة قليلاً ، وبينما ستكون معظم عمليات العرض صغيرة ، فإن حقيقة أن _بعضها_ يمكن أن تكون ضخمة تعني أن طلباتنا وحدودنا يجب أن تحجز قدرًا أكبر من الذاكرة مما نحتاجه فعليًا إلى 90٪ من الوقت لتجنب OOM ، بدلاً من تجاوز البود أحيانًا الحد الذي تم تكوينه والقدرة على الامتداد إلى مساحة المبادلة.

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

لا تكمن المشكلة هنا في أن وظيفتك سوف تتسرب للمبادلة ، بل أن جميع الوظائف الأخرى التي تعمل على تلك العقدة ستكون كذلك. والبعض (معظمهم؟) لن يعجبهم على الإطلاق.

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

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

لا تفهموني خطأ ، أنا لا أقول أن هذه هي الطريقة الوحيدة "الصحيحة" لإدارة الأمور. أنا أحاول فقط توضيح الأساس المنطقي المحتمل الذي دخل في التصميم.

إخلاء المسؤولية: أنا موظف سابق في Google واستخدمت Borg لتشغيل العديد من الخدمات الكبيرة جدًا ، لذا فأنا أعرف ذلك جيدًا ، وتترجم هذه المعرفة إلى حد كبير إلى Kubernetes. لست حاليًا مع Google ، وكل ما أكتبه هنا هو أفكاري.

@ 1e100 : أنت

(أنا أيضًا أحد مستخدمي Google-SRE سابقًا ، وأوافق على أن هذه الأساطير الشائعة في Google هي بالتأكيد ما تم اتخاذ قرار بشأنه (أو حتى مرغوب فيه) لتعطيل التبديل على k8s أيضًا. لقد شاهدت العديد من فرق Google تتحرك من خلال تعلم أن تعطيل المبادلة لا يؤدي إلى تعطيل المبادلة ، وإهدار الذاكرة الكلي الذي يتبع فقط وصف حد "صعب" (قتل أوم) للذاكرة - هذه بالتحديد بعض الأشياء التي أود تحسينها باستخدام k8s. هناك عدد من المقابض القابلة للضبط cgroup / swap متاحة الآن ولم يكن لدينا عندما تم تصميم نموذج مورد borg في البداية ، وأنا مقتنع بأنه يمكننا تحقيق النتائج المرجوة دون اتباع نهج رمي الطفل مع مياه الاستحمام . سألاحظ أيضًا أن مقايضة Google _ في كثير من الأحيان_ تكون أقل كفاءة في المتوسط ​​من أجل تحقيق وقت أسوأ / أسوأ حالة معروف (أي: السلوك في الوقت الفعلي) وأن هذا غالبًا _ليس_ هو الخيار المرغوب خارج Google - أصغر / مضيف أقل ، SLOs أكثر استرخاء ، ميزانيات أقل ، تعريف ضعيف أكثر إد الوظائف المجمعة ، واستخدام المزيد من اللغات غير المجمعة غير الفعالة في الكومة ، وما إلى ذلك)

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

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

هذه بيئات مشتركة حسب التصميم ، وتريد التخلص من الطرق التي تجعل البرامج أداء بعضها البعض غير متوقع ، وليس إضافة أخرى جديدة. كما تقول شركة SREs من Google "الأمل ليس إستراتيجية". تعد Swap thrashing هي أسهل طريقة أعرفها لإغلاق جهاز Linux تمامًا وبشكل لا يمكن إصلاحه ، حتى إذا كنت تقوم بالتبديل إلى SSD. لا يمكن أن يكون ذلك جيدًا حتى لو كنت تقوم بتشغيل حمل عمل واحد على الجهاز ، ناهيك عن بضع عشرات. يمكن أن تكون حالات الفشل المترابطة مؤلمة بشكل خاص في مجموعات أصغر مع عدد قليل من المهام / الكبسولات.

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

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

فقط لإظهار إلى أين سأذهب مع هذا ، فإن اقتراحي الحالي هو:

  • الاستعارة هي أن كل حاوية تتصرف كما لو كانت على آلة بمفردها مع قدر معين من الكبش (يُعطى بواسطة limits.memory ) وقم بتبديلها.
  • مثل الموارد الأخرى: الجدول على أساس requests.memory ، فرض حدًا على أساس limits.memory . "الذاكرة" في هذه الحالة تعني "ذاكرة الوصول العشوائي" - استخدام المبادلة مجاني.
  • على وجه التحديد k8s requests.memory -> cgroup memory.low (تم تصغيرها بواسطة أي عامل زيادة الالتزام) ؛ k8s limits.memory -> cgroup memory.high .
  • إذا تجاوزت الحاوية حد الذاكرة التي تم تكوينها ، فإنها تبدأ في التبديل - _ بغض النظر_ عن مقدار ذاكرة الوصول العشوائي المجانية المتاحة. بفضل cgroups ، هذا _ ليس فقط استخدام VM ، ولكنه يتضمن أيضًا ذاكرة التخزين المؤقت للكتل ، ومخازن مأخذ التوصيل المؤقتة ، وما إلى ذلك المنسوب إلى الحاوية. هذا يمنعنا من الضغط على الذاكرة على الحاويات الأخرى (أو العمليات المضيفة). عند البحث عن صفحة لإخراجها ، ستبحث النواة عن الحاويات التي تتجاوز حجم طلب الذاكرة الخاص بها.
  • أدخل حدًا ناعمًا لاستخدام المبادلة الكلية kubelet soft حيث ستتوقف k8s عن جدولة البودات الجديدة على المضيف (تمامًا مثل "أنظمة الملفات المشتركة" الأخرى مثل imagefs).
  • إذا وصلنا إلى الحد الثابت لإجمالي استخدام المبادلة ، فابدأ في طرد البودات بناءً على فئة qos / الأولوية وحجم الجهاز الظاهري أعلى "الطلبات" (تمامًا مثل "أنظمة الملفات المشتركة" الأخرى مثل imagefs).
  • إذا تجاوزت الحاوية مجموعة عملها بشكل كبير ( requests.memory ) ، فقد تتعطل (إذا تجاوزت أيضًا limits.memory أو لم يكن هناك ذاكرة تخزين كافية متوفرة على المضيف). نحن بصراحة _ لا_ نفعل أي شيء حيال ذلك من خلال آلية الموارد. إذا كانت الحاوية تتعثر ، فستفشل (من المفترض) في عمليات التحقق من قابلية الاستجابة / الاستعداد وستُقتل من خلال تلك الآلية (على سبيل المثال: swap-thrashing لا بأس به إذا لم يكن لدينا اتفاقيات مستوى الخدمة (SLA) للاستجابة المهيأة).

والنتيجة النهائية هي أن المسؤول مسؤول عن تكوين مقايضة "كافية" على كل نظام. يجب على التطبيقات تكوين limits.memory مع ذاكرة الوصول العشوائي _max_ التي يريدون استخدامها ، و requests.memory مع مجموعة العمل المقصودة (بما في ذلك مخازن kernel المؤقتة ، إلخ). كما هو الحال مع الموارد الأخرى ، لا تزال فئات qos مضمونة (limit == request) ، قابلة للانفجار (حد غير محدد أو! = طلب) ، أفضل جهد (بدون حد أو طلب). على وجه الخصوص ، يشجع هذا العمليات القابلة للانفجار على الإعلان بالقرب من مجموعة العمل المقصودة (لا يوجد مخزن أمان كبير) ، مما يسمح بالتخصيص الفعال (بشكل مثالي 100 ٪ بالضبط من ذاكرة الوصول العشوائي المخصصة لمجموعة العمل) ويعطي تدهورًا سلسًا في الأداء عندما تتجاوز الحاويات ذلك - تمامًا مثل الموارد الأخرى "المتسامحة" مثل وحدة المعالجة المركزية.

أعتقد أن هذا قابل للتنفيذ داخل مجموعات cgroups Linux ، ويعالج مخاوف العزلة ، ويستمر في السوابق المفاهيمية التي حددتها موارد k8s الأخرى ، ويتراجع إلى السلوك الحالي عند تعطيل المبادلة (مما يجعل الترحيل أمرًا سهلاً). السؤال الوحيد الذي أطرحه هو ما إذا كان هذا _بالفعل_ ما تم تنفيذه (باستثناء حد "kubelet soft / hard" "swapfs" - أحتاج إلى الذهاب وقراءة رمز kubelet / CRI cgroups الفعلي قبل أن أتمكن من كتابة اقتراح محدد وعناصر عمل .

التعليقات / المناقشة حول ما سبق قد لا تكون مناسبة في قضية جيثب هذه (إنه منتدى مناقشة ضعيف). إذا كان هناك أي خطأ فادح في ما سبق ، فسأرحب بتعليقات guslees على k8s slack ، وإلا سأكتب مستندًا مناسبًا وأذهب في مناقشة التصميم المعتادة في مرحلة ما.

أوصي بكتابة مستند رسمي حتى نتمكن من الحصول على منتدى أفضل للمناقشة.

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

ولكن ، أيضًا ، ليس لدي النطاق الترددي لمواكبة قناة Slack في أوقات فراغي ؛ إذا كانت هناك طريقة غير متزامنة للتنسيق ، فيرجى إبلاغي بذلك.

فقط لإبقاء الأمور على قيد الحياة: ما زلت مهتمًا جدًا بالعمل على KEP و / أو التنفيذ لهذا ؛ بمجرد أن تستقر الأمور (لدي ورشة عمل للتحضير لعطلة نهاية الأسبوع القادمة) ، سأحاول الانضمام إلى قناة Slack.

مرحبًا ، هل هناك أي نقاش عام حول هذه القضية يحدث حاليًا؟ (فترة السماح لـ k8s ليست مفتوحة للجميع في الوقت الحالي ، وأفترض أنها لن تكون متاحة لبعض الوقت).

leonaves لا يوجد نقاش حول guslees هو آخر المناقشة. لاحظ أنه يجب أن يكون هناك KEP مع التفاصيل في kubernetes / repo التحسينات لبدء الأمور وربما سلاسل الرسائل البريدية أيضًا.

يبدو أن هناك نهاية النفق لإعادة فتح الركود قريبًا جدًا. عبور أصابعي.

كما اتضح ، ما زلت لا أمتلك النطاق الترددي الذهني للانضمام إلى قناة Slack أخرى. ما زلت لا أزال مع التعاون في هذا عبر البريد الإلكتروني.

حل بديل لأولئك الذين يريدون حقًا المبادلة. اذا أنت

  • ابدأ kubelet بـ --fail-swap-on=false
  • أضف المبادلة إلى العقد الخاصة بك
  • ستتمكن الحاويات التي لا _حدد متطلبات الذاكرة بعد ذلك افتراضيًا من استخدام كل ذاكرة الجهاز ، بما في ذلك المبادلة.

هذا ما نفعله. أو على الأقل ، أنا متأكد من ذلك ، لم أقم بتطبيقه شخصيًا ، لكن هذا ما أجمعه.

قد تكون هذه إستراتيجية قابلة للتطبيق فقط إذا لم تحدد أي من حاوياتك متطلبات ذاكرة صريحة ...

هل هذه الطريقة لا تعمل بعد الآن !؟ قمت بتشغيل المبادلة ونشر جراب بدون إعداد ذاكرة ، وحصلت على هذه الحاوية

$ docker inspect <dockerID> | grep Memory
            "Memory": 0,
            "KernelMemory": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": -1

قيمة MemorySwap هي "0" ، مما يعني أن هذه الحاوية لا يمكنها الوصول إلى المبادلة :(

تصبح المشكلات قديمة بعد 90 يومًا من الخمول.
ضع علامة على المشكلة على أنها جديدة /remove-lifecycle stale .
تتعفن المشكلات التي لا معنى لها بعد 30 يومًا إضافيًا من عدم النشاط وتغلق في النهاية.

إذا كان إغلاق هذه المشكلة آمنًا الآن ، فيرجى القيام بذلك باستخدام /close .

إرسال التعليقات إلى اختبار سيج ، kubernetes / test-infra و / أو fejta .
/ دورة الحياة التي لا معنى لها

/ إزالة دورة الحياة التي لا معنى لها.

/ إزالة دورة الحياة التي لا معنى لها

الذهاب لإسقاط هذا هنا كمرجع آخر لقراء هذه المشكلة: https://chrisdown.name/2018/01/02/in-defence-of-swap.html

تصبح المشكلات قديمة بعد 90 يومًا من الخمول.
ضع علامة على المشكلة على أنها جديدة /remove-lifecycle stale .
تتعفن المشكلات التي لا معنى لها بعد 30 يومًا إضافيًا من عدم النشاط وتغلق في النهاية.

إذا كان إغلاق هذه المشكلة آمنًا الآن ، فيرجى القيام بذلك باستخدام /close .

إرسال التعليقات إلى اختبار سيج ، kubernetes / test-infra و / أو fejta .
/ دورة الحياة التي لا معنى لها

/ إزالة دورة الحياة التي لا معنى لها

هذه الميزة مطلوبة حقًا في بعض حالات الاستخدام. نستخدم حاليًا k8s للتعلم الآلي وأحيانًا نحتاج إلى تحميل نماذج كبيرة في الذاكرة (في حالتنا أحيانًا 500 ميجا بايت لكل طلب api!) ، وتتسبب حدود الذاكرة الفعلية في حدوث مشكلات خطيرة. سيعمل التدرج من منظور شخصي تقني ولكن التكاليف ستذهب إلى السطح ، إذا كانت لدينا الذاكرة الافتراضية كخيار فسيكون ذلك رائعًا.

هل من فرصة أن تعود هذه التذكرة إلى خريطة الطريق مرة أخرى؟

يبدو وكأنه حالة ل map.

أنا أيضًا مهتم جدًا بهذه الميزة. هل هناك أي أخبار عن هذا؟

يسعدني أن أبدأ في النظر في هذا عندما يكون لدي الوقت ، وهو نقص في المعروض الآن ، ولكن سيكون من الجيد أن يكون لديك حالة قانونية أو اثنتين مما يؤدي إلى تفاقم المشكلة حتى يمكن تمييزها بشكل كامل (بعد ذلك " يبدأ بالضرب وكل شيء يذهب إلى الجحيم ") ويتم التحقق من صحة النهج النهائي والإصلاح.

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

سيكون من الجيد أن يكون لديك حالة قانونية أو حالتان تؤديان إلى تفاقم المشكلة حتى يمكن وصفها بشكل كامل

هذا يبدو وكأنه KEP .

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

سينطبق هذا المنطق على أي عمليات تعمل في مزيج من الحاويات ، بغض النظر عما إذا كان Kubernetes قيد الاستخدام أم لا.

متفق! لكن Docker يدعم بالفعل بشكل صريح التشغيل بالمبادلة. Kubernetes لا يفعل ذلك صراحة (على الرغم من أنه يمكنك إجباره على ذلك). رأيي هو أنه يجب أن يتم استدعاؤه على الأقل ، لأنه ليس في نموذج التهديد لدى الجميع ، خاصةً إذا لم يكن عليهم التفكير في الأمر سابقًا.

نعم أيضًا ، sftim ، إنه كذلك. :-) أعتقد أن ما أقوله هو أنني أرغب في الكتابة / المساهمة في KEP ، لكني أرغب في رؤية حالة أو حالتين اختبار بسيطتين تمارسان المشكلة بشكل موثوق به على نظام اختبار معين قبل المغامرة بذلك يمكننا التأكد من أننا نحل المشكلات الصحيحة.

superdave ما نوع حالة الاختبار التي تفكر فيها؟

هذا اختبار تافه:

  1. قم بإعداد كتلة مع 1 عقدة و 16 جيجا بايت من ذاكرة الوصول العشوائي و 64 جيجا بايت من ملف ترحيل الصفحات.
  2. حاول جدولة 20 جرابًا ، لكل منها طلب ذاكرة 1 جيجا بايت وحد ذاكرة 1 جيجا بايت.
  3. لاحظ أنه لا يتم تحديد كل شيء.

هنا آخر:

  1. قم بإعداد 6 آلات ، لكل منها 16 جيجا بايت من ذاكرة الوصول العشوائي و 64 جيجا بايت من ملف الصفحات.
  2. حاول استخدام kubeadm مع الخيارات الافتراضية لتهيئة هذه الأجهزة كمجموعة Kubernetes.
  3. لاحظ أن kubeadm ليس سعيدًا بشأن استخدام المقايضة.

هناك تحول كبير في SSD على معظم الأنظمة الأساسية السحابية المحترمة الآن ، وبالنظر إلى أن Linux خصص تحسينات للمبادلة على SSD https://lwn.net/Articles/704478/ مع إمكانية إضافية للضغط ، فإن هذا الموقف يجعل فرصة جديدة تمامًا لاستخدام المبادلة كـ مورد يمكن التنبؤ به وسريع لذاكرة RAM إضافية في حالة ضغط الذاكرة.
يصبح التبادل المعطل موردًا ضائعًا بنفس الطريقة التي يتم بها إهدار ذاكرة الوصول العشوائي غير المستخدمة إذا لم يتم استخدامها لمخازن الإدخال / الإخراج المؤقتة.

تضمين التغريدة

متفق! لكن Docker يدعم بالفعل بشكل صريح التشغيل بالمبادلة. Kubernetes لا يفعل ذلك صراحة (على الرغم من أنه يمكنك إجباره على ذلك). رأيي هو أنه يجب أن يتم استدعاؤه على الأقل ، لأنه ليس في نموذج التهديد لدى الجميع ، خاصةً إذا لم يكن عليهم التفكير في الأمر سابقًا.

في هذه الحالة ، سيكون من العدل افتراض أن kubelet سوف mlock() مساحة الذاكرة الخاصة به وتعيين OOM kill أولوية منخفضة لتجنب التبديل أو قتل OOM ، وتشغيل جميع الحاويات في cgroups بـ swapiness تعيين 0 افتراضيًا. إذا أراد شخص ما الاستفادة من مبادلة النموذج ، فيمكنه الاشتراك عن طريق استخدام خيار مثل enableSwapiness: 50 لحاوية (حاويات) معينة في الحجرة.
لا مفاجآت ، البطاريات متضمنة.

sftim تلك derekwaynecarr :

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

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

وأيضًا أسفله مباشرةً من @ matthiasr :

هناك المزيد من السياق في المناقشة هنا: # 7294 - وجود تبادل متاح له تفاعلات غريبة وسيئة للغاية مع حدود الذاكرة. على سبيل المثال ، الحاوية التي تصل إلى حد الذاكرة الخاص بها _ ثم تبدأ في الانسكاب في المبادلة (يبدو أن هذا تم إصلاحه منذ f4edaf2 - لن يُسمح لهم باستخدام أي مقايضة سواء كانت موجودة أم لا).

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

تضمين التغريدة

متفق! لكن Docker يدعم بالفعل بشكل صريح التشغيل بالمبادلة. Kubernetes لا يفعل ذلك صراحة (على الرغم من أنه يمكنك إجباره على ذلك). رأيي هو أنه يجب أن يتم استدعاؤه على الأقل ، لأنه ليس في نموذج التهديد لدى الجميع ، خاصةً إذا لم يكن عليهم التفكير في الأمر سابقًا.

في هذه الحالة ، سيكون من العدل افتراض أن kubelet سوف mlock() مساحة الذاكرة الخاصة به وتعيين OOM kill أولوية منخفضة لتجنب التبديل أو قتل OOM ، وتشغيل جميع الحاويات في cgroups بـ swapiness تعيين 0 افتراضيًا. إذا أراد شخص ما الاستفادة من مبادلة النموذج ، فيمكنه الاشتراك عن طريق استخدام خيار مثل enableSwapiness: 50 لحاوية (حاويات) معينة في الحجرة.
لا مفاجآت ، البطاريات متضمنة.

أعتقد أنني أتفق مع كل شيء هنا. التقصير في السلوك الحالي لتجنب المفاجآت غير السارة.

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

#include <iostream>
#include <vector>
#include <unistd.h>
int main() {
  std::vector<int> data;
  try
    {
        while(true) { data.resize(data.size() + 200); };
    }
    catch (const std::bad_alloc& ex)
    {
        std::cerr << "Now we filled up memory, so assume we never access that stuff again and just moved on, or we're stuck in an endless loop of some sort...";
        while(true) { usleep(20000); };
    }
  return 0;
}

حل بديل لأولئك الذين يريدون حقًا المبادلة. اذا أنت

  • ابدأ kubelet بـ --fail-swap-on=false
  • أضف المبادلة إلى العقد الخاصة بك
  • ستتمكن الحاويات التي لا _حدد متطلبات الذاكرة بعد ذلك افتراضيًا من استخدام كل ذاكرة الجهاز ، بما في ذلك المبادلة.

هذا ما نفعله. أو على الأقل ، أنا متأكد من ذلك ، لم أقم بتطبيقه شخصيًا ، لكن هذا ما أجمعه.

قد تكون هذه إستراتيجية قابلة للتطبيق فقط إذا لم تحدد أي من حاوياتك متطلبات ذاكرة صريحة ...

مرحبًا hjwp ، شكرًا لك على معلوماتك. هذا حقا يساعد كثيرا!

هل يمكنني طرح سؤال بعد هذا؟

بعد إعداد كل شيء كما قلت ، هل هناك طريقة للحد من استخدام ذاكرة المبادلة بواسطة الحاويات؟

كنت أفكر في تعيين بارامز --memory-swap لـ Docker
https://docs.docker.com/config/containers/resource_constraints/# - تفاصيل الذاكرة المبادلة
حاليًا ، لا يوجد حد لاستخدام الحاوية الخاصة بي على استخدام المبادلة ( "MemorySwap": -1 )

sudo docker inspect 482d70f73c7c | grep Memory
            "Memory": 671088640,
            "KernelMemory": 0,
            "MemoryReservation": 0,
            "MemorySwap": -1,
            "MemorySwappiness": null,

لكن لم أجد هذه المعلمة مكشوفة في k8s.

بالمناسبة ، هل سيؤدي الحد على ذاكرة البودات أيضًا إلى تقييد استخدام المبادلة؟

الإعدادات المتعلقة بجهاز vm الخاص بي

vm.overcommit_kbytes = 0
vm.overcommit_memory = 1
vm.overcommit_ratio = 50
vm.swappiness = 20
vm.vfs_cache_pressure = 1000

شكرا لك!

@ pai911 لا أعتقد أن هذا ممكن ،

حاليًا ، CRI لا تدعم ذلك ، انظر إلى هذا ، لا يوجد خيار مثل --memory-swap في عامل الإرساء

هذا هو قيود CRI على الرغم من أن مواصفات OCI تدعم هذا الخيار ، ولكن لا يتم تصديرها إلى طبقة CRI

أحد الحلول الممكنة (نظريًا) هو إنشاء مجموعة DaemonSet مميزة والتي بدورها تقرأ بيانات التعليقات التوضيحية من الكبسولات ، ثم تقوم DaemonSet بتحرير قيمة cgroup يدويًا

cgroup

مرحبًا @ win-t ،

شكرا لك على ملاحظاتك!

حتى الآن ، هذا الخيار للاستخدام الداخلي فقط؟

هل تعرف ما هي قيمة cgroup التي تم تعيينها لخيار مبادلة الذاكرة هذا؟

حتى الآن ، هذا الخيار للاستخدام الداخلي فقط؟

نعم ، لا يمكنك ضبط هذا الخيار ، حيث لا يتم عرضهما في k8s

راجع للشغل ، يجب أن يكون فحص عامل الإرساء MemorySwap هو نفسه مع Memory وفقًا لهذا ، لا أعرف كيف يمكنك الحصول على -1 في فحص عامل الإرساء الخاص بك

هل تعرف ما هي قيمة cgroup التي تم تعيينها لخيار مبادلة الذاكرة هذا؟

  • --memory في خريطة عامل التحميل لـ memory.limit_in_bytes في cgroup v1
  • --memory-swap في خريطة عامل التحميل لـ memory.memsw.limit_in_bytes في cgroup v1

@ win-t شكرا جزيلا لك!

أنا أستخدم الإصدار التالي

Client Version: version.Info{Major:"1", Minor:"15", GitVersion:"v1.15.5", GitCommit:"20c265fef0741dd71a66480e35bd69f18351daea", GitTreeState:"clean", BuildDate:"2019-10-15T19:16:51Z", GoVersion:"go1.12.10", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"15", GitVersion:"v1.15.10", GitCommit:"1bea6c00a7055edef03f1d4bb58b773fa8917f11", GitTreeState:"clean", BuildDate:"2020-02-11T20:05:26Z", GoVersion:"go1.12.12", Compiler:"gc", Platform:"linux/amd64"}

ونظرت في التاريخ. يبدو أنه تمت إضافة الإصلاح في هذا الالتزام

ربما لم يتم تضمينه في الإصدار الذي أقوم بتشغيله؟

حتى الآن ، هذا الخيار للاستخدام الداخلي فقط؟

نعم ، لا يمكنك ضبط هذا الخيار ، حيث لا يتم عرضهما في k8s

راجع للشغل ، يجب أن يكون فحص عامل الإرساء MemorySwap هو نفسه مع Memory وفقًا لهذا ، لا أعرف كيف يمكنك الحصول على -1 في فحص عامل الإرساء الخاص بك

هل تعرف ما هي قيمة cgroup التي تم تعيينها لخيار مبادلة الذاكرة هذا؟

  • --memory في خريطة عامل التحميل لـ memory.limit_in_bytes في cgroup v1
  • --memory-swap في خريطة عامل التحميل لـ memory.memsw.limit_in_bytes في cgroup v1

هذا غريب.

كنت أستخدم kops + Debian ، ويظهر فحص Docker أنه لا يوجد حد لذاكرة Swap
(يقوم Docker بفحص المعلومات التي نشرتها سابقًا)

ولكن بعد ذلك انتقلت إلى صورة Amazon Linux ، وهذا ما حصلت عليه

            "Memory": 671088640,
            "KernelMemory": 0,
            "MemoryReservation": 0,
            "MemorySwap": 671088640,
            "MemorySwappiness": null,

سأفعل المزيد من التحقيقات وأرى ما إذا كان هذا خطأ

حتى الآن ، هذا الخيار للاستخدام الداخلي فقط؟

نعم ، لا يمكنك ضبط هذا الخيار ، حيث لا يتم عرضهما في k8s
راجع للشغل ، يجب أن يكون فحص عامل الإرساء MemorySwap هو نفسه مع Memory وفقًا لهذا ، لا أعرف كيف يمكنك الحصول على -1 في فحص عامل الإرساء الخاص بك

هل تعرف ما هي قيمة cgroup التي تم تعيينها لخيار مبادلة الذاكرة هذا؟

  • --memory في خريطة عامل التحميل لـ memory.limit_in_bytes في cgroup v1
  • --memory-swap في خريطة عامل التحميل لـ memory.memsw.limit_in_bytes في cgroup v1

هذا غريب.

كنت أستخدم kops + Debian ، ويظهر فحص Docker أنه لا يوجد حد لذاكرة Swap
(يقوم Docker بفحص المعلومات التي نشرتها سابقًا)

ولكن بعد ذلك انتقلت إلى صورة Amazon Linux ، وهذا ما حصلت عليه

            "Memory": 671088640,
            "KernelMemory": 0,
            "MemoryReservation": 0,
            "MemorySwap": 671088640,
            "MemorySwappiness": null,

سأفعل المزيد من التحقيقات وأرى ما إذا كان هذا خطأ

يمكنني الآن إعادة إنتاج المشكلة الموجودة في صورة دبيان الرسمية بواسطة kops

يبدو أن هذه الصورة الرسمية لـ kops ستجعل ذاكرة المبادلة غير محدودة
kope.io/k8s-1.15-debian-stretch-amd64-hvm-ebs-2020-01-17

خطوات الاستنساخ:

يتم تحديد مجموعة مثيلات kops على النحو التالي:

apiVersion: kops.k8s.io/v1alpha2
kind: InstanceGroup
metadata:
  creationTimestamp: "2020-03-12T06:33:09Z"
  generation: 5
  labels:
    kops.k8s.io/cluster: solrcluster.k8s.local
  name: node-2
spec:
  additionalUserData:
  - content: |
      #!/bin/sh
      sudo cp /etc/fstab /etc/fstab.bak
      sudo mkfs -t ext4 /dev/nvme1n1
      sudo mkdir /data
      sudo mount /dev/nvme1n1 /data
      echo '/dev/nvme1n1       /data   ext4    defaults,nofail        0       2' | sudo tee -a /etc/fstab
      sudo fallocate -l 2G /data/swapfile
      sudo chmod 600 /data/swapfile
      sudo mkswap /data/swapfile
      sudo swapon /data/swapfile
      echo '/data/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
      sudo sysctl vm.swappiness=10
      sudo sysctl vm.overcommit_memory=1
      echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf
      echo 'vm.overcommit_memory=1' | sudo tee -a /etc/sysctl.conf
    name: myscript.sh
    type: text/x-shellscript
  image: kope.io/k8s-1.15-debian-stretch-amd64-hvm-ebs-2020-01-17
  instanceProtection: true
  kubelet:
    failSwapOn: false
  machineType: t3.micro

خطوات:

  1. بعد تشغيل الكتلة وتشغيلها.

  2. قم بنشر Solr Helm Chart باستخدام إعداد المورد التالي

resources:
  limits:
    cpu: "1"
    memory: 640Mi
  requests:
    cpu: 100m
    memory: 256Mi

** يجب أن يعمل أي قرنة أخرى أيضًا

  1. قائمة الحاويات للعثور على معرف الحاوية
    sudo docker container ls

  2. افحص معلمات ذاكرة الحاوية
    sudo docker inspect d67a72bba427 | grep Memory

            "Memory": 671088640,
            "KernelMemory": 0,
            "MemoryReservation": 0,
            "MemorySwap": -1,
            "MemorySwappiness": null,

هل يجب علي إرسال المشكلة في مكان ما؟ k8s أو kops؟

خطوات:

  1. بعد تشغيل الكتلة وتشغيلها.
  2. قم بنشر Solr Helm Chart باستخدام إعداد المورد التالي
resources:
  limits:
    cpu: "1"
    memory: 640Mi
  requests:
    cpu: 100m
    memory: 256Mi

** يجب أن يعمل أي قرنة أخرى أيضًا

  1. قائمة الحاويات للعثور على معرف الحاوية
    sudo docker container ls
  2. افحص معلمات ذاكرة الحاوية
    sudo docker inspect d67a72bba427 | grep Memory
            "Memory": 671088640,
            "KernelMemory": 0,
            "MemoryReservation": 0,
            "MemorySwap": -1,
            "MemorySwappiness": null,

هل يجب علي إرسال المشكلة في مكان ما؟ k8s أو kops؟

يمكنني أن أؤكد أنه يمكنني فقط رؤية السلوك الصحيح على Amazon Linux
ami-0cbc6aae997c6538a : amzn2-ami-hvm-2.0.20200304.0-x86_64-gp2

            "Memory": 671088640,
            "CpusetMems": "",
            "KernelMemory": 0,
            "MemoryReservation": 0,
            "MemorySwap": 671088640,
            "MemorySwappiness": null,

وهذا هو: "تغيير الذاكرة" == "الذاكرة"

كلتا الصورتين الأخريين لهما نفس الإعداد: "MemorySwap": -1 ، مما يؤدي إلى استخدام مقايضة غير محدود.

  • ديبيان

    • ami-075e61ad77b1269a7 : k8s-1.15-debian-stretch-amd64-hvm-ebs-2020-01-17

  • أوبونتو

    • ami-09a4a9ce71ff3f20b : ubuntu / images / hvm-ssd / ubuntu-bionic-18.04-amd64-server-20200112

لذا أعتقد أنها قد تكون مشكلة k8s؟

قصص المستخدم:

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

(2) أقوم بتشغيل التعلم الآلي أو عبء عمل تحليل البيانات حيث يمكن أن يتضخم استخدام الذاكرة فجأة ويتراجع. لا بأس إذا كانت هذه التطبيقات بطيئة ، طالما أنها لا تنتهي وتنتهي في النهاية. أرغب في تزويد المجموعة بالمقايضة للتخفيف من عمليات الإخلاء عند حدوث بالونات الذاكرة هذه. سيكون لهذه السنفات طلبات منخفضة للذاكرة والمبادلة ، وحد متوسط ​​للذاكرة - ربما يكفي لخط الأساس + مجموعة عمل واحدة - وحد كبير للتبديل.

(3) أقوم بتشغيل خادم ويب في مترجم (مثل Ruby on Rails) يحتاج أحيانًا إلى fork + exec. تؤدي محاسبة الذاكرة الصارمة إلى حدوث حالات فشل مفترق ، وهو أمر غير مقبول. أرغب في توفير المبادلة بحيث يكون للنواة مساحة رأس مضمونة للذاكرة لتغطية سلوك العملية بين مكالمات fork و exec. يمكن تعيين قيمة vm.swappiness على تثبيط المبادلة للغاية ، وقمت بإعداد تنبيهات لإخطار العمليات إذا تم استخدام المبادلة بالفعل أثناء الإنتاج. تحدد مواصفات الكبسولة طلب المبادلة وتقييدها بنفس القيمة.

لقد حاولنا مؤخرًا ترحيل جميع خدماتنا المستندة إلى عامل الإرساء إلى Kubernetes ، لكننا اضطررنا إلى التخلي عن المشروع نظرًا لأن التبادل غير مدعوم.

وجدنا أننا سنحتاج إلى توفير 3 أضعاف كمية الأجهزة من أجل دعم نفس العدد الدقيق للحاويات التي كنا نشغلها حاليًا مع تمكين التبديل.

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

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

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

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

قد يجرؤ المرء على القول إن التطبيقات التي تعمل في تلك الحاويات مكتوبة بشكل سيء للغاية.

قد يجرؤ المرء على القول إن التطبيقات التي تعمل في تلك الحاويات مكتوبة بشكل سيء للغاية.

هذا نوع من غير ذي صلة ، ونادرًا ما يكون توجيه أصابع الاتهام بناء. تم تصميم نظام Kubernetes البيئي لدعم مجموعة واسعة من ملفات تعريف التطبيقات ، ولا يُفرد أحدها مثل هذا كثيرًا.

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

قد يجرؤ المرء على القول إن التطبيقات التي تعمل في تلك الحاويات مكتوبة بشكل سيء للغاية.

لول ، هذه ميزة kernel ، يمكن للتطبيق استخدام madvise(2) على ملف shm ، ونحن لا نحظر madvise syscall ،
لذلك فهو مؤهل للمستخدم للاستفادة من هذه الميزة في تصميمه ، ولا يمكنك القول "تمت كتابته بشكل سيئ للغاية" ،

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

قد يجرؤ المرء على القول إن التطبيقات التي تعمل في تلك الحاويات مكتوبة بشكل سيء للغاية.

يشير ردك إلى أنك لا تفهم أعباء العمل التي يعمل معها العديد من المطورين.

يتعامل عبء العمل الذي ذكرته مع مجموعات بيانات مختلفة الحجم مقدمة من المستخدمين ، وبالتالي النطاق الكبير لمتطلبات الموارد المحتملة.

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

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

تحتاج بعض عمليات نشر Kubernetes إلى التبديل

لدي حالة استخدام صالحة - أقوم بتطوير منتج محلي ، Linux distro ، متضمن مع kubeadm. لا مقياس أفقي حسب التصميم. لكي أتمكن من النجاة من ذروة الذاكرة الانتهازية والاستمرار في العمل (ولكن بطيئًا) ،

لتثبيت kubeadm مع تمكين التبديل

  1. أنشئ ملفًا في /etc/systemd/system/kubelet.service.d/20-allow-swap.conf بالمحتوى:

    [Service]
    Environment="KUBELET_EXTRA_ARGS=--fail-swap-on=false"
    
  2. يركض

    sudo systemctl daemon-reload
    
  3. قم بتهيئة kubeadm باستخدام العلم --ignore-preflight-errors=Swap

    kubeadm init --ignore-preflight-errors=Swap
    

https://stackoverflow.com/a/62158455/3191896

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

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

metatick قال:

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

تم تصميم مكتبة Linux القياسية C لاستبدال مخصص الذاكرة ؛ يتم استدعاء malloc و realloc و free من خلال مؤشرات لهذا الغرض. لذلك يمكنك فقط LD_PRELOAD مكتبة تتجاوزها للتخصيص من ملف مميَّز.

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

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

السؤال الوحيد الذي أطرحه هو ما إذا كان هذا هو ما تم تنفيذه بالفعل (باستثناء حد kubelet soft / hard "swapfs") - أحتاج إلى الذهاب وقراءة كود kubelet / CRI cgroups الفعلي قبل أن أتمكن من كتابة اقتراح محدد وعناصر عمل .

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

شكرا،
يناير

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

لم أفعل. (لقد بحثت في رمز عامل الميناء قليلاً ، لكنني نسيت كل شيء عنه الآن وسأحتاج إلى البدء من جديد)

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

للإضافة إلى قصة metatick :

أستخدم حاليًا Gigalixir كمضيف لي ، يعمل على قمة Kubernetes. إنه تطبيق ويب. في بعض الأحيان ، يقوم العملاء بتحميل مجموعة من الصور ، لذلك يقوم تطبيقي بتدوير مجموعة من عمليات ImageMagick لتغيير حجمها. طفرات استخدام الذاكرة ، يتم تشغيل OOM killer ، وينخفض ​​تطبيقي (لفترة وجيزة) ويتلف التحميل.

انتهى بي الأمر إلى دفع أطنان إلى Gigalixir أكثر مما ينبغي لمجرد استخدام spikey. كما ذكر آخرون.

قد لا تحب المبادلة من منظور التصميم ، لكن قرارك يكلف رجال الأعمال أموالًا ... وهو مضيعة للوقت.

ارجو الاصلاح. :)

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

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

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

ولكن في الوقت الحالي ، لماذا لا ندع المبادلة موجودة على العقدة ، فقم بتعيين Swappiness على 0 للقرون التي ليس لها حد معين ، وعندما يتم تعيين حد (أو بعض حقول المواصفات الأخرى لقول "swapInsteadOfKill") ، قم بتعيين المبادلة إلى قيمة غير صفرية؟

بجانب المناقشة حول "المبادلة أو عدم المبادلة" ، أشعر بالفضول لأن السلوك الموصوف بواسطة @ pai911 لم يتم تناوله بشكل أكبر من قبل فريق k8s.

أستطيع أن أؤكد أن kubelet يبدو أنه يتصرف بشكل مختلف (وعلى بعض أنظمة التشغيل ليس وفقًا للرمز الذي تم قصه أعلاه) فيما يتعلق بإعدادات ذاكرة docker deamon. تعمل مجموعاتنا على SUSE linux ونواجه نفس استخدام المبادلة غير المحدود المذكور في https://github.com/kubernetes/kubernetes/issues/53533#issuecomment -598056151

تفاصيل نظام التشغيل: SUSE Linux Enterprise Server 12 SP4 - Linux 4.12.14-95.45-default

بدون الدعم المناسب لـ Swap في k8s على أي حال ، أود على الأقل أن يتعامل kubelet مع إعدادات ذاكرة Docker باستمرار بغض النظر عن نظام التشغيل الأساسي.

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

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

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

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات