Wednesday, 5 February 2014

Настройка cgroup на Debian 7

По мотивам статьи: http://www.stableit.ru/2012/10/cgroup-centos-6.html

В отличие от CentOS у Debian 7 Wheezy фактически нет нормального мейнтенера подсистемы cgroups, поэтому обойтись установкой пары пакетов и правкой 1-2х конфигов не получится.

apt-get install -y cgroup-bin libcgroup1

Копируем примеры конфигов:

cp /usr/share/doc/cgroup-bin/examples/cgconfig.conf /etc/cgconfig.conf
cp /usr/share/doc/cgroup-bin/examples/cgconfig.sysconfig /etc/default/cgconfig
zcat /usr/share/doc/cgroup-bin/examples/cgconfig.gz > /etc/init.d/cgconfig
chmod +x /etc/init.d/cgconfig 

Создаем спец-папку (без нее поймаем ошибку "touch: cannot touch /var/lock/subsys/cgconfig: No such file or directory [FAIL] Failed to touch /var/lock/subsys/cgconfig ... failed!"):
mkdir -p /var/lock/subsys

Теперь добавляем cgroup для тестов, пусть это будет cpuacct, так как она не приводит к деградациям и ее можно использовать безвредно и на боевом ПО.

Добавляем в конфиг: /etc/cgconfig.conf следующие строки:
mount {
    cpuacct = /mnt/cgroups/cpuacct;
}
group wwwdata {
  cpuacct {
  }
}


Теперь попробуем стартануть его:
 /etc/init.d/cgconfig restart

Убеждаемся, что cgroup была корректно смонтирована:
cat /proc/mounts |grep cgroup
cgroup /mnt/cgroups/cpuacct cgroup rw,relatime,cpuacct 0 0

А сама папка выглядит примерно так:
ls -al /mnt/cgroups/cpuacct/
total 4.0K
drwxr-xr-x. 3 root root    0 Feb  5 14:04 .drwxr-xr-x. 3 root root 4.0K Feb  5 14:04 ..-rw-r--r--. 1 root root    0 Feb  5 14:04 cgroup.clone_children
--w--w--w-. 1 root root    0 Feb  5 14:04 cgroup.event_control
-rw-r--r--. 1 root root    0 Feb  5 14:04 cgroup.procs
-r--r--r--. 1 root root    0 Feb  5 14:04 cpuacct.stat
-rw-r--r--. 1 root root    0 Feb  5 14:04 cpuacct.usage
-r--r--r--. 1 root root    0 Feb  5 14:04 cpuacct.usage_percpu
-rw-r--r--. 1 root root    0 Feb  5 14:04 notify_on_release
-rw-r--r--. 1 root root    0 Feb  5 14:04 release_agent
-rw-r--r--. 1 root root    0 Feb  5 14:04 tasks
drwxr-xr-x. 2 root root    0 Feb  5 14:04 wwwdata

Теперь нам нужно добиться того, чтобы процессы конкретного пользователя загонялись в определенную cgroup.

Снова копируем конфиги:
cp /usr/share/doc/cgroup-bin/examples/cgrules.conf  /etc/cgrules.conf
cp /usr/share/doc/cgroup-bin/examples/cgred   /etc/init.d/cgred
cp /usr/share/doc/cgroup-bin/examples/cgred.conf /etc/default/cgred.conf
chmod +x  /etc/init.d/cgred

Далее правим баги мейнтейнеров Debian:
sed -i 's/sysconfig/default/' /etc/init.d/cgconfig

Потом добавялем туда (/etc/cgrules.conf) одну строчку в самый низ:
@www-data    cpuacct wwwdata/

Далее отключаем создание дефалт группы (в которую система будет помещать все процессы кроме тех, которые помещены в иные группы):

vim /etc/default/cgconfig
CREATE_DEFAULT=no

Таким образом мы настраиваем помещение всех процессов пользователя www-data в группу с именем wwwdata.

После этого несколько раз (потому что что-то в скриптах не то и с первого раза у него не выходит размонтировать cgroup) дергаем команду:
/etc/init.d/cgconfig stop

И потом запускаем:
/etc/init.d/cgconfig start

После этого настраиваем демона cgred, который, собственно, должен распихивать процессы по cgroup:
/etc/init.d/cgred start

Но нас постигнет ужасное разочарование - init скрипт тупо взят из RedHat без должной доработки под особенности Debian (впрочем, в  /etc/init.d/cgconfig примерное тоже самое - там вместо /etc/default используется путь /etc/sysconfig):

/etc/init.d/cgred: line 43: /etc/rc.d/init.d/functions: No such file or directory
Starting CGroup Rules Engine Daemon: /etc/init.d/cgred: line 85: daemon: command not found

Чтобы исправить это открываем /etc/init.d/cgred и комментируем 43ю строку с кодом: "/etc/rc.d/init.d/functions".

Потом ищем строку "daemon --check $servicename --pidfile $pidfile $CGRED_BIN $OPTIONS" и заменяем на:

start-stop-daemon --start --quiet --pidfile $pidfile --exec $CGRED_BIN -- $OPTIONS  

Далее правим:
sed -i 's/sysconfig/default/' /etc/init.d/cgred

Еще нужно исправить группу, от имени которой будет работать демон:

vim /etc/default/cgred.conf

и заменяем SOCKET_GROUP="cgred" на SOCKET_GROUP=""

Далее нам нужно создать папку для нашей cgroup:

mkdir /mnt/cgroups/cpuacct/wwwdata
Итак, запускаем демона:
/etc/init.d/cgred start

После этого нужно инициировать перезапуск процессов, которые нам интересно поместить в cgroup, в моем случае это nginx работающий от имени пользователя www-data:
/etc/init.d/nginx reload

Все, теперь убеждаемся, что процессы попали в нужную cgroup:
cat /mnt/cgroups/cpuacct/wwwdata/tasks
28623
28624
28625
28626

8 comments:

  1. Респект и уважуха за инструкцию!
    От себя добавлю, что в /etc/init.d/cgred исправил строку
    killproc -p $pidfile TERM "$processname"
    на
    killproc $pidfile SIGTERM "$processname"

    Ну update-rc.d еще прогнал, чтобы при запуске всё работало.

    ReplyDelete
    Replies
    1. Вам спасибо, что интересуетесь таким крутым механизмом как cgroups :)

      Delete
    2. В какой-то мере нужда заставила разобраться. :)

      Delete
  2. какое содержимое файлов получилось в итоге? в первую очередь интересует /etc/init.d/cgconfig

    ReplyDelete
    Replies
    1. Боюсь, этого ничего не сохранилось, ибо было очень давно.

      Delete
  3. # /etc/init.d/cgconfig restart
    [....] Restarting cgconfig (via systemctl): cgconfig.serviceFailed to restart cgconfig.service: Unit cgconfig.service failed to load: No such file or directory.
    failed!

    ReplyDelete
    Replies
    1. Привет! получилось решить эту проблему?

      Delete
    2. пока решается только перезагрузкой, ибо системд занимает папку маунттмпфс_cgroup/systemd. по логам видно что cgconfig не может стартонутьь изза занятого директория. маунт показывает наличие указанной занятости. как освободить пока не разбирался

      Delete

Note: only a member of this blog may post a comment.