ОБНОВЛЕНИЕ: Обратите внимание, что приведенный ниже ответ относится к RHEL 6. В RHEL 7 большинство cgroups управляется systemd, а libcgroup устарела.
После публикации этого вопроса я изучил все руководство, на которое я ссылался выше, а также большую часть документации cgroups.txt и cpusets.txt . Теперь я знаю больше, чем когда-либо ожидал узнать о cgroups, поэтому я отвечу на свой вопрос здесь.
Есть несколько подходов, которые вы можете использовать. Контакт нашей компании в Red Hat (Технический Архитектор) рекомендовал не ограничивать все процессы, а отдавать предпочтение более декларативному подходу - ограничивать только те процессы, которые мы специально хотели ограничить. Причина этого, согласно его высказываниям на эту тему, заключается в том, что системные вызовы могут зависеть от кода пользовательского пространства (такого как процессы LVM), который в случае ограничения может замедлить работу системы - противоположность предполагаемому эффекту. В итоге я ограничил несколько специально названных процессов и оставил все остальное в покое.
Кроме того, я хочу упомянуть некоторые основные данные cgroup, которые мне не хватало, когда я публиковал свой вопрос.
Группы не зависят от libcgroup
установки. Однако это набор инструментов для автоматической обработки конфигурации cgroup и назначения процессов для cgroups, и он может быть очень полезным.
Я обнаружил, что инструменты libcgroup также могут вводить в заблуждение, поскольку пакет libcgroup построен на собственном наборе абстракций и предположений об использовании cgroups, которые немного отличаются от фактической реализации cgroups на уровне ядра. (Я могу привести примеры, но это займет немного работы; прокомментируйте, если вам интересно.)
Поэтому перед использованием libcgroup инструментов (таких , как /etc/cgconfig.conf
, /etc/cgrules.conf
, cgexec
, cgcreate
, cgclassify
и т.д.) , я настоятельно рекомендую получить хорошо знакомы с /cgroup
самой виртуальной файловой системы, а также создание контрольных групп, контрольной группы иерархии (включая иерархии с несколькими подсистемами прикрепленными, которые libcgroup скрытно и leakily аннотаций вручную далеко), переназначение процессов различным группам путем запуска echo $the_pid > /cgroup/some_cgroup_hierarchy/a_cgroup_within_that_hierarchy/tasks
и другие, казалось бы, волшебные задачи, libcgroup
выполняемые под капотом.
Другой основной концепцией я пропускал в том , что если /cgroup
виртуальная файловая система установлена в вашей системе на всех (или более точно, если какой - либо из контрольной группы подсистем ака «контроллеры» смонтированы на всех), то каждый процесс по всей системе в а контрольная группа. Нет такой вещи, как «некоторые процессы находятся в cgroup, а некоторые нет».
Для данной иерархии существует то, что называется корневой группой , которая владеет всеми ресурсами системы для подключенных подсистем. Например, иерархия cgroup, к которой подключены подсистемы cpuset и blkio, будет иметь корневую cgroup, которая будет владеть всеми процессорами в системе и всеми blkio в системе, и может совместно использовать некоторые из этих ресурсов с дочерними cgroups. Вы не можете ограничить корневую группу, поскольку она владеет всеми ресурсами вашей системы, поэтому ограничивать ее даже не имеет смысла.
Некоторые другие простые данные, которые мне не хватало в libcgroup:
Если вы используете /etc/cgconfig.conf
, вы должны убедиться, что chkconfig --list cgconfig
показывает, что cgconfig
установлен для запуска при загрузке системы.
Если вы измените /etc/cgconfig.conf
, вам нужно запустить, service cgconfig restart
чтобы загрузить изменения. (А проблемы с остановкой или запуском службы cgclear
очень распространены, когда вы дурачитесь с тестированием. Для отладки я рекомендую, например lsof /cgroup/cpuset
, if cpuset
это имя используемой вами иерархии cgroup.)
Если вы хотите использовать /etc/cgrules.conf
, вы должны убедиться, что «демон механизма правил cgroup» ( cgrulesengd
) работает: service cgred start
и chkconfig cgred on
. (И вы должны знать о возможном, но маловероятном состоянии гонки в отношении этой службы, как описано в Руководстве по управлению ресурсами Red Hat в разделе 2.8.1 внизу страницы.)
Если вы хотите дурачиться вручную и настраивать свои cgroups, используя виртуальную файловую систему (которую я рекомендую для первого использования), вы можете сделать это, а затем создать cgconfig.conf
файл, который будет отражать ваши настройки, используя cgsnapshot
его различные параметры.
И, наконец, ключевая информация, которую мне не хватало, когда я писал следующее:
Однако предостережение об этом, похоже, заключается в том, что потомки myprocessname будут переназначены в ограниченную cpu0only cgroup.
Я был прав, но есть вариант, о котором я не знал.
cgexec
это команда для запуска процесса / запуска команды и назначения ее группе.
cgclassify
это команда для назначения уже запущенного процесса в cgroup.
Оба из них также будут препятствовать cgred
( cgrulesengd
) переназначению указанного процесса другой cgroup на основе /etc/cgrules.conf
.
Оба cgexec
и cgclassify
поддерживают --sticky
флаг, который дополнительно предотвращает cgred
переназначение дочерних процессов на основе /etc/cgrules.conf
.
Итак, ответ на вопрос в том виде, в котором он был написан мной (хотя это и не та установка, которую я в итоге реализовал из-за рекомендаций нашего Red Hat Technical Architect, упомянутых выше):
Сделайте cpu0only
и anycpu
cgroup, как описано в моем вопросе. (Убедитесь, cgconfig
что установлен для запуска при загрузке.)
Сделайте * cpuset cpu0only
правило, как описано в моем вопросе. (И убедитесь, cgred
что установлен для запуска при загрузке.)
Запустите все процессы , я хочу неограниченные с: cgexec -g cpuset:anycpu --sticky myprocessname
.
Эти процессы будут неограниченными, и все их дочерние процессы также будут неограниченными. Все остальное в системе будет ограничено CPU 0 (после перезагрузки, поскольку cgred
cgrules не применяется к уже запущенным процессам, если они не меняют свой EUID). Это не совсем рекомендуется, но это было то, что я изначально просил, и это можно сделать с помощью cgroups.