Как запустить cgexec без sudo от имени текущего пользователя в Ubuntu 22.04 с cgroups v2, с ошибкой «сбой смены группы cgroup»?
Я пробовал процедуры из:
- Ошибка Cgroups: не удалось изменить группу cgroup
- Как использовать cgroup в Ubuntu 13.04
- https://unix.stackexchange.com/questions/197718/does-managing-cgroups-require-root-access
но они не работают в Ubuntu 22.04, предположительно из-за обновления cgroups v2:
sudo cgcreate -a $USER:$USER -g memory:myGroup -t $USER:$USER
sudo cgset -r memory.max=500M myGroup
sudo cgset -r memory.swap.max=0 myGroup
cgexec -g memory:myGroup id
терпит неудачу с:
cgroup change of group failed
Это работает, если я бегу с
sudo
sudo cgexec -g memory:myGroup id
но тогда команда работает как
root
, и я хочу, чтобы вместо этого он работал от имени текущего пользователя.
3 ответа
Я прочитал документацию по ядру Linux и нашел следующее (выделено мной):
cgroup.procs
Файл значений, разделенных новой строкой для чтения и записи, который существует во всех контрольных группах.
...
PID может быть записан для переноса процесса, связанного с PID, в cgroup. Писатель должен соответствовать всем следующим условиям.
- У него должен быть доступ на запись к файлу «cgroup.procs».
- У него должен быть доступ на запись к файлу «cgroup.procs» общего предка исходной и целевой контрольных групп.
...
В этом случае общий предок/
. Так что я делаюcgroup.procs
корневой группы, доступной для записи:
sudo chmod o+w /sys/fs/cgroup/cgroup.procs
И теперь я могу использоватьcgexec
как любой пользователь без полномочий root. Не зная, есть ли какие-либо последствия для безопасности.
Чтобы решить эту проблему, вам нужно загрузить хост-систему в режиме CGroupV1, изменив аргументы загрузки вашего ядра, включив в них:
systemd.unified_cgroup_hierarchy=false
sudo nano /etc/default/grub
GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1 systemd.unified_cgroup_hierarchy=false"
sudo update-grub
sudo reboot
Раньше я запускал несколько ресурсоемких инструментов сcgexec
в контрольных группах v1. Я не уверен, что это поддерживается в cgroups v2; по крайней мере, я не мог заставить его работать.
После слишком большого количества времени, потраченного на изучение этого, мне удалось добиться успеха в Ubuntu 22.04 + cgroups v2.
1. Создайте контрольную группу и (в моем случае) настройте разрешения
$ cd /sys/fs/cgroup/
$ sudo mkdir europe create
$ ls -ld europe
drwxr-x--- 2 root root 0 out 28 22:50 europe
$ sudo chmod a+rx europe
$ ls -ld europe
drwxr-xr-x 2 root root 0 out 28 22:50 europe
Без изменения разрешений со мной происходят две вещи: я не могу использовать cat внутри группы без sudo иsystemd-cgtop --depth 1
возвращаетсяFailed to refresh: Permission denied
.
2. Ограничьте ЦП до 3 ядер и ОЗУ до 16 ГБ.
У меня было несколько доступных контроллеров (cgroup.controllers
), но единственные, которые передавались вниз по поддереву, былиmemory
иpids
поэтому я добавил недостающееcpu
контроллер.
$ cat cgroup.controllers // all available
cpuset cpu io memory hugetlb pids rdma misc
$ cat cgroup.subtree_control // for subgroups
memory pids
$ sudo bash -c 'echo '+cpu' > cgroup.subtree_control'
$ cat cgroup.subtree_control // now includes CPU
cpu memory pids
$ cat europe/cgroup.controllers // can confirm in subgrp
cpu memory pids
Теперь ограничьте CPU и RAM:
$ cat europe/memory.max
max
$ cat europe/cpu.max
max 100000
$ echo '16G' | sudo tee europe/memory.max
16G
$ echo '300000 100000' | sudo tee europe/cpu.max
300000 100000
$ cat europe/memory.max
17179869184
$ cat europe/cpu.max
300000 100000
3. Запустите что-нибудь
Мы можем добавить PID, которые затем будут выполняться в группе.europe
.
Вместо того, чтобы запускать процесс и затем добавлять его PID, я добавляю PID окна терминала. Тогда все, что запускается в этой оболочке, будет выполняться в группе.
Откройте другой терминал:
$ cat /sys/fs/cgroup/europe/cgroup.procs
$ echo $$ | sudo tee /sys/fs/cgroup/europe/cgroup.procs
25982
$ cat europe/cgroup.procs
25982
26104
$ cat europe/cgroup.procs
25982
26105
$ cat europe/cgroup.procs
25982
26106
Первый PID относится к терминалу (соответствуетecho $$
в bash), а второй PID — это командаcat
вот почему каждый раз, когда я запускал команду, второй PID был другим.
4. Удалить группу, когда она не нужна
$ cat /sys/fs/cgroup/europe/cgroup.procs
$ sudo rmdir /sys/fs/cgroup/europe
Если есть еще процессы вeurope/cgroup.procs
получаем ошибку. В этом примере закройте терминал, который был добавлен в группу на предыдущем шаге.