Как запустить cgexec без sudo от имени текущего пользователя в Ubuntu 22.04 с cgroups v2, с ошибкой «сбой смены группы cgroup»?

Я пробовал процедуры из:

но они не работают в 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получаем ошибку. В этом примере закройте терминал, который был добавлен в группу на предыдущем шаге.

Другие вопросы по тегам