प्रतिनिधि इंटरव्यू विषय

Linux इंटरव्यू: कंटेनर्स प्रक्रियाओं और संसाधनों को कैसे अलग (आइसोलेट) करते हैं?

सामान्यकठिन
Offer.cc संपादकीय टीमप्रकाशित अपडेट किया गया

प्रश्न

cgroup v2 वाले Linux होस्ट पर, कंटेनर A अपने एप्लिकेशन को PID 1 के रूप में देखता है और उसका अपना एक प्राइवेट होस्टनेम, माउंट टेबल और नेटवर्क स्टैक है। इसे 512 MiB मेमोरी, औसतन 0.5 CPU और अधिकतम 128 टास्क के लिए कॉन्फ़िगर किया गया है। बताएं कि रनटाइम नेमस्पेस, रूट फ़ाइलसिस्टम और cgroups की मदद से इस सीमा का निर्माण कैसे करता है; होस्ट के साथ क्या साझा रहता है; प्रत्येक सीमा तक पहुँचने पर क्या होता है; यूज़र नेमस्पेस, कैपेबिलिटीज़, seccomp और LSM इस सीमा को कैसे मजबूत करते हैं; और आप होस्ट तथा कंटेनर दोनों तरफ से प्रत्येक दावे को कैसे सत्यापित करेंगे।

प्रॉम्प्ट और लागू संदर्भ

cgroup v2 का उपयोग करने वाले Linux होस्ट पर, कंटेनर A के पास ये अभ्यास प्रतिबंध हैं:

प्रतिबंधठोस cgroup v2 मान
Memorymemory.max = 536870912 बाइट्स, या 512 MiB
CPUcpu.max = 50000 100000, या प्रत्येक 100 ms में अधिकतम 50 ms
Task countpids.max = 128

कंटेनर के अंदर, एप्लिकेशन स्वयं को PID 1, एक कंटेनर होस्टनेम, अपनी माउंट टेबल और अपने नेटवर्क इंटरफ़ेस के रूप में देखता है। बताएं कि रनटाइम उस परिवेश को कैसे बनाता है, आइसोलेशन वास्तव में कहाँ से आता है, और लिमिट फेलियर कैसे दिखाई देते हैं। फिर साझा-कर्नेल सुरक्षा सीमा को कवर करें और केवल एक सफल docker run के बजाय अवलोकनीय कर्नेल स्थिति के साथ कॉन्फ़िगरेशन को साबित करें।

यह प्रश्न Linux, प्लेटफ़ॉर्म, SRE, DevOps, इन्फ्रास्ट्रक्चर, क्लाउड, सुरक्षा और बैकएंड भूमिकाओं पर लागू होता है। ये मान इंटरव्यू के प्रतिबंध हैं, अनुशंसित डिफ़ॉल्ट नहीं। "कंटेनर" एक Linux OCI-स्टाइल प्रोसेस कंटेनर को संदर्भित करता है; VM-समर्थित कंटेनर उत्पाद एक अलग आइसोलेशन लेयर जोड़ते हैं।

इंटरव्यूअर क्या मूल्यांकन कर रहा है

पहला परीक्षण यह है कि क्या उम्मीदवार "लाइटवेट VM" वाक्यांश को एक सटीक प्रोसेस मॉडल से बदल सकता है। Linux कंटेनर होस्ट पर एक प्रोसेस ट्री होता है। नेमस्पेस उन वैश्विक संसाधनों को बदलते हैं जिन्हें वे प्रक्रियाएं देख सकती हैं: PID, माउंट, नेटवर्क ऑब्जेक्ट, IPC ऑब्जेक्ट, होस्ट पहचान, यूज़र ID, cgroup पाथ और वैकल्पिक रूप से क्लॉक। एक रूट फ़ाइलसिस्टम और एक प्राइवेट माउंट व्यू यूज़रस्पेस इमेज की आपूर्ति करते हैं। इनमें से कोई भी दूसरा कर्नेल नहीं बनाता है।

दूसरा परीक्षण दृश्यता (visibility) को संसाधन नियंत्रण (resource control) से अलग करना है। नेमस्पेस इस सवाल का जवाब देते हैं कि "यह प्रक्रिया किस इंस्टेंस को देख या संशोधित कर सकती है?" Cgroups जवाब देते हैं कि "यह समूह कितना उपभोग कर सकता है, और इसका हिसाब कैसे रखा जाता है?" एक PID नेमस्पेस टास्क की संख्या को सीमित नहीं करता है। एक cgroup PID सीमा होस्ट प्रक्रियाओं को नहीं छिपाती है। एक माउंट नेमस्पेस माउंट व्यू को बदलता है, जबकि rootfs फ़ाइलों की आपूर्ति करता है। केवल chroot न तो एक पूर्ण कंटेनर है और न ही एक सुरक्षा सीमा।

तीसरा परीक्षण सटीक cgroup v2 फ़ाइलों से व्यवहार प्राप्त करना है। memory.max एक हार्ड मेमोरी सीमा है जो रिक्लेम विफल होने के बाद cgroup-लोकल OOM किल का कारण बन सकती है। cpu.max बैंडविड्थ नियंत्रण है: 100 ms की अवधि में 50 ms की खपत के बाद, चलने योग्य कार्य (runnable work) तब तक थ्रॉटल किया जाता है जब तक कि कोटा उपलब्ध न हो; इसे किल नहीं किया जाता है। pids.max उल्लंघन करने वाले fork() या clone() को EAGAIN के साथ अस्वीकार कर देता है। उम्मीदवार को उन इवेंट काउंटरों के नाम बताने चाहिए जो इन परिणामों में अंतर करते हैं।

चौथा परीक्षण सुरक्षा निर्णय (security judgment) है। कंटेनर होस्ट कर्नेल को साझा करते हैं, इसलिए नेमस्पेस और cgroups एक VM सीमा के बराबर नहीं होते हैं। यूज़र-ID मैपिंग, एक छोटा कैपेबिलिटी सेट, no_new_privs, seccomp, AppArmor या SELinux जैसा LSM, रीड-ओनली या मास्क्ड माउंट, और सीमित डिवाइस अटैक सर्फ़ेस को कम करते हैं। एक प्रिविलेज्ड कंटेनर, होस्ट PID या नेटवर्क नेमस्पेस, Docker सॉकेट, या व्यापक होस्ट माउंट जानबूझकर महत्वपूर्ण सीमाओं को हटा सकते हैं।

अंत में, इंटरव्यूअर एक सत्यापन योजना (verification plan) चाहता है। उत्तर में सीमा के दोनों पक्षों से नेमस्पेस इनोड पहचान, UID/GID मैपिंग, cgroup सदस्यता और नियंत्रक फ़ाइलें, प्रोसेस कैपेबिलिटीज़, seccomp स्थिति, माउंट प्रोपेगेशन, नेटवर्क इंटरफ़ेस और विफलता काउंटरों की तुलना की जानी चाहिए।

उत्तर देने से पहले स्पष्ट करने योग्य प्रश्न

  • कौन सा रनटाइम और कंटेनर मोड दायरे में है? Linux पर एक OCI रनटाइम माना गया है। रूटलेस मोड, यूज़र-नेमस्पेस रीमैपिंग, प्रिविलेज्ड मोड और VM-समर्थित सैंडबॉक्स ट्रस्ट बाउंड्री को बदलते हैं।
  • क्या "0.5 CPU" का अर्थ कोटा है या सापेक्ष भार (relative weight)? यहाँ इसका अर्थ 100,000-माइक्रोसेकंड की अवधि में 50,000 माइक्रोसेकंड की बैंडविड्थ कैप है। cpu.weight केवल कंटेंशन के दौरान सापेक्ष हिस्सेदारी को बदलता है।
  • 512 MiB में क्या शामिल है? cgroup v2 प्रमुख उपयोगकर्ताओं जैसे अनाम मेमोरी (anonymous memory), पेज कैश, कर्नेल संरचनाओं और सॉकेट बफ़र्स का हिसाब रखता है, लेकिन प्रत्येक होस्ट संसाधन इस एकल फ़ाइल द्वारा नियंत्रित नहीं होता है।
  • क्या 128 का अर्थ प्रक्रियाएं हैं या कर्नेल टास्क? pids नियंत्रक कर्नेल टास्क ID का उपयोग करता है, इसलिए थ्रेड्स भी बजट का उपभोग करते हैं। यह विवरण अत्यधिक थ्रेडेड रनटाइम के लिए मायने रखता है।
  • क्या स्वैप सक्षम है और अलग से सीमित है? memory.max और memory.swap.max अलग-अलग नियंत्रण हैं। प्रॉम्प्ट केवल मेमोरी सीमा तय करता है, इसलिए स्वैप नीति का निरीक्षण किया जाना चाहिए, न कि मान लिया जाना चाहिए।
  • वास्तव में कौन से नेमस्पेस कॉन्फ़िगर किए गए हैं? OCI कॉन्फ़िगरेशन एक नेमस्पेस बना सकता है, पाथ द्वारा किसी मौजूदा नेमस्पेस से जुड़ सकता है, या प्रकार को छोड़ सकता है और रनटाइम के नेमस्पेस को इनहेरिट कर सकता है। किसी एक का छूटना एक वास्तविक सीमा परिवर्तन है।
  • थ्रेट मॉडल क्या है? मल्टी-टेनेंट शत्रुतापूर्ण वर्कलोड के लिए प्रोसेस आइसोलेशन के अलावा एक VM या microVM सीमा की आवश्यकता हो सकती है। एक विश्वसनीय आंतरिक वर्कलोड एक अलग संतुलन स्वीकार कर सकता है।

30-सेकंड उत्तर का ढाँचा

"एक Linux कंटेनर rootfs के विरुद्ध शुरू किया गया एक होस्ट प्रोसेस ट्री है, जिसे चयनित नेमस्पेस और एक cgroup में रखा गया है; होस्ट कर्नेल साझा रहता है। नेमस्पेस विचारों (views) को अलग करते हैं, जबकि cgroups खपत का हिसाब रखते हैं और उसे सीमित करते हैं। यहाँ, memory.max=536870912 विफल रिक्लेम के बाद cgroup OOM का कारण बन सकता है, cpu.max=50000 100000 निष्पक्ष-वर्ग (fair-class) के काम को प्रति 100 ms में 50 ms के बाद थ्रॉटल करता है, और pids.max=128 उल्लंघन करने वाले fork या clone को EAGAIN के साथ अस्वीकार कर देता है।

मैं जहाँ उपयुक्त हो वहाँ UID मैपिंग, न्यूनतम कैपेबिलिटीज़, no_new_privs, seccomp, एक AppArmor या SELinux नीति, सुरक्षित माउंट और प्रतिबंधित डिवाइस जोड़ूंगा। मैं दोनों पक्षों से नेमस्पेस पहचान, UID मैप, माउंट, इंटरफ़ेस, प्रभावी cgroup फ़ाइलों, कैपेबिलिटीज़ और सुरक्षा स्थिति को सत्यापित करूंगा, फिर सीमित परीक्षण चलाऊंगा और मिलान वाले memory.events, cpu.stat, और pids.events साक्ष्य की आवश्यकता होगी।"

चरण-दर-चरण गहन विश्लेषण

चरण 1: होस्ट-प्रोसेस मॉडल से शुरुआत करें

रनटाइम को एक रूट फ़ाइलसिस्टम और कॉन्फ़िगरेशन वाला OCI बंडल प्राप्त होता है। एक प्रतिनिधि सेटअप क्रम है:

  1. बंडल, निष्पादन योग्य फ़ाइल (executable), माउंट, नेमस्पेस विकल्पों, क्रेडेंशियल्स और संसाधन सेटिंग्स को मान्य करना;
  2. cgroup सब-ट्री बनाना या चुनना और नियंत्रक मान लिखना;
  3. नए नेमस्पेस बनाना या कॉन्फ़िगर किए गए मौजूदा नेमस्पेस में शामिल होना;
  4. यदि यूज़र नेमस्पेस का उपयोग किया जाता है, तो UID/GID मैपिंग स्थापित करना;
  5. माउंट प्रोपेगेशन को सुरक्षित बनाना, rootfs और विशेष फ़ाइलसिस्टम को माउंट करना, और प्रोसेस रूट को स्विच करना;
  6. नया नेटवर्क नेमस्पेस उपयोग किए जाने पर नेटवर्क डिवाइस बनाना या स्थानांतरित करना और रूट कॉन्फ़िगर करना;
  7. क्रेडेंशियल, कैपेबिलिटीज़, no_new_privs, seccomp, और LSM लेबल या प्रोफ़ाइल सेट करना;
  8. प्रक्रिया को cgroup से जोड़ना और कॉन्फ़िगर किए गए एप्लिकेशन को exec करना।

सटीक क्रम और सहायक प्रक्रियाएं रनटाइम के अनुसार भिन्न होती हैं। इनवेरिएंट अवलोकनीय कर्नेल स्थिति है: एप्लिकेशन नेमस्पेस सदस्यता, क्रेडेंशियल, माउंट, फ़िल्टर और एक cgroup पाथ के साथ एक होस्ट-शेड्यूल प्रक्रिया बनी रहती है। यदि रनटाइम आंशिक सेटअप के बाद क्रैश हो जाता है, तो क्लीनअप को माउंट, इंटरफ़ेस, नेमस्पेस पिन और cgroups को हटाना होगा; "कंटेनर" शब्द कोई कर्नेल ऑब्जेक्ट नहीं है जो स्वचालित रूप से क्लीनअप करता है।

चरण 2: प्रत्येक नेमस्पेस को एक ज़िम्मेदारी सौंपें

मुख्य नेमस्पेस एक दूसरे के पूरक हैं:

नेमस्पेसपृथक दृश्य (आइसोलेटेड व्यू)महत्वपूर्ण सीमा
PIDप्रोसेस ID नंबर स्पेस और दृश्यताएक ही टास्क का एक आंतरिक PID और एक होस्ट PID होता है; कंटेनर PID 1 को चाइल्ड प्रक्रियाओं को रीप (reap) करना चाहिए और सिग्नलों को सही ढंग से संभालना चाहिए
Mountमाउंट पॉइंट और प्रोपेगेशनयह माउंट टेबल को बदलता है, अंतर्निहित कर्नेल या स्वचालित रूप से बैकिंग स्टोरेज को नहीं
Networkइंटरफ़ेस, रूट, पोर्ट, सॉकेट और नेटवर्क स्टैकveth पेयर, ब्रिज, रूटिंग या किसी अन्य नेटवर्क ड्राइवर के साथ कनेक्टिविटी को जानबूझकर फिर से जोड़ा जाता है
UTSहोस्टनेम और NIS डोमेन नामयह पहचान की प्रस्तुति है, प्रमाणीकरण नहीं
IPCSystem V IPC और POSIX मैसेज क्यूमाउंट के माध्यम से जानबूझकर साझा की गई फ़ाइलें या सॉकेट अभी भी वर्कलोड को जोड़ सकते हैं
UserUID/GID मैपिंग और नेमस्पेस-स्कोप्ड कैपेबिलिटीज़अंदर का UID 0 एक अनप्रिविलेज्ड होस्ट UID पर मैप हो सकता है
Cgroupcgroup पदानुक्रम का दृश्यसंसाधन प्रवर्तन नियंत्रकों से आता है, cgroup नेमस्पेस व्यू से नहीं
Timeबूट और मोनोटोनिक क्लॉक ऑफ़सेटयह मनमाना स्वतंत्र वॉल-क्लॉक हार्डवेयर प्रदान नहीं करता है

OCI नेमस्पेस सूची से छूटा हुआ नेमस्पेस प्रकार रनटाइम से इनहेरिट किया जाता है। --pid=host, होस्ट नेटवर्किंग, या किसी अन्य कंटेनर के नेमस्पेस में शामिल होना जानबूझकर किया जा सकता है, लेकिन उत्तर में पूरी तरह से प्राइवेट कंटेनर का वर्णन करने के बजाय खोए हुए आइसोलेशन को रेखांकित किया जाना चाहिए।

फ़ाइलसिस्टम सीमा के लिए माउंट नेमस्पेस और rootfs दोनों की आवश्यकता होती है। एक प्राइवेट या स्लेव प्रोपेगेशन मोड कंटेनर माउंट इवेंट को अप्रत्याशित रूप से होस्ट पर जाने से रोकता है। रीड-ओनली माउंट, मास्क्ड पाथ, एक न्यूनतम /dev, और स्पष्ट बाइंड माउंट एक्सेस को सीमित करते हैं। होस्ट रूट या कंटेनर-इंजन सॉकेट का राइटेबल बाइंड माउंट प्रक्रिया के प्राइवेट होस्टनेम की परवाह किए बिना सीधा उच्च-प्रभाव वाला पाथ बनाता है।

चरण 3: तीन संसाधन-सीमा परिणामों को समझें

मेमोरी। memory.max=536870912 cgroup और उसके वंशजों के लिए मुख्य हार्ड लिमिट है। जैसे-जैसे उपयोग सीमा के करीब पहुंचता है, कर्नेल रिक्लेम का प्रयास करता है। यदि उपयोग सीमा तक पहुंच जाता है और इसे कम नहीं किया जा सकता है, तो cgroup OOM हैंडलिंग में प्रवेश करता है; डिफ़ॉल्ट मोड में OOM किलर उस cgroup में एक टास्क का चयन कर सकता है, और memory.oom.group=1 एक अविभाज्य वर्कलोड के रूप में व्यवहार का अनुरोध कर सकता है। सीमा से ऊपर की संक्षिप्त रीडिंग हो सकती है। memory.current, memory.peak, और memory.events में max, oom, oom_kill, और oom_group_kill फ़ील्ड की जाँच करें। उन काउंटरों और कर्नेल या रनटाइम साक्ष्य के बिना प्रत्येक SIGKILL को cgroup OOM के रूप में डायग्नोज़ न करें।

CPU। cpu.max=50000 100000 का अर्थ है कि समूह में निष्पक्ष-वर्ग (fair-class) के टास्क प्रत्येक 100,000-माइक्रोसेकंड की अवधि के दौरान 50,000 माइक्रोसेकंड तक उपभोग कर सकते हैं: 0.5 CPU की औसत बैंडविड्थ। एकाधिक थ्रेड एक साथ कोटा खर्च कर सकते हैं और इसे अवधि में पहले ही समाप्त कर सकते हैं। चलने योग्य टास्क तब तक थ्रॉटल किए जाते हैं जब तक कि कोटा उपलब्ध न हो जाए; उन्हें समाप्त (terminate) नहीं किया जाता है। cpu.stat में usage_usec, nr_periods, nr_throttled, और throttled_usec का निरीक्षण करें। इसलिए अवधि की सीमा के पास लेटेंसी स्पाइक कोटा थ्रॉटलिंग हो सकता है, भले ही होस्ट CPU अन्यथा उपलब्ध हो।

टास्क। pids.max=128 कर्नेल टास्क पर एक पदानुक्रमित (hierarchical) हार्ड लिमिट है। थ्रेड्स भी गिने जाते हैं। एक बार जब कोई नया टास्क नीति का उल्लंघन करता है, तो fork() या clone() EAGAIN के साथ विफल हो जाता है; मौजूदा टास्क चलते रहते हैं। pids.current, pids.peak, और pids.events में max गणना का निरीक्षण करें। मौजूदा टास्क को स्थानांतरित करने या कॉन्फ़िगर की गई सीमा को कम करने से अस्थायी रूप से pids.current > pids.max उत्पन्न हो सकता है; नए निर्माण को अभी भी नीति का उल्लंघन करने से रोक दिया जाता है।

पैरेंट cgroups भी चाइल्ड cgroups को बाधित करते हैं। एक चाइल्ड वह CPU, मेमोरी या टास्क क्षमता प्राप्त नहीं कर सकता जिसकी उसके पूर्वज अनुमति नहीं देते हैं। इसके विपरीत, ये तीन सेटिंग्स स्वचालित रूप से प्रत्येक संसाधन को सीमित नहीं करती हैं: स्टोरेज स्पेस, I/O, फ़ाइल डिस्क्रिप्टर, नेटवर्क बैंडविड्थ, डिवाइस और कर्नेल-वैश्विक ऑब्जेक्ट्स को अपने स्वयं के नियंत्रण और ऑपरेटिंग सीमाओं की आवश्यकता होती है।

चरण 4: साझा कर्नेल के चारों ओर लेयर्ड सुरक्षा नियंत्रण

यूज़र नेमस्पेस एक प्रक्रिया को अंदर UID 0 होने की अनुमति देते हैं जबकि बाहर एक सामान्य अनप्रिविलेज्ड UID पर मैप होते हैं। यह नेमस्पेस एस्केप या गलत होस्ट-फ़ाइल एक्सेस के प्रभाव को कम करता है, लेकिन मैपिंग और फ़ाइलसिस्टम स्वामित्व को एक साथ डिज़ाइन किया जाना चाहिए। यूज़र नेमस्पेस के बिना, कंटेनर में रूट अभी भी होस्ट UID 0 है, भले ही इसकी कैपेबिलिटीज़ और सुलभ ऑब्जेक्ट प्रतिबंधित हों।

कैपेबिलिटीज़ पारंपरिक रूट विशेषाधिकारों को विभाजित करती हैं। सभी कैपेबिलिटीज़ देने के बजाय न्यूनतम सेट से शुरुआत करें। किसी कैपेबिलिटी को हटाना केवल तभी उपयोगी होता है जब प्रक्रिया उसे फ़ाइल कैपेबिलिटीज़, सेट-यूज़र-ID निष्पादन, या किसी अन्य पाथ के माध्यम से फिर से हासिल नहीं कर सकती है; एक सीमित सेट और no_new_privs उस इरादे को ऑडिट योग्य बनाते हैं।

Seccomp सिस्टम कॉल को फ़िल्टर करता है और कॉल तथा तर्कों के आधार पर अनुमति, अस्वीकार, ट्रैप, किल, लॉग या सूचित कर सकता है। यह पहुंच योग्य कर्नेल अटैक सर्फ़ेस को कम करता है लेकिन एप्लिकेशन-स्तरीय प्राधिकरण को नहीं समझता है। AppArmor या SELinux जैसा LSM फ़ाइलों, प्रक्रियाओं, सॉकेट्स और अन्य ऑब्जेक्ट्स पर संचालन के लिए नीति लागू करता है। रीड-ओनली फ़ाइलसिस्टम, मास्क्ड /proc पाथ, और एक न्यूनतम डिवाइस सेट स्वतंत्र बाधाएं जोड़ते हैं।

ये लेयर्स हैं, विकल्प नहीं। Cgroups मुख्य रूप से अकाउंटिंग और रिसोर्स डिनायल ऑफ सर्विस को संबोधित करते हैं; वे एक कंटेनर को दूसरे के डेटा को पढ़ने से नहीं रोकते हैं। नेमस्पेस मुख्य रूप से विचारों (views) को अलग करते हैं; वे साझा कर्नेल को पैच नहीं करते हैं। शत्रुतापूर्ण किरायेदारों के लिए, कर्नेल-शोषण जोखिम या अनुपालन एक VM, microVM, या सैंडबॉक्स्ड-कर्नेल सीमा को सही ठहरा सकता है।

चरण 5: दोनों पक्षों से कर्नेल स्थिति को सत्यापित करें

होस्ट से, पहले कंटेनर की init प्रक्रिया और cgroup पाथ की पहचान करें। एक सामान्य निरीक्षण रूपरेखा है:

bash
pid=<host-pid-of-container-init>
cg=/sys/fs/cgroup/<container-cgroup>

readlink /proc/$pid/ns/{pid,mnt,net,uts,ipc,user,cgroup}
cat /proc/$pid/uid_map
cat /proc/$pid/gid_map
cat /proc/$pid/cgroup

cat "$cg/memory.current" "$cg/memory.max" "$cg/memory.events"
cat "$cg/cpu.max" "$cg/cpu.stat"
cat "$cg/pids.current" "$cg/pids.max" "$cg/pids.events"

grep -E '^(CapPrm|CapEff|CapBnd|NoNewPrivs|Seccomp):' /proc/$pid/status

होस्ट और किसी अन्य कंटेनर के साथ नेमस्पेस सिम्लिंक डिवाइस/इनोड पहचान की तुलना करें। विभिन्न पहचान विभिन्न नेमस्पेस इंस्टेंसेस को साबित करती हैं; वे अकेले सुरक्षित माउंट, रूट या नीति साबित नहीं करते हैं। वास्तविक माउंट टेबल और प्रोपेगेशन, नेटवर्क लिंक और रूट, प्रभावी कैपेबिलिटी सेट, seccomp मोड, LSM लेबल और डिवाइस नोड्स का निरीक्षण करें।

कंटेनर के अंदर, /proc/1/status, /proc/self/cgroup, mount, hostname, दृश्यमान प्रक्रियाएं, इंटरफ़ेस, रूट, UID/GID, और नेमस्पेस लिंक रिकॉर्ड करें। केवल डायग्नोसिस के लिए अधिकृत होस्ट से nsenter का उपयोग करें; नेमस्पेस में प्रवेश करना विशेषाधिकार प्राप्त पहुँच है, यह इस बात का प्रमाण नहीं है कि सीमा विफल हो गई।

अंत में, डिस्पोजेबल परिवेश में सीमित विफलता परीक्षण चलाएं। मेमोरी को धीरे-धीरे आवंटित करें और memory.events के साथ विफलता को सहसंबद्ध करें; CPU कार्य चलाएं और लेटेंसी को nr_throttled के साथ सहसंबद्ध करें; थ्रेड्स या प्रक्रियाएं तब तक बनाएं जब तक कि अगला निर्माण EAGAIN न लौटाए और pids.events न बढ़ जाए। होस्ट-स्तरीय दबाव से पहले परीक्षण रोकें, और सत्यापित करें कि सिबलिंग cgroups स्वस्थ रहें।

चरण 6: अवलोकनों को स्वीकृति मानदंडों में बदलें

एक स्वीकार्य रिकॉर्ड में मान, पहचान और परिणाम शामिल होते हैं:

  • नेमस्पेस ID भिन्न होते हैं जहाँ आइसोलेशन आवश्यक होता है और केवल वहीं मेल खाते हैं जहाँ साझाकरण जानबूझकर किया गया हो;
  • UID 0 मैपिंग, प्रभावी कैपेबिलिटीज़, NoNewPrivs, seccomp मोड, और LSM लेबल थ्रेट मॉडल से मेल खाते हैं;
  • माउंट प्रोपेगेशन, बाइंड माउंट, मास्क्ड पाथ, राइटेबल पाथ, और डिवाइस एक्सेस OCI कॉन्फ़िगरेशन से मेल खाते हैं;
  • प्रभावी cgroup पर memory.max, cpu.max, और pids.max क्रमशः 536870912, 50000 100000, और 128 के बराबर हैं;
  • मेमोरी दबाव प्रासंगिक मेमोरी इवेंट काउंटरों को बदलता है, CPU लोड टास्क को मारे बिना थ्रॉटलिंग काउंटरों को बढ़ाता है, और 129वां टास्क निर्माण तब अस्वीकार कर दिया जाता है जब 128 टास्क पहले से चार्ज होते हैं;
  • प्रत्येक परीक्षण के दौरान पैरेंट और सिबलिंग cgroups अपने स्वयं के बजट के भीतर रहते हैं;
  • पुनरारंभ और जबरन-विफलता परीक्षण कोई अप्रत्याशित माउंट, इंटरफ़ेस, नेमस्पेस पिन, या पॉप्युलेटेड cgroups नहीं छोड़ते हैं।

129वें-टास्क का कथन इस शर्त पर निर्भर है कि प्रभावी पदानुक्रम में ठीक 128 टास्क पहले से ही चार्ज हैं और कोई समवर्ती निकास (concurrent exit) नहीं हुआ है। वास्तविक परीक्षण में, यह मानने के बजाय कि एप्लिकेशन में एक टास्क है, निर्माण से ठीक पहले pids.current पढ़ें।

उत्कृष्ट नमूना उत्तर

"मैं होस्ट-प्रोसेस मॉडल से शुरुआत करूँगा। रनटाइम एक OCI rootfs और कॉन्फ़िगरेशन लेता है, अनुरोधित PID, माउंट, नेटवर्क, UTS, IPC, यूज़र, cgroup, और टाइम नेमस्पेस बनाता है या उनसे जुड़ता है, माउंट और नेटवर्किंग को कॉन्फ़िगर करता है, प्रोसेस ट्री को cgroup से जोड़ता है, क्रेडेंशियल और सुरक्षा नीति लागू करता है, और एप्लिकेशन को execs करता है। अंदर PID 1 अभी भी बाहर एक अन्य PID के साथ एक होस्ट प्रक्रिया है। कंटेनर का एक प्राइवेट यूज़रस्पेस व्यू होता है, जबकि होस्ट कर्नेल साझा रहता है।

नेमस्पेस और cgroups अलग-अलग समस्याओं का समाधान करते हैं। PID नेमस्पेस प्रक्रिया दृश्यता को बदलता है; माउंट नेमस्पेस प्लस rootfs दृश्यमान फ़ाइलसिस्टम को बदलता है; नेटवर्क नेमस्पेस अपने स्वयं के इंटरफ़ेस, रूट, पोर्ट और सॉकेट प्रदान करता है। यूज़र नेमस्पेस आंतरिक UID 0 को एक अनप्रिविलेज्ड होस्ट UID पर मैप कर सकते हैं। Cgroups प्रोसेस ट्री का हिसाब रखते हैं और नियंत्रित करते हैं लेकिन होस्ट ऑब्जेक्ट्स को नहीं छिपाते हैं।

बताए गए cgroup v2 मानों के लिए, memory.max=536870912 एक 512 MiB हार्ड सीमा है। कर्नेल रिक्लेम की कोशिश करता है, फिर यदि उपयोग कम नहीं किया जा सकता है तो cgroup OOM हैंडलिंग को लागू कर सकता है; मैं max, oom, और oom_kill में अंतर करने के लिए memory.events पढ़ूँगा। cpu.max=50000 100000 निष्पक्ष-वर्ग के काम के लिए प्रति 100 ms में अधिकतम 50 ms की आपूर्ति करता है। एक बार कोटा उपयोग हो जाने के बाद, चलने योग्य टास्क तब तक थ्रॉटल किए जाते हैं जब तक कि अधिक कोटा उपलब्ध न हो, और cpu.stat nr_throttled और throttled_usec की रिपोर्ट करता है; कोई CPU-लिमिट किल नहीं है। pids.max=128 थ्रेड्स सहित कर्नेल टास्क की गणना करता है। उल्लंघन करने वाला fork या clone EAGAIN लौटाता है, और pids.events हिट को रिकॉर्ड करता है।

चूँकि कर्नेल साझा है, मैं जहाँ उपयुक्त हो यूज़र नेमस्पेस, एक न्यूनतम कैपेबिलिटी सेट, no_new_privs, seccomp, एक AppArmor या SELinux नीति, रीड-ओनली या मास्क्ड माउंट और एक न्यूनतम डिवाइस सेट की परत लगाऊंगा। मैं प्रिविलेज्ड मोड, होस्ट नेमस्पेस, व्यापक होस्ट माउंट, या इंजन-सॉकेट एक्सेस को तब तक अस्वीकार करूँगा जब तक कि प्रत्येक एक स्पष्ट विश्वसनीय आवश्यकता न हो। शत्रुतापूर्ण मल्टी-टेनेंसी के लिए एक VM या microVM सीमा की आवश्यकता हो सकती है।

सत्यापित करने के लिए, मैं होस्ट और कंटेनर से /proc/{PID}/ns/* डिवाइस/इनोड पहचान, UID/GID मैप, माउंट, इंटरफ़ेस, cgroup पाथ, प्रभावी नियंत्रक फ़ाइलें, कैपेबिलिटीज़, seccomp मोड और LSM लेबल की तुलना करूँगा। फिर मैं सीमित मेमोरी, CPU और टास्क परीक्षण चलाऊँगा और मिलान वाले कर्नेल काउंटरों और विफलता मोड की आवश्यकता होगी। एक कंटेनर जो केवल शुरू होता है उसने आइसोलेशन साबित नहीं किया है।"

सामान्य गलतियाँ और सुधार

  • कंटेनर को एक छोटा VM कहना → यह साझा कर्नेल को छुपाता है और गलत सुरक्षा धारणाएं पैदा करता है → नेमस्पेस, cgroup, फ़ाइलसिस्टम, क्रेडेंशियल और नीति स्थिति के साथ होस्ट प्रक्रियाओं का वर्णन करें।
  • यह कहना कि नेमस्पेस CPU और मेमोरी को सीमित करते हैं → नेमस्पेस विचारों को अलग करते हैं, खपत को नहीं → संसाधन सीमाओं को cgroup नियंत्रकों और फ़ाइलों से मैप करें।
  • यह कहना कि cgroups फ़ाइलों और प्रक्रियाओं को अलग करते हैं → cgroups टास्क को समूहीकृत, हिसाब और बाधित करते हैं → दृश्यता को PID और माउंट नेमस्पेस से मैप करें।
  • chroot को एक कंटेनर मानना → स्पष्ट रूट को बदलने से PID, नेटवर्क, यूज़र या संसाधन आइसोलेशन नहीं जुड़ता है → माउंट और अन्य आवश्यक नेमस्पेस प्लस नीति के साथ एक rootfs को संयोजित करें।
  • यह दावा करना कि CPU सीमा प्रक्रिया को मार देती है → CPU कोटा सामान्य रूप से चलने योग्य निष्पक्ष-वर्ग कार्य को थ्रॉटल करता है → थ्रॉटलिंग के लिए cpu.stat की जाँच करें।
  • मेमोरी उपयोग के ठीक 512 MiB पर रुकने की उम्मीद करना → रिक्लेम, अकाउंटिंग का समय, और अस्थायी अधिकता त्वरित रीडिंग को जटिल बनाते हैं → लागू परिणाम स्थापित करने के लिए memory.max और इवेंट काउंटरों का उपयोग करें।
  • pids.max के विरुद्ध केवल प्रक्रियाओं की गणना करना → नियंत्रक कर्नेल टास्क की गणना करता है, इसलिए थ्रेड्स इसका उपभोग करते हैं → सीमा परीक्षण से पहले pids.current का निरीक्षण करें।
  • यह मान लेना कि अंदर का रूट हानिरहित है → यूज़र नेमस्पेस के बिना यह अभी भी होस्ट UID 0 हो सकता है, जो केवल अन्य नियंत्रणों द्वारा विवश होता है → uid_map और कैपेबिलिटीज़ का निरीक्षण करें।
  • नेमस्पेस पृथक्करण को एक सुरक्षित टेनेंट सीमा के बराबर मानना → एक कर्नेल भेद्यता या खतरनाक होस्ट माउंट प्रक्रिया सीमा को पार कर सकता है → थ्रेट मॉडल बताएं और नीति या VM सीमा जोड़ें।
  • कॉन्फ़िगरेशन की जाँच करना लेकिन प्रभावी स्थिति की नहीं → रनटाइम फ़्लैग को ओवरराइड किया जा सकता है, इनहेरिट किया जा सकता है, या आंशिक रूप से विफल हो सकता है → /proc और cgroup फ़ाइलें पढ़ें, फिर प्रत्येक सीमा का परीक्षण करें।

फॉलो-अप प्रश्न

फॉलो-अप 1: कंटेनर के अंदर PID 1 को विशेष उपचार की आवश्यकता क्यों है?

PID नेमस्पेस में पहली प्रक्रिया उसके वंशजों को PID 1 के रूप में दिखाई देती है। यह अनाथ बच्चों (orphaned children) को अपनाती है और उन्हें रीप (reap) करना चाहिए, अन्यथा जॉम्बीज़ जमा हो जाते हैं और pids बजट का उपभोग करते हैं। PID 1 में विशेष सिग्नल-हैंडलिंग सिमेंटिक्स भी होते हैं, इसलिए एक रैपर जो सिग्नल अग्रेषित नहीं करता है, वह सुंदर समाप्ति (graceful termination) को विफल कर सकता है। वास्तविक init प्रक्रिया, चाइल्ड रीपिंग, सिग्नल फ़ॉरवर्डिंग और शटडाउन समय सीमा को सत्यापित करें, न कि यह मान लें कि एप्लिकेशन फ्रेमवर्क उन्हें संभालता है।

फॉलो-अप 2: cpu.max और cpu.weight में क्या अंतर है?

cpu.max निष्पक्ष-वर्ग के काम के लिए प्रति अवधि अधिकतम बैंडविड्थ सेट करता है। यह एक cgroup को थ्रॉटल कर सकता है, भले ही उस समूह द्वारा अपना वर्तमान कोटा समाप्त करने के बाद होस्ट के पास खाली CPU हो। cpu.weight कंटेंशन के दौरान चलने योग्य सिबलिंग cgroups के बीच एक आनुपातिक प्राथमिकता है और यह अपने आप में एक हार्ड 0.5-CPU सीमा को परिभाषित नहीं करता है। एक प्रोडक्शन नीति विभिन्न लक्ष्यों के लिए दोनों का उपयोग कर सकती है।

फॉलो-अप 3: क्या कंटेनर रूट होस्ट पर अनप्रिविलेज्ड हो सकता है?

हाँ, जब एक यूज़र नेमस्पेस अंदर UID 0 को बाहर एक अनप्रिविलेज्ड UID रेंज में मैप करता है। /proc/{PID}/uid_map और /proc/{PID}/gid_map में मैपिंग की पुष्टि करें। यह होस्ट विशेषाधिकार को सीमित करता है, लेकिन बाइंड-माउंट स्वामित्व, अधीनस्थ-ID आवंटन, स्वामित्व वाले यूज़र नेमस्पेस में कैपेबिलिटीज़ और कर्नेल अटैक सर्फ़ेस की अभी भी समीक्षा की आवश्यकता होती है।

फॉलो-अप 4: फ़ाइलसिस्टम सुरक्षा के लिए एक प्राइवेट माउंट नेमस्पेस अपर्याप्त क्यों है?

यह माउंट टेबल को अलग करता है, लेकिन रनटाइम यह तय करता है कि कौन से बैकिंग फ़ाइलसिस्टम और बाइंड माउंट वहां दिखाई देंगे। / के राइटेबल बाइंड माउंट वाला एक प्राइवेट नेमस्पेस अभी भी होस्ट रूट को उजागर करता है। माउंट स्रोतों, प्रोपेगेशन, राइटेबल फ़्लैग, मास्क्ड और रीड-ओनली पाथ, डिवाइस नोड्स, और प्रक्रिया के क्रेडेंशियल और LSM नीति की एक साथ समीक्षा करें।

फॉलो-अप 5: आपको VM या MicroVM को कब प्राथमिकता देनी चाहिए?

जब पारस्परिक रूप से गैर-भरोसेमंद किरायेदार मनमाना कोड निष्पादित करते हैं, साझा-कर्नेल एस्केप स्वीकृत जोखिम से बाहर होता है, अनुपालन के लिए अलग कर्नेल की आवश्यकता होती है, या कर्नेल संस्करण और मॉड्यूल भिन्न होने चाहिए, तो एक मजबूत सीमा को प्राथमिकता दें। इसकी लागत अतिरिक्त स्टार्टअप, मेमोरी, इमेज और संचालन ओवरहेड है। यह निर्णय थ्रेट मॉडल और मापे गए प्लेटफ़ॉर्म बाधाओं का पालन करता है, न कि केवल कंटेनर या VM लेबल का।

फॉलो-अप 6: आप ऐसे कंटेनर का निदान कैसे करेंगे जो धीमा है लेकिन OOM-Killed नहीं है?

एप्लिकेशन लेटेंसी को cpu.stat थ्रॉटलिंग, memory.events हाई/मैक्स प्रेशर, प्रेशर-स्टाल जानकारी, I/O नियंत्रक आँकड़े, होस्ट शेड्यूलिंग और नेटवर्क त्रुटियों के साथ सहसंबद्ध करें। स्थिर OOM काउंटरों के साथ बढ़ता हुआ nr_throttled या throttled_usec CPU कोटा की ओर इशारा करता है। रिक्लेम या I/O दबाव भी बिना किल के काम को रोक सकता है, इसलिए निदान के लिए संरेखित टाइमस्टैम्प और प्रभावी cgroup वंशावली की आवश्यकता होती है।

सार्वजनिक स्रोत

संबंधित प्रश्न