Як створити групи користувачів з systemd


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запустить контейнер у непривілейованому режимі лише тоді, коли він зможе створити необхідні групи в /sys/fs/cgroup/XXX/*. Однак це неможливо, lxcоскільки systemdвстановлюється rootієрархія групи /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(через . scriptThe .важливо, щоб це працювало!), Це те, що я не просто відкриваю новий сеанс для userале додайте поточну оболонку як процес, який запускається в цій новій групі. Я можу досягти такого ж ефекту, запустивши скрипт в підрозділі, а потім спуститися в cgroupієрархію в chb subcgroupі використовуватиecho $$ > tasksщоб додати поточну оболонку до кожного учасника chb cgroup hierarchy.

Отже, коли я запускаю lxcв цю поточну оболонку, мій контейнер також стане членом усіх chb subcgroups, членами яких shellє поточний . Тобто моє containerуспадковує cgroupстатус мого shell. Це також пояснює, чому вона не працює в будь-якій іншій оболонці, яка не є частиною поточного chb subcgroups.

Я все ще проходжу на 2.. Напевно, нам доведеться чекати або systemdоновлення, або подальших Kernelрозробок, щоб systemdприйняти послідовну поведінку, але я все одно віддаю перевагу ручній настройці, оскільки це змушує вас зрозуміти, що ви робите.


ви можете не просто змонтувати рейтинг груп десь ще (чесне запитання) ? Було багато суперечок щодо linux-груп і systemd минулого року, коли сервіс-супровідник, очевидно, вирішив надати systemd по імені та іншим аналогічним неназваним програмам повноваження щодо роботи з групами в просторі користувачів. не впевнений, як все вийшло, але я знаю, що це було досить в повітрі, чи може користувач це зробити взагалі рік тому.
mikeserv

Я, мабуть, міг би це зробити, але мені довелося б не допустити, щоб systemd монтував кореневий каталог cgroup в першу чергу. Щоразу, коли я ввійду на свою машину, systemd змонтує ієрархію коренів кореневої групи під / sys / fs / cgroup та додає cgroup користувача лише під системною частиною кореневої cgroup (Ви можете побачити це вище). Різниця між системними дистрибутивами і не системними дистрибутивами перед їх переключенням полягає в тому, що, наприклад, у керуванні групою Ubuntu не в руках демона init.
lord.garbage

Він замість цього обробляється програмою, наприклад cgmanager. Або ви можете це зробити вручну, як пропонується у посиланні на kernel.org, яке я розмістив вище. Наразі я не маю достатньо глибокого розуміння системного управління групами, щоб би мовити з ним глибше, ніж зараз. Але, сподіваємось, це незабаром зміниться.
lord.garbage

1
Правда, я пам’ятаю, як ти заявив, що у коментарі до відповіді я дав давно. Я
розпитую

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. Останню команду потрібно запустити в поточній оболонці, щоб додати її до нової групи для $USER.
lord.garbage

0

Насправді в archlinux це не працюватиме, наприклад, з непривілейованим користувачем (рекомендується використовувати контейнери unpriv. Lxc). тобто у цього користувача немає sudo :)

Замість цього визначте групу в /etc/cgconfig.conf, активуйте cgconfig, cgrules (libcgroup в AUR), додайте також cgrules, виконано .. unpriv. користувач також матиме однакові права.

У systemd 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 може залежати від того, скільки ядер у вас є, mem можна встановити на деяке фактичне значення тощо, тощо.

EDIT 2: Нарешті, у systemd, якщо ви хочете скористатись автозапуском із таким непривілейованим користувачем, ви можете:

cp /usr/lib/systemd/system/lxc{,admin}\@.service, а потім додайте User = lxcadmin

і ввімкніть його для контейнера lxcadmin, який називається lolz systemctl, увімкніть lxcadmin @ lolz.


Дякую @Anthon, я ніколи не можу отримати форматування коду прямо на цих веб-сайтах, x
Маліна Саліна,

Дякую. Вибачте за пізню відповідь. Ваш перший пункт, "Насправді в archlinux це не працюватиме, наприклад, з непривілейованим користувачем (рекомендується використовувати контейнери unpriv. Lxc). Тобто, у користувача немає sudo :)", не стоїть так, як вам потрібен лише ваш rootадміністратор, щоб створити і chownви у всіх cgroupконтролерах. Це ідеально добре і безпечно. movepidможе бути зроблено без rootправ і, отже, непрів. користувачеві не потрібні ніякі sudoправа. (Btw, libcgroupбільше не слід вживати. RHEL та інші
знецінили

@Brauner. Як ви автоматично запускаєтесь під час завантаження, контейнери вашого непривілейованого користувача? Насправді у ваших перелічених рішеннях працював лише (і мається на увазі) користувач sudo. Мій не став. Ви запитали, як це виправити. У будь-якому випадку, щойно відбулося оновлення, і cgconfig зараз не запускається, оскільки user.slices додаються автоматично, перед налаштуваннями cgconfig, здається. У них відсутні будь-які дозволи користувачів (можливо, регресивна помилка, я зараз переглядаю це). Я не сказав, що це найкраще рішення. Це / рішення вашого запиту. :) Але зараз мої контейнери не запускаються, grrr.
Маліна Саліна

Причина, що я перерахував systemctl enable lxcadmin @ контейнер, так що root міг вирішити запустити unpriv контейнер під час завантаження. Якщо користувач сам використовує його в --user (land), він завантажиться лише тоді, коли він увійде в систему, не дуже корисно для сервера. І примітка до вашого коментаря. Я вважаю, що використання користувача у всіх контролерах дозволяє користувачеві почати переміщення під-файлу в простір хоста, я вважаю, що це досить загроза безпеці.
Маліна Саліна

Ем, це, здавалося б, ви робили зі своїм методом, спочатку перерахованим, мабуть, але подивіться на це, навіть якщо це системний пакет ubuntu bugs.launchpad.net/ubuntu/+source/systemd/+bug/1413927 Але щось було оновлено в минулі дні змінювали логіку .. Я намагаюся її відстежити.
Маліна Саліна

0

Тому я зіткнувся з тією ж проблемою, коли намагався отримати непривітні контейнери LXC, що працюють на CentOS 7. Я не хотів користуватися, cgmanagerтому що мені не подобається вводити будь-які додаткові сервіси, якщо це зовсім не потрібно. Натомість я замість цього робив патч systemd, використовуючи кілька патчів із пакету ubuntu та один спеціальний патч для розширення списку контролерів груп. У мене є джерела, необхідні для створення RPM на моєму акаунті GitHub за адресою https://github.com/CtrlC-Root/rpmdist . У мене також є виправлені версії тіньових утиліт (для субуїдів і субгідок) і пам (для loginuid). Після того, як я встановлю ці RPM і налаштую користувача на запуск непривілейованих контейнерів (призначення присвоєних і субгідок, виділення пар veth в lxc-usernet, створення .config / lxc / default.conf тощо), я можу запустити непривілейовані контейнери LXC просто чудово.

EDIT: Ще одна причина, по якій я не хотів використовувати cgmanager, це тому, що я не хотів, щоб мої постійні користувачі взагалі мали використовувати sudo. Постійні користувачі повинні мати можливість увійти, і все повинно "просто працювати" поза коробкою.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.