Systemd के साथ उपयोगकर्ता cgroups कैसे बनाएँ


14

मैं अनपेक्षित lxcकंटेनरों का उपयोग करता हूं Arch Linux। यहाँ बुनियादी सिस्टम इन्फोस हैं:

[chb@conventiont ~]$ uname -a
Linux conventiont 3.17.4-Chb #1 SMP PREEMPT Fri Nov 28 12:39:54 UTC 2014 x86_64 GNU/Linux

यह एक कस्टम / संकलित कर्नेल है user namespace enabled:

[chb@conventiont ~]$ lxc-checkconfig 
--- Namespaces ---
Namespaces: enabled
Utsname namespace: enabled
Ipc namespace: enabled
Pid namespace: enabled
User namespace: enabled
Network namespace: enabled
Multiple /dev/pts instances: enabled

--- Control groups ---
Cgroup: enabled
Cgroup clone_children flag: enabled
Cgroup device: enabled
Cgroup sched: enabled
Cgroup cpu account: enabled
Cgroup memory controller: enabled
Cgroup cpuset: enabled

--- Misc ---
Veth pair device: enabled
Macvlan: enabled
Vlan: enabled
File capabilities: enabled

Note : Before booting a new kernel, you can check its configuration
usage : CONFIG=/path/to/config /usr/bin/lxc-checkconfig

[chb@conventiont ~]$ systemctl --version
systemd 217
+PAM -AUDIT -SELINUX -IMA -APPARMOR +SMACK -SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID -ELFUTILS +KMOD +IDN 

दुर्भाग्य से, वर्तमान में systemdअच्छा नहीं खेलता है lxc। विशेष रूप से cgroupsएक गैर-रूट उपयोगकर्ता के लिए स्थापित करना अच्छा नहीं लग रहा है या मैं अभी भी अपरिचित हूं कि यह कैसे करना है। lxcकेवल unprivileged मोड में एक कंटेनर शुरू करेगा जब यह आवश्यक cgroups बना सकता है /sys/fs/cgroup/XXX/*। हालाँकि यह संभव नहीं है lxcक्योंकि systemdइसमें rootcgroup पदानुक्रम की गणना होती है /sys/fs/cgroup/*। निम्नलिखित के लिए एक वर्कअराउंड लगता है:

for d in /sys/fs/cgroup/*; do
        f=$(basename $d)
        echo "looking at $f"
        if [ "$f" = "cpuset" ]; then
                echo 1 | sudo tee -a $d/cgroup.clone_children;
        elif [ "$f" = "memory" ]; then
                echo 1 | sudo tee -a $d/memory.use_hierarchy;
        fi
        sudo mkdir -p $d/$USER
        sudo chown -R $USER $d/$USER
        echo $$ > $d/$USER/tasks
done

यह कोड एक अनपेक्षित उपयोगकर्ता के लिए पदानुक्रम cgroupमें संबंधित निर्देशिका बनाता है cgroup। हालाँकि, जो कुछ मुझे समझ में नहीं आता है। पूर्वोक्त निष्पादित करने से पहले मैं इसे देखूंगा:

[chb@conventiont ~]$ cat /proc/self/cgroup 
8:blkio:/
7:net_cls:/
6:freezer:/
5:devices:/
4:memory:/
3:cpu,cpuacct:/
2:cpuset:/
1:name=systemd:/user.slice/user-1000.slice/session-c1.scope

उपरोक्त कोड को निष्पादित करने के बाद, मैं उस शेल में देखता हूं जिसे मैंने इसमें चलाया था:

[chb@conventiont ~]$ cat /proc/self/cgroup 
8:blkio:/chb
7:net_cls:/chb
6:freezer:/chb
5:devices:/chb
4:memory:/chb
3:cpu,cpuacct:/chb
2:cpuset:/chb
1:name=systemd:/chb

लेकिन किसी भी अन्य खोल में मैं अभी भी देखता हूं:

[chb@conventiont ~]$ cat /proc/self/cgroup 
8:blkio:/
7:net_cls:/
6:freezer:/
5:devices:/
4:memory:/
3:cpu,cpuacct:/
2:cpuset:/
1:name=systemd:/user.slice/user-1000.slice/session-c1.scope

इसलिए, मैं अपने अनपेक्षित lxcकंटेनर को शेल में शुरू कर सकता हूं मैंने ऊपर उल्लिखित कोड निष्पादित किया है लेकिन किसी अन्य में नहीं।

  1. क्या कोई इस व्यवहार की व्याख्या कर सकता है?

  2. क्या किसी cgroupsको systemd( >= 217) के वर्तमान संस्करण के साथ आवश्यक सेट करने का एक बेहतर तरीका मिल गया है ?

जवाबों:


13

एक बेहतर और सुरक्षित समाधान यह है कि cgmanagerइसे systemctl start cgmanager(ऑन- systemdडिस्टर्ड डिस्ट्रो) के साथ इंस्टॉल और रन किया जाए । आपके पास आपका rootउपयोगकर्ता हो सकता है, या यदि आपके पास सभी नियंत्रकों में अपने अप्रकाशित उपयोगकर्ता के लिए sudoहोस्ट बनाने के अधिकार हैं cgroups:

sudo cgm create all $USER
sudo cgm chown all $USER $(id -u $USER) $(id -g $USER)

एक बार जब वे आपके अनपेक्षित उपयोगकर्ता के लिए बना दिए जाते हैं, तो वह उन प्रक्रियाओं को स्थानांतरित कर सकता है, जिनका उपयोग करके वह cgroupप्रत्येक नियंत्रक के लिए उसकी पहुँच प्राप्त कर सकता है:

cgm movepid all $USER $PPID

सुरक्षित, तेज, शेल स्क्रिप्ट की तुलना में अधिक विश्वसनीय जो मैंने पोस्ट किया है।

मैनुअल समाधान:

उत्तर देने के लिए 1।

for d in /sys/fs/cgroup/*; do
        f=$(basename $d)
        echo "looking at $f"
        if [ "$f" = "cpuset" ]; then
                echo 1 | sudo tee -a $d/cgroup.clone_children;
        elif [ "$f" = "memory" ]; then
                echo 1 | sudo tee -a $d/memory.use_hierarchy;
        fi
        sudo mkdir -p $d/$USER
        sudo chown -R $USER $d/$USER
        echo $$ > $d/$USER/tasks
done

मैं क्या वास्तव में जब मुझे लगता है कि पटकथा लिखी हो रहा है, लेकिन पढ़ रहा था के बारे में अनभिज्ञ था इस और प्रयोग एक सा मुझे समझने की क्या हो रहा है में मदद की। मैं मूल रूप से इस स्क्रिप्ट में जो कर रहा हूं cgroupवह वर्तमान के लिए एक नया सत्र बनाने के लिए है userजो कि मैंने पहले ही ऊपर कहा है। जब मैं वर्तमान में इन आदेशों को चलाने के shellतो या उन्हें एक लिपि में चलाने के लिए और यह है कि यह वर्तमान में मूल्यांकन किया जाता है shellऔर एक में नहीं subshell(के माध्यम से काम करने के लिए इस के लिए महत्वपूर्ण है!) है कि मैं ही नहीं, के लिए एक नया सत्र खोलने है लेकिन वर्तमान शेल को इस नई cgroup में चलने वाली प्रक्रिया के रूप में जोड़ें। मैं एक उपधारा में स्क्रिप्ट को चलाकर उसी प्रभाव को प्राप्त कर सकता हूं और फिर अंदर और उपयोग में पदानुक्रम में उतर सकता हूं. script.usercgroupchb subcgroupecho $$ > tasksके हर सदस्य के लिए वर्तमान शेल जोड़ने के लिए chb cgroup hierarchy

इसलिए, जब मैं lxcउस चालू शेल में दौड़ता हूं तो मेरा कंटेनर भी उन सभी chb subcgroupएस का सदस्य बन जाएगा , जो वर्तमान shellका सदस्य है। कहने का containerतात्पर्य यह है कि मुझे अपनी cgroupस्थिति विरासत में मिली है shell। यह भी बताता है कि यह किसी अन्य शेल में काम क्यों नहीं करता है जो वर्तमान chb subcgroupएस का हिस्सा नहीं है ।

मैं अभी भी गुजरता हूं 2.। संभवतः एक सुसंगत व्यवहार को अपनाने के लिए हमें या तो systemdअपडेट या आगे के Kernelघटनाक्रम की प्रतीक्षा करनी होगी, systemdलेकिन मैं मैन्युअल सेटअप को वैसे भी पसंद करता हूं क्योंकि यह आपको यह समझने के लिए मजबूर करता है कि आप क्या कर रहे हैं।


क्या आप सिर्फ कहीं और (ईमानदार सवाल) cgroups माउंट नहीं कर सकते ? पिछले साल लिनक्स cgroups और systemd पर विवाद का एक अच्छा सौदा था जब cgroups अनुचर ने जाहिरा तौर पर userpace में cgroups से अधिक अन्य नामांकित एप्लिकेशन प्राधिकरण को नाम और अन्य समान अनाम सिस्टम द्वारा देने का निर्णय लिया । यह निश्चित नहीं है कि यह सब कैसे निकला, लेकिन मुझे पता है कि यह हवा में बहुत ऊपर था कि क्या एक उपयोगकर्ता एक साल पहले ऐसा कर सकता है।
15-15 को 15

मैं शायद ऐसा कर सकता था, लेकिन मुझे सिस्टमग्रुप को पहली जगह में cgroup रूट डायरेक्टरी को बढ़ने से रोकना होगा। जब भी मैं अपने मशीन सिस्टम में लॉगिन करता हूं, रूट cgroup रूट पदानुक्रम को / sys / fs / cgroup के नीचे माउंट करेगा और केवल रूट cgroup के सिस्टम भाग के तहत एक उपयोगकर्ता cgroup जोड़ता है (आप इसे ऊपर देख सकते हैं।) स्विच करने से पहले सिस्टमड आधारित डिस्ट्रोस और न कि सिस्टमड आधारित डिस्ट्रोस के बीच का अंतर यह है कि उदाहरण के लिए उबंटू cgroup प्रबंधन इनिट डेमॉन के हाथों में नहीं है।
lord.garbage

इसके बजाय जैसे cgmanager जैसे प्रोग्राम को हैंडल किया जाता है। या आप इसे कर्नेल के लिंक में सुझाए गए अनुसार हाथ से कर सकते हैं। मैंने ऊपर पोस्ट किया है। मैं वर्तमान में इसे समझने के लिए सिस्टेम cgroup प्रबंधन की गहरी पर्याप्त समझ नहीं रखता। लेकिन उम्मीद है कि यह जल्द ही बदल जाएगा।
lord.garbage

1
यह सच है, मुझे याद है कि आपने एक उत्तर के लिए एक टिप्पणी में कहा था कि मैंने बहुत समय पहले दिया था। मैं पूछताछ करूँगा ...
lord.garbage

1
मूल रूप से चाल है sudo systemctl start cgmanager && sudo cgm create all $USER && sudo cgm chown all $USER $(id -u) $(id -g) && sudo cgm movepid all $USER $PPID:। अंतिम कमांड को वर्तमान शेल में चलाने की जरूरत है ताकि इसे नए cgroup में जोड़ा जा सके $USER
lord.garbage

0

वास्तव में आर्चलिनक्स में, यह एक अप्रकाशित उपयोगकर्ता के साथ काम नहीं करेगा (अनुशंसित नहीं है। unpriv। Lxc कंटेनरों का उपयोग करते समय)। यानी उपयोगकर्ता के पास sudo नहीं है :)

इसके बजाय, /etc/cgconfig.conf में समूह को परिभाषित करें, cgconfig, cgrules (AUR में libcgroup) को सक्रिय करें, साथ ही साथ cgrules जोड़ें। उपयोगकर्ता के पास भी समान अधिकार होंगे।

सिस्टमड 218 में (मुझे नहीं पता कि कब, लेकिन लगता है कि किसी को दो और शर्तों को जोड़ना होगा क्योंकि वे cgconfig तरीके से निर्मित होने पर सेट नहीं होते हैं):

cat /etc/cgconfig.conf

group lxcadmin {
perm {
    task {
        uid = lxcadmin;
        gid = lxcadmin;
    }
    admin {
        uid = lxcadmin;
        gid = lxcadmin;
    }
}
cpu { }
memory { memory.use_hierarchy = 1; }  
blkio { }
cpuacct { }
cpuset { 
    cgroup.clone_children = 1;
    cpuset.mems = 0;
    cpuset.cpus = 0-3; 
}
devices { }
freezer { }
hugetlb { }
net_cls { }
}

cat /etc/cgrules.conf
lxcadmin        *       lxcadmin/

नाम मान लेना कर्नेल में संकलित है।

यह एक टेम्पलेट है, cpus आपके पास कितने कोर के अनुसार हो सकता है, मेम को कुछ वास्तविक मूल्य, आदि के लिए सेट किया जा सकता है।

EDIT 2: अंत में, systemd में, क्या आपको ऐसे अनपेक्षित उपयोगकर्ता के साथ ऑटो-स्टार्ट का उपयोग करना चाहिए, आप यह कर सकते हैं:

cp /usr/lib/systemd/system/lxc.pe,admin Ideal\@@service, फिर उपयोगकर्ता जोड़ें = lxcadmin

और इसे lxcadmin के कंटेनर के लिए सक्षम करें जिसे lolz systemctl कहा जाता है lxcadmin @ lolz सक्षम करें।


धन्यवाद @Anthon, मैं कभी भी इन वेबसाइटों में कोड फॉर्मेटिंग सही नहीं पा सकता, x
मालिना सलीना

धन्यवाद। देर से उत्तर के लिए क्षमा करें। आपका पहला बिंदु, "वास्तव में आर्च्लिनक्स में, यह उदासीन उपयोगकर्ता के साथ काम नहीं करेगा (अनुशंसित नहीं है। unpriv। Lxc कंटेनरों का उपयोग करते समय)। यानी उस उपयोगकर्ता के पास sudo :) नहीं है" क्योंकि आप केवल अपने rootव्यवस्थापक की आवश्यकता नहीं रखते हैं। बनाएँ और chownआप सभी cgroupनियंत्रकों में। यह पूरी तरह से ठीक और सुरक्षित है। अधिकारों के movepidबिना किया जा सकता है rootऔर इसलिए, अयोग्य। उपयोगकर्ता को किसी भी sudoअधिकार की आवश्यकता नहीं है। (Btw, libcgroupअब इसका इस्तेमाल नहीं किया जाना चाहिए। RHEL और अन्य लोगों ने इसे हटा दिया है।)
lord.garbage

@Brauner। आप बूट पर ऑटोस्टार्ट कैसे करते हैं, आपके अनप्लग किए गए उपयोगकर्ता के कंटेनर तब? वास्तव में सूचीबद्ध आपके समाधान केवल एक sudo उपयोगकर्ता के काम (और निहित) हैं। मेरा नहीं हुआ। आपने पूछा कि इसे कैसे ठीक किया जाए। वैसे भी, बस एक अद्यतन किया गया है, और cgconfig अब शुरू करने में विफल रहता है, क्योंकि user.slices स्वचालित रूप से जोड़े जाते हैं, cgconfig सेटिंग्स के आगे यह लगता है। ये किसी भी उपयोगकर्ता अनुमतियों (संभवतः एक प्रतिगमन बग, अब इसे देख रहे हैं) का अभाव है। मैंने यह नहीं कहा कि यह सबसे अच्छा समाधान था। यह आपकी जांच का एक समाधान था । :) लेकिन मेरे कंटेनर अब बूट पर शुरू नहीं हो रहे हैं, जीआरआर।
मलिना सलीना

मेरे द्वारा व्यवस्थित lctadmin @ कन्टेनर को सूचीबद्ध करने का कारण यह था कि रूट बूट पर एक अयोग्य कंटेनर चलाने का निर्णय ले सके। यदि उपयोगकर्ता खुद इसे --user (भूमि) में उपयोग करता है, तो यह तभी बूट होगा जब वह लॉग इन करेगा, सर्वर के लिए बहुत उपयोगी नहीं होगा। और आपकी टिप्पणी पर ध्यान दें। किसी उपयोगकर्ता को सभी नियंत्रकों में धोखा देना, उस उपयोगकर्ता को होस्ट के स्थान में पिड की चाल शुरू करने की अनुमति देता है, मेरा मानना ​​है कि यह एक सुरक्षा जोखिम है।
मलिना सलीना

एर्म, ऐसा प्रतीत होता है कि आप अपनी पद्धति के साथ शुरुआत में सूचीबद्ध थे जो मुझे लगता है कि सूचीबद्ध है, लेकिन इसे देखें, भले ही यह ubuntu systemd package बगs.launchpad.net/ubuntu/+source/systemd/+bug/14830927 पर अपडेट किया गया था, लेकिन इसमें कुछ अपडेट किया गया था पिछले दिनों तर्क बदलते हुए .. मैं इसे ट्रैक करने की कोशिश कर रहा हूं।
मालिना सलीना

0

इसलिए मैं उसी समस्या में भाग गया जब LXC अप्रकाशित कंटेनरों को CentOS 7 पर काम करने की कोशिश कर रहा था। 7. मैं इस्तेमाल नहीं करना चाहता था cgmanager क्योंकि मुझे कोई अतिरिक्त सेवा शुरू करना पसंद नहीं है अगर बिल्कुल आवश्यक नहीं है। मैंने इसके बजाय ubuntu पैकेज और कुछ कस्टम पैच से cgroup नियंत्रकों की सूची का विस्तार करने के लिए कुछ पैच का उपयोग करके सिस्टमिंग पैचिंग कर रहा है। मेरे पास https://github.com/CtrlC-Root/rpmdist पर अपने GitHub खाते पर RPM बनाने के लिए आवश्यक स्रोत हैं । मेरे पास छाया-बर्तनों के संस्करण (सबुइड्स और सबगिड्स के लिए) और पीएएम (लॉगग्यूइड के लिए) भी हैं। के बाद मैं इन RPM को स्थापित करने और unpriviliged कंटेनरों को चलाने के लिए एक उपयोगकर्ता को कॉन्फ़िगर करता हूं (subuids & subgids असाइन करें), lxc-usernet में veth जोड़े आवंटित करें, .config / lxc / default.conf, आदि बनाएं। मैं LXC unprivileged कंटेनरों को बस ठीक से चला सकता हूं।

संपादित करें: एक और कारण जो मैं cgmanager का उपयोग नहीं करना चाहता था क्योंकि मैं नहीं चाहता कि मेरे नियमित उपयोगकर्ता को sudo का उपयोग करना पड़े। नियमित उपयोगकर्ताओं को लॉग इन करने में सक्षम होना चाहिए और सब कुछ बॉक्स से "बस काम" करना चाहिए।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.