LimitNPROC مقابل TasksMax: ما الذي تحسبه وحدة OpenVPN
يعد LimitNPROC عمليات مستخدم واحد على مستوى النظام كله، بينما يحد TasksMax من cgroup وحدة واحدة. اقرأ القيم الفعلية قبل رفع أي منهما.
غالبًا ما يصل فشل بدء تشغيل OpenVPN في صورة شكوى بشأن الموارد مع اقتراح حسن النية برفع أحد الحدود، ولا ينجح هذا الاقتراح إلا في نحو نصف الحالات. ثمة عدّادان غير مترابطين يقفان خلف تلك الإخفاقات. أحدهما حد في النواة على عدد المهام التي يملكها معرّف مستخدم حقيقي، ويُورَّث عند تنفيذ العملية. والآخر ميزانية cgroup يطبقها مدير الخدمة على وحدة وعلى كل ما تتفرع عنه. وقراءة القيمة الفعلية لكل منهما، للوحدة التي تعمل فعلاً، تكلف أقل من التخمين.
عدّادان، سؤالان
LimitNPROC هو RLIMIT_NPROC تحت اسم systemd، ووحدة محاسبته هي معرّف المستخدم الحقيقي. كل عملية يملكها ذلك المستخدم تُحسب ضد المجموع نفسه، بما في ذلك العمل الذي تبدأه وحدات أخرى أو جلسة تسجيل دخول أو وظيفة مجدولة. لذا ليس هذا الحد سقفًا لكل خدمة على حدة حتى عندما يُضبط داخل وحدة خدمة، والخدمة التي تتفرع عنها عملية مساعدة لكل عميل تنافس كل شيء آخر يعمل تحت ذلك الحساب. وقد تدفع وظيفة cron مشغولة تحت المستخدم نفسه وحدة VPN إلى ما وراء خط لم تتجاوزه أبدًا بمفردها.
TasksMax له مالك مختلف: وحدة تحكم pids على cgroup الخاصة بالوحدة، وهي تعُد المهام لا العمليات. الخيوط مهام، لذا يمكن لبرنامج خفي يبدو أحادي الخيط وله مجموعة عمال أن يستهلك ميزانية تبدو للوهلة الأولى أكبر بكثير من عدد عملياته. ويوضح EffectiveTasksMax ما تسمح به هرمية cgroup فعلاً بعد أن تقول الشرائح الأعلى كلمتها.
لماذا يغيّر استثناء الجذر الإجابة
لا تطبق النواة RLIMIT_NPROC على عملية تحمل CAP_SYS_RESOURCE أو CAP_SYS_ADMIN، ولهذا فإن وحدة تعمل بصلاحيات الجذر دون التخلي عن الامتيازات تكون عمليًا بلا حد بموجب ذلك الإعداد. هذا الاستثناء الوحيد يفسر النصيحة المتناقضة التي يتبادلها الناس: رفع LimitNPROC يصلح نشرًا تخلّى عن الامتيازات ولا يفعل شيئًا إطلاقًا لنشر بقي متمتعًا بها. تحقق من User= ومن كون البرنامج الخفي يغيّر هويته بعد بدء التشغيل قبل أن تنسب الفضل أو اللوم لذلك الإعداد. والوحدة المتمتعة بالامتيازات التي تتحول لاحقًا إلى حساب غير متمتع بها تعود تحت الحد في لحظة التحول، وهو ما يجعل الجدول الزمني للفشل جديرًا بالقراءة أيضًا.
مرحلة الفشل تضيّق الأمر أكثر. فالرفض أثناء تهيئة التنفيذ، وخطأ التفرع الذي يبلغ عنه البرنامج الخفي نفسه، ورفض إنشاء مهمة داخل cgroup، تُنتج أسطر سجل مختلفة، وواحد منها فقط يجيبه رفع الميزانية.
اقرأ القيم الفعلية، لا قيم الطرفية
ulimit -u في طرفية تفاعلية يصف تلك الطرفية. وهو لا يصف ما مرره مدير الخدمة إلى البرنامج الخفي، ولا يقول شيئًا عن محاسبة cgroup. استعلم عن الوحدة بدلاً من ذلك، مستخدمًا اسم النسخة الموجود على المضيف لا مثالًا من دليل.
systemctl show [email protected] -p User -p LimitNPROC -p TasksCurrent -p TasksMax -p EffectiveTasksMax
cat /proc/$(systemctl show -p MainPID --value [email protected])/limits | grep -i processes
داخل حاوية تحتاج الإجابة إلى قراءتين إضافيتين، لأن القيمة الداخلية infinity لا تصف إلا رؤية الضيف. اطلب من مالك المضيف سقف pids الخاص بالحاوية، وتأكد مما إذا كان مدير الخدمات الداخلي قادرًا على تفويض وحدة التحكم تلك أصلاً. فالوحدة المتداخلة لا يمكنها حمل ميزانية لم تمنحها إياها cgroup الأم.
قدّر حجم الإصلاح وأثبته تحت الحمل
اختر رقمًا من عبء العمل لا من نص الخطأ. أحصِ العمليات التي يبدأها البرنامج الخفي لكل عميل متصل أو لكل استدعاء مساعد، واضربها في التزامن المتوقع أن يحمله النشر، وأضف هامشًا للجلسات الإدارية، ثم قارن ذلك الرقم بالقيمتين الفعليتين. إن تجاوز محلي من نوع drop-in يبقي التغيير قابلًا للمراجعة ويصمد أمام ترقيات الحزم، في حين أن تعديل ملف وحدة مشحون يخفي التعديل حتى تستبدله التحديثة التالية. اكتب الحساب بجوار التجاوز، لأن الشخص التالي الذي سيرفعه أو يخفضه يحتاج إلى الافتراضات لا إلى الرقم النهائي.
تُطبق تغييرات الميزانية عند التنفيذ، لذا لا يعيد التحميل وحده ضبط حجم العمليات التي تعمل بالفعل. أعد تشغيل الوحدة عبر دورة حياتها الطبيعية، مع قبول انقطاع الجلسة، واقرأ العدّادات مرة أخرى على النسخة الجديدة.
sudo systemctl daemon-reload
sudo systemctl restart [email protected]
systemctl show [email protected] -p TasksCurrent -p EffectiveTasksMax
sudo journalctl -u [email protected] -b --no-pager | tail -n 20
ما يثبت الإصلاح هو وحدة أُعيد تشغيلها ويقع عدد مهامها تحت السقفين وهي تحمل الحمل المقصود، مع سجل لم يعد يبلغ عن استنفاد المهام أو التفرع في المرحلة نفسها. احتفظ بأرقام قبل وبعد مع التغيير كي يبدأ التحقيق التالي من قياس لا من النصيحة نفسها. وإذا كان العدد ما زال يبلغ السقف، فالحساب كان خاطئًا لا الحد صغيرًا بالخطأ، وهذا الفرق جدير بالمعرفة قبل إعادة التشغيل التالية.