Як використовувати групи для обмеження всіх процесів, крім білого списку, до одного процесора?


26

Є посібник з груп з Red Hat, який, можливо, є корисним (але не дає відповіді на це запитання).

Я знаю, як обмежити певний процес певним процесором під час команди запуску цього процесу:

По-перше, введення наступного * в /etc/cgconfig.conf:

mount {
  cpuset =  /cgroup/cpuset;
  cpu =     /cgroup/cpu;
  cpuacct = /cgroup/cpuacct;
  memory =  /cgroup/memory;
  devices = /cgroup/devices;
  freezer = /cgroup/freezer;
  net_cls = /cgroup/net_cls;
  blkio =   /cgroup/blkio;
}

group cpu0only {
  cpuset {
    cpuset.cpus = 0;
    cpuset.mems = 0;
  }
}

А потім запустіть процес і призначте його конкретно цій групі, використовуючи:

cgexec -g cpuset:cpu0only myprocessname

Я можу обмежувати всі випадки конкретного імені процесу автоматично, (я вважаю, що це правильно), вводячи наступне /etc/cgrules.conf:

# user:process  controller  destination
*:myprocessname cpuset      cpu0only

Моє запитання: Як я можу зробити зворотний шлях ?

Іншими словами, як я можу призначити всі процеси, за винятком конкретного набору білих процесів та їхніх дітей, до групи обмежених груп?


Виходячи з того, що я вивчив, але не перевірив, я вважаю, що часткове рішення буде таким:

Додайте групу "без обмежень":

group anycpu {
  cpuset {
    cpuset.cpus = 0-31;
    cpuset.mems = 0;  # Not sure about this param but it seems to be required
  }
}

Призначте мій процес явно групі без обмежень, а все інше - групі з обмеженням:

# user:process  controller  destination
*:myprocessname cpuset      anycpu
*               cpuset      cpu0only

Однак застереження щодо цього, мабуть, є (від читання документів, а не від тестування, тому зерна солі), що дітям myprocessnameбуде переведено на обмежену cpu0onlyгрупу.

Можливим альтернативним підходом було б створення користувача для запуску myprocessnameта обмеження всіх процесів цього користувача , а все інше обмежене. Однак у моєму фактичному випадку використання процес повинен запускатися під корінь, і є й інші процеси, які також повинні запускатися під корінь, які слід обмежувати.

Як я можу це досягти за допомогою груп?


Якщо це неможливо з груповими групами (на що я зараз підозрюю, що так), чи правильні мої ідеї щодо часткових рішень і чи будуть вони працювати так, як я думаю?

* Відмова: Це, мабуть, не мінімальний приклад коду; я не розумію всіх частин, тому не знаю, які не потрібні.

Відповіді:


30

ОНОВЛЕННЯ: Зауважте, що відповідь нижче стосується RHEL 6. У RHEL 7 більшість груп керується systemd, а libcgroup - застарілою.


Після публікації цього питання я вивчив цілий посібник, з яким я посилався вище, а також більшість документації cgroups.txt та cpusets.txt . Зараз я знаю більше, ніж я коли-небудь очікував дізнатися про групи, тому я відповім на власне запитання тут.

Можна скористатися декількома підходами. Контакт нашої компанії з Red Hat (Технічний архітектор) рекомендував не обмежувати всіх процесів, віддаючи перевагу більш декларативному підходу - обмежуючи лише ті процеси, які ми спеціально хотіли. Причина цього, згідно з його твердженнями з цього приводу, полягає в тому, що можливі системні виклики залежати від кодового простору користувача (наприклад, LVM-процесів), який при обмеженні може уповільнити систему - протилежний наміченому ефекту. Тож я врешті-решт обмежив кілька конкретно названих процесів, а все інше залишив у спокої.

Додатково хочу зазначити деякі основні дані групи, які мені не вистачало, коли я розміщував запитання.


Групи не залежать від libcgroupвстановлення. Однак, це набір інструментів для автоматичної обробки конфігурації групи та присвоєння процесів групам і може бути дуже корисним.

Я виявив, що інструменти libcgroup також можуть вводити в оману, тому що пакет libcgroup побудований на власному наборі абстракцій та припущень щодо використання вами груп, які дещо відрізняються від фактичної реалізації ядра рівня груп. (Я можу навести приклади, але це потребує певної роботи; прокоментуйте, якщо вам це цікаво.)

Тому перед використанням 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. Не існує такого поняття, як "деякі процеси в групі, а деякі - ні".

Існує те, що називається кореневою групою для даної ієрархії, яка володіє всіма ресурсами системи для доданих підсистем. Наприклад, ієрархія групових груп, у якій додані підсистеми cpuset і blkio, матиме кореневу cgroup, яка б володіла всім процесором у системі та всім blkio в системі, і могла б поділитися деякими з цих ресурсів з дочірніми групами. Ви не можете обмежувати кореневу групу, оскільки вона володіє всіма ресурсами вашої системи, тому обмежувати це навіть не має сенсу.


Ще деякі прості дані, які мені не вистачало про libcgroup:

Якщо ви користуєтесь /etc/cgconfig.conf, ви повинні переконатися, що chkconfig --list cgconfigпоказує, що cgconfigвстановлено для запуску під час завантаження системи.

Якщо ви змінилися /etc/cgconfig.conf, вам потрібно запустити, service cgconfig restartщоб завантажити зміни. (І проблеми з зупинкою служби або запуском cgclearдуже часто зустрічаються при дурному тестуванні. Для налагодження я рекомендую, наприклад lsof /cgroup/cpuset, якщо cpusetє ім'я ієрархії групи, яку ви використовуєте.)

Якщо ви хочете скористатися /etc/cgrules.conf, вам потрібно переконатися, що "движок демона з правилами групи" ( cgrulesengd) працює:: service cgred startі chkconfig cgred on. (І ви повинні знати про можливий, але малоймовірний стан перегонів щодо цієї послуги, як описано в Посібнику з управління ресурсами Red Hat у розділі 2.8.1 внизу сторінки.)

Якщо ви хочете обдурити вручну і налаштувати свої групи за допомогою віртуальної файлової системи (яку я рекомендую для першого використання), ви можете зробити це, а потім створити cgconfig.confфайл, який відображає налаштування, використовуючи cgsnapshotйого різні параметри.


І нарешті, ключовий фрагмент інформації, який мені не вистачало, коли я писав таке:

Однак застереження щодо цього ... здається, що діти мого імені будуть перепризначені для обмеженої групи cpu0only.

Я мав рацію, але є варіант, про який я не знав.

cgexec це команда для запуску процесу / запуску команди та присвоєння її групі.

cgclassify це команда призначити вже запущений процес групі.

І те й інше заважатиме cgred( cgrulesengd) перерозподіляти зазначений процес іншій групі на основі /etc/cgrules.conf.

Обидва cgexecі cgclassifyпідтримують --stickyпрапор, що додатково не дозволяє cgredперерозподілити дочірні процеси на основі /etc/cgrules.conf.


Отже, відповідь на запитання, яке я написав (хоча це не інсталяція, яку я закінчив реалізовувати, через поради нашого технічного архітектора Red Hat):

Складіть cpu0onlyі anycpuгрупи, як описано в моєму запитанні. (Переконайтеся cgconfig, що для завантаження встановлено.)

Складіть * cpuset cpu0onlyправило, як описано в моєму запитанні. (І переконайтеся cgred, що налаштування запускається під час завантаження.)

Запустіть всі процеси , я хочу необмежені з: cgexec -g cpuset:anycpu --sticky myprocessname.

Ці процеси будуть необмеженими, і всі їхні дочірні процеси також будуть необмеженими. Все інше в системі буде обмежено CPU 0 (після перезавантаження, оскільки cgredне застосовує crurule до вже запущених процесів, якщо вони не змінять свій EUID). Це не цілком доцільно, але це було те, що я спочатку просив, і це можна зробити з групами.


Ого. круто. як це було 0 голосів?
mikeserv

@mikeserv, спасибі :) Відповідь на ваше запитання: перевірити дати; Я щойно написав цю відповідь вчора.
Wildcard

1
я побачив, що. але це було 24 години тому. ймовірно, причина його довга. хороший матеріал іноді може так не помітити. і в будь-якому випадку, відповіді з великою кількістю голосів дійсно незабаром є дуже рідко хорошими - інформація не може бути такою корисною, якщо стільки людей вже знають, що це. це одна з хороших. групи таємничі.
mikeserv
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.