понедельник, 18 июня 2012 г.

Ограничение ресурсов jail в FreeBSD (память, процессор, жесткий диск)

При использовании нескольких jail вам может понадобиться ограничить доступные им ресурсы, к примеру, при оказании услуг VDS-хостинга.

Ранее не было встроенных механизмов ограничения доступных частоты процессора и оперативной памяти. В версии FreeBSD версии 9.0 появился механизм управления ресурсами RCTL (Hierarchical Resource Limits). Эта система позволяет ограничивать ресурсы как отдельным пользователям и процессам, так и целым jail.

По умолчанию, rctl не работает. Протестировать это можно командой:

/usr/bin/rctl ; echo $?

Результатом будет:

rctl: rctl_get_rules: Function not implemented
1

Для работы rctl требуется перекомпилировать ядро с определенными опциями:

options RACCT
options RCTL

После того, как система начнет работать с модифицированным ядром будет запущен демон racctd. Та же команда будет выводить результат 0, что будет означать, что функция работоспособна.

Для управления правилами используется утилита rctl. Когда она выполняется без опций, то результатом будет вывод текущих правил на стандартный выход. Существуют следующие параметры команды rctl:
-a rule - Добавляет правило в базу данных RCTL.
-l filter - Отображает правила применяемые к процессу, подпадающему под фильтр.
-r filter - Удаляет правила подпадающие под фильтры из базы данных RCTL.
-u filter - Отображает ресурсы используемые объектом (процесс, пользователь, класс логинов или jail) подпадающим под фильтр.
-h - "человекопонятный" вывод.  Использует суффиксы: Byte, Kilobyte, Megabyte, Gigabyte, Terabyte and Petabyte.
-n - Отображать ID пользователей численно, а не конвертировать их в имена пользователей.

Синтаксис правил.

Правила записываются строками вида  subject:subject-id:resource:action=amount/per.

subject определяет тип объекта к которому применяется правило. Это может быть процесс, пользователь, login class или jail.

subject-id определяет объект. Это может быть имя пользователя, числовой ID пользователя, имя login class или имя jail.

resource определяет ресурс, которым управляет данное правило.

action определяет что произойдет когда процесс превысит лимит (amount).

amount определяет сколько ресурсов процесс может использовать прежде чем сработает указанное действие (action).

Поле per определяет что к какому объекту применяется указанный лимит (amount). К примеру, правило "loginclass:users:vmem:deny=100M/process" означает, что каждый процесс любого пользователя, входящего в класс логинов "users", может использовать до 100 мегабайт виртуальной памяти. Правило "loginclass:users:vmem:deny=100M/user" будет значить, что для каждого пользователя, входящего в класс логинов "users", сумма виртуальной памяти используемой всеми процессами данного пользователя не будет превышать 100 мегабайт. Правило  "loginclass:users:vmem:deny=100M/loginclass" будет значить, что сумма виртуальной памяти используемой всеми процессами всех пользователей, входящих в класс логинов "users", не будет превышать 100 мегабайт.

Валидное правило обязательно должно иметь значения всех этих полей, кроме per, которое, по умолчанию, имеет значение равное объекту (subject).

Фильтр - это правило, в котором одно или несколько полей оставлено пустым (кроме per). Например, фильтр, который удовлетворяет всем правилам должен быть записан как  ":::=/" или, короче, ":". Фильтр, который удовлетворяем всем классам логинов, должен быть записан как "loginclass:". Фильтры, который соответствует всем правилам для ресурса nproc будет выглядеть как "::nproc".

Виды ресурсов (resource):

cputime                  процессорное время в секундах
datasize                 размер данных, в байтах
stacksize               размер стэка, в байтах
coredumpsize        размер core dump, в байтах
memoryuse           количество используемой памяти, в байтах
memorylocked      заблокированная память, в байтах
maxproc                количество процессов
openfiles               размер таблицы описаний файлов
vmemoryuse         ограничение адресного пространства, в байтах
pseudoterminals   количество терминалов
swapuse                использование подкачки, в байтах
nthr                       количество потоков
msgqqueued         количество сообщений SysV в очереди
msgqsize              размер очереди сообщений SysV, в байтах
nmsgq                  количество очередей сообщений SysV
nsem                    количество семафоров SysV
nsemop                кол-во семафоров SysV измененных в одном вызове semop(2)
nshm                    количество  сегментов разделенной (shared) памяти SysV
shmsize                размер разделенной памяти SysV, в байтах
wallclock              время wallclock, в секундах

Виды действий (action):

deny - отказать в выделении ресурса, не поддерживается для cputime (то есть, нет возможности ограничить ресурсы процессора, можно только залогировать их) и wallclock
log - вывести лог на консоль
devctl - отправить предупреждение в devd (демон, который позволяет запускать программы, когда происходят определенные события ядра)
sig* - отправить сигнал соответствующему процессу, к примеру SIGTERM.

Примеры сигналов:

SIGTERM - сигнал остановки программы, может быть обработан или проигнорирован.
SIGKILL - убить программу, вызывает немедленное её завершение.
SIGSTOP - приостановить процесс, работу которого позже можно будет восстановить сигналом SIGCONT.

Примеры использования утилиты rctl:

rctl -a user:joe:vmemoryuse:deny=1g - запрещает пользователю joe использовать больше 1 ГБ виртуальной памяти

rctl -r: - удаляет все правила

rctl -hu jail:www - показывает информацию об использовании ресурсов jail с именем www. Так должно быть, но выяснилось, что преобразование имен jail в id не работает, поэтому нужно с помощью команды jls узнать id jail и писать, к примеру, rctl -hu jail:1

rctl -l process:512 - показывает все правила, применяемые к процессу с PID 512.

Примеры ограничения ресурсов jail:

rctl -a jail:1:memoryuse:deny=1g - запрещает jail с id 1 использовать более 1 гигабайта памяти.

rctl -a jail:1:cputime:log=1 - при использовании jail с id 1 более чем одной секунды процессорного времени в логе /var/log/messages появится соответствующая запись:

Jun  4 17:43:00 gate kernel: rctl: rule "jail:1:cputime:log=1" matched by pid 2406 (cron), uid 0, jail 1

Если необходимо применять правила автоматически после перезагрузки системы, то их необходимо сохранить в файле /etc/rctl.conf, который прочитывается при переходе в многопользовательский режим. В файле можно оставлять комментарии, предваряя их символом #.

К сожалению, в FreeBSD 9.0 нет возможности резделить ресурсы процессора между несколькими jail в процентном соотношении.

Ограничения на использование процессора.

К сожалению, не удалось найти адекватных средств для ограничения максимально доступной нагрузки на процессор для jail. Единственное, что нашлось - это утилита cpuset, которая позволяет назначить определенные процессоры или ядра для использования конкретной jail. К примеру:

cpuset -l 0,2 -j 3

Данная команда заставляет jail с id 3 использовать первый и третий процессоры.

Ограничение на использование жёсткого диска.

Опять же, не удалось найти адекватный способ ограничения использования жесткого диска тюрьмами. Всё, что удалось найти - это создание виртуального жесткого диска заданного объема. Такой диск можно примонтировать в директорию и уже туда установить jail.

Cоздаем файл состоящий из 4 миллионов блоков (count) по 1 килобайту (bs) и забитый нулевыми байтами. Итого, 4 гигабайта. Для изменения количества гигабайт, достаточно поменять параметр count.

dd if=/dev/zero of=jail.file bs=1k count=4m

Проверяем создался ли файл и его размер:

ls -lh jail.file

Результат:

-rw-r--r--  1 root  wheel   4.0G Jun 13 00:15 jail.file

В систему подключается виртуальный диск из указанного файла:

mdconfig -a -t vnode -f jail.file

Результат:

md0

На устройстве md0 создается файловая система UFS с включенными мягкими обновлениями:

newfs -U /dev/md0

Результат:

/dev/md0: 4096.0MB (8388608 sectors) block size 32768, fragment size 4096
        using 6 cylinder groups of 740.00MB, 23680 blks, 47360 inodes.
        with soft updates
super-block backups (for fsck -b #) at:
 192, 1515712, 3031232, 4546752, 6062272, 7577792

Монтируем диск в директорию /mnt (либо любую другую, в которой располагаются диски ваших jail):

mount /dev/md0 /mnt

Готово. Теперь в данную директорию можно установить jail и её размер будет ограничен размером созданного файла.

Смотрите также остальные статьи про jail:

Создание и настройка jail окружения в FeeBSD

Настройка и управление jail в FreeBSD.

Ezjail - легкое управление клетками в FreeBSD

0 коммент.:

Отправить комментарий