LimitNPROC बनाम TasksMax: एक OpenVPN यूनिट क्या गिनती है
LimitNPROC पूरे सिस्टम में एक उपयोगकर्ता की प्रक्रियाएँ गिनता है; TasksMax एक यूनिट के cgroup को सीमित करता है। इनमें से कोई भी बढ़ाने से पहले प्रभावी मान पढ़ें।
विफल OpenVPN स्टार्ट अक्सर संसाधन की शिकायत और सीमा बढ़ाने के सद्भावपूर्ण सुझाव के रूप में आता है, और वह सुझाव केवल लगभग आधे मामलों में काम करता है। इन विफलताओं के पीछे दो असंबंधित काउंटर हैं। एक कर्नेल की सीमा है—किसी वास्तविक उपयोगकर्ता ID के स्वामित्व वाले कार्यों की संख्या पर, और प्रक्रिया चलाते समय यह विरासत में मिलती है। दूसरा cgroup बजट है, जिसे सेवा प्रबंधक एक यूनिट और उससे फोर्क होने वाली हर चीज़ पर लागू करता है। जो यूनिट वास्तव में चल रही है, उसके लिए हर एक का प्रभावी मान पढ़ना अनुमान से कम खर्चीला है।
दो काउंटर, दो सवाल
LimitNPROC systemd नाम के तहत RLIMIT_NPROC है, और इसकी गणना-इकाई वास्तविक उपयोगकर्ता ID है। उस उपयोगकर्ता के स्वामित्व वाली हर प्रक्रिया उसी कुल में गिनी जाती है, जिसमें अन्य यूनिट, लॉगिन सत्र या शेड्यूलर जॉब द्वारा शुरू किया गया काम भी शामिल है। इसलिए यह सीमा सेवा-वार कैप नहीं है, भले ही इसे किसी सेवा यूनिट के भीतर सेट किया गया हो, और हर क्लाइंट के लिए हेल्पर फोर्क करने वाली सेवा उस खाते के तहत चलने वाली बाकी हर चीज़ से प्रतिस्पर्धा करती है। उसी उपयोगकर्ता के तहत एक व्यस्त क्रॉन जॉब VPN यूनिट को उस रेखा से आगे धकेल सकता है जिसे उसने अकेले कभी पार नहीं किया।
TasksMax का स्वामी अलग है: यूनिट के cgroup पर pids नियंत्रक, जो प्रक्रियाओं के बजाय कार्य गिनता है। थ्रेड कार्य हैं, इसलिए एक थ्रेड जैसा दिखने वाला पर वर्कर पूल वाला डेमॉन ऐसा बजट खा सकता है जो पहली नज़र में उसकी प्रक्रिया संख्या से कहीं बड़ा लगता है। EffectiveTasksMax बताता है कि मूल स्लाइस अपनी बात कह लेने के बाद cgroup पदानुक्रम वास्तव में क्या अनुमति देता है।
root अपवाद उत्तर क्यों बदलता है
कर्नेल CAP_SYS_RESOURCE या CAP_SYS_ADMIN वाली प्रक्रिया पर RLIMIT_NPROC लागू नहीं करता, इसीलिए विशेषाधिकार छोड़े बिना root के रूप में चलने वाली यूनिट उस सेटिंग से व्यवहार में असीमित रहती है। यही एक अपवाद लोगों के बीच अदला-बदली होती विरोधाभासी सलाह को समझाता है: LimitNPROC बढ़ाना विशेषाधिकार छोड़ चुके परिनियोजन को ठीक करता है और विशेषाधिकार बनाए रखने वाले के लिए कुछ भी नहीं करता। उस सेटिंग को श्रेय या दोष देने से पहले User= और यह जाँचें कि डेमॉन शुरू होने के बाद पहचान बदलता है या नहीं। जो यूनिट विशेषाधिकारों के साथ चलती है पर बाद में अपरिविलेज्ड खाते में जाती है, वह बदलाव के क्षण में फिर से सीमा के नीचे आ जाती है, जिससे विफलता की समयरेखा भी पढ़ने योग्य बनती है।
विफलता का चरण इसे और संकीर्ण करता है। निष्पादन की तैयारी के दौरान इनकार, डेमॉन द्वारा स्वयं बताई गई फोर्क त्रुटि, और cgroup के भीतर अस्वीकृत कार्य निर्माण—ये अलग journal पंक्तियाँ देते हैं, और इनमें से केवल एक का उत्तर बड़े बजट से मिलता है।
प्रभावी मान पढ़ें, शेल के नहीं
इंटरैक्टिव शेल का 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
सुधार को साबित करती है वह पुनः आरंभ की गई यूनिट जिसकी कार्य संख्या इच्छित भार उठाते हुए भी दोनों सीमाओं के नीचे रहती है, साथ में ऐसा journal जो उसी चरण पर अब कार्य या फोर्क समाप्त होने की सूचना नहीं देता। बदलाव के साथ पहले-बाद की संख्याएँ रखें ताकि अगली जाँच उसी सलाह से नहीं, किसी मापन से शुरू हो। यदि संख्या अब भी सीमा तक पहुँचती है, तो गणना गलत थी, सीमा संयोगवश बहुत छोटी नहीं थी, और अगले रीस्टार्ट से पहले यह अंतर जानना उचित है।