Контрольні групи в Linux

В сучасних серверах стандартної архітектури, побудованих на базі багатоядерних процесорів, число логічних процесорів можна порівняти з числом процесорів великих Unix-серверів недавнього минулого. У зв'язку з тим, що популярна для серверів стандартної архітектури ОС Linux ефективно працює також і на багатопроцесорних системах із загальною пам'яттю суперкомп'ютерного рівня, природно, що розвинені засоби управління ресурсами - cgroups (соntrol groups, контрольні групи) - з'явилися і в стандартних ядрах Linux ( починаючи з 2.6.24). Сучасні версії ядер і відповідні дистрибутиви Linux за замовчуванням включають в свої конфігурації підтримку cgroups - не стала винятком і версія ОС OpenSuSE 12.1 c ядром 3.1.0, на прикладі якої покажемо особливості роботи з контрольними групами.

Контрольна група - це безліч завдань (task), що характеризуються певним набором параметрів підсистем. До контрольних груп належать не тільки початково приписані до них завдання, але і всі їх «нащадки». Застосування контрольних груп дозволяє управляти розподілом різних ресурсів, доступних ОС, між групами процесів. Підсистема - засіб надання завданням деякого сервісу. Типовою підсистемою є контролер будь-яких ресурсів (процесор, пам'ять і т. Д.), Але підсистема може надавати, наприклад, послуги з ізоляції процесів в просторі імен. Взаємодія контрольних груп з підсистемами здійснюється шляхом установки параметрів, що настроюються підсистем для кожної контрольної групи.

Подібно процесам, cgroups організовані ієрархічно, що відбивається деревом відповідних каталогів в файлової системі cgroup. Дочірні групи успадковують атрибути батьків. Ієрархія cgroups може асоціюватися з декількома або з усіма підсистемами, але може бути і так, що кожної підсистемі відповідає своя ієрархія. Якщо підсистема задіяна в управлінні будь-якої ієрархією (див. Малюнок), то вона не може застосовуватися в інших ієрархіях. Кожній ієрархії належить частина всіх завдань ОС. У цій ієрархії завдання може належати тільки одній контрольній групі, але одна і та ж завдання може бути представлена ​​в контрольній групі, керованій одним набором підсистем, і в інший контрольній групі з іншої ієрархії, керованої іншим набором підсистем.

У цій ієрархії завдання може належати тільки одній контрольній групі, але одна і та ж завдання може бути представлена ​​в контрольній групі, керованій одним набором підсистем, і в інший контрольній групі з іншої ієрархії, керованої іншим набором підсистем

Ілюстрація взаємозв'язку контрольних груп, підсистем і задач. Представлено дві ієрархії (А і B), сім підсистем (підсистема 6 не задіяна в cgroups) і чотири завдання

У стандартній версії ядра OpenSuSE 12.1 представлено дев'ять підсистем. Параметри підсистем, які керують контрольними групами, встановлюються шляхом запису значень цих параметрів до відповідних псевдофайла віртуальної файлової системи cgroup.

Підсистема cpuset дозволяє «прив'язати» завдання до певного набору логічних процесорів (це можуть бути ядра багатоядерних мікропроцесорів або логічні процесори в разі застосування технологій багатонитковою обробки, наприклад Intel HyperThreading). Можна не тільки вказати, на яких процесорах буде виконуватися завдання (файл cpuset.cpus), але і якими вузлами оперативної пам'яті вони можуть користуватися (файл cpuset.mems). В сучасних мікропроцесорах контролери пам'яті вбудовані, що призводить багатопроцесорні сервери до архітектури ccNUMA, коли є відмінність між локальною пам'яттю (вузлом), приєднаної безпосередньо до даного процесору, і віддаленій пам'яттю, приєднаної до інших процесорам.

Підсистеми cpu і cpuacct виконують дві головні функції: облік використання процесорного часу і обмеження частки процесорного часу, на яке може претендувати контрольна група (всі її завдання разом). Підсистема memory дозволяє обмежувати пам'ять, яку дозволяється використовувати завданням контрольних груп. Підсистема devices дозволяє системному адміністратору вказати список пристроїв, до яких матимуть доступ завдання контрольної групи. Підсистема blkio (блоковий введення / виведення) є контролером ресурсів дискового введення / виводу. З її допомогою можна сформулювати політику розподілу смуги пропускання введення / виведення, вказавши пропорційні ваги. Підсистема freezer орієнтована на застосування у високопродуктивних кластерах і призначена для зупинки ( «заморозки») всіх завдань в групі - наприклад, якщо вони досягли контрольної точки. Підсистема net_cls дозволяє приписувати ідентифікатори мережевим пакетам, що може застосовуватися для вказівки пріоритетів пакетам, використовуваним завданнями різних груп.

Нехай є університетський сервер, на якому виконуються завдання викладачів і студентів, а також системні завдання. Можна задати умову, щоб системні завдання задіяли до 20% процесорного часу, завдання викладачів - до 60%, а студентські - до 20%, причому якщо логічних процесорів багато, то можливо виділити кожній групі власні процесори. Можна ввести також обмеження на частку пам'яті: 20% системі, 50% викладачам і 30% студентам, а також розмежувати смугу пропускання дискових пристроїв: 20% системі, 50% викладачам і 30% студентам. Нарешті, можна розмежувати мережевий введення-виведення, віддавши 20% для виконання браузерів, 60% - мережевої файлової системи і 20% - на інші потреби. У свою чергу, можна розмежувати і мережевий трафік браузерів. Можна вважати системні завдання верхнім рівнем ієрархії cgroups - Cюда потрапляють всі завдання, які не запускаються викладачами або студентами. А на другому рівні ієрархії можна розташувати дві контрольні групи: для викладачів і студентів.

Якщо не брати до уваги завдання розмежування мережевого трафіку, то можна зробити так, щоб всі контрольні групи керувалися одним загальним набором підсистем, а можна створювати свою ієрархію контрольних груп для кожної підсистеми. В останньому випадку кожна задача на сервері буде потрапляти відразу в три різні контрольні групи - по одній в кожній ієрархії. У різних версіях ядер можуть бути, взагалі кажучи, реалізовані різні підсистеми. Наприклад, в стандартному ядрі дистрибутива OpenSuSE 12.1 не підтримуються засоби управління пропускною спроможністю мережевого вводу / виводу. У разі реалізації в ядрі можна було б створити три контрольні групи: для браузерів, NFS і інших процесів. При цьому контрольна група для браузерів складалася б з двох підгруп - для викладачів і студентів, і всі такі завдання потрапляли б виключно в одну з цих підгруп. Можна було б також створювати свої підгрупи для кожного типу браузерів.

Базові cредства cgroups реалізовані в ядрі, однак для зручності роботи адміністратора з управління ресурсами сервера є додаткові пакети, зокрема, забезпечують можливості управління cgroups більш високого рівня. У OpenSuSE ці кошти знаходяться в rpm-пакетах cpuset, libcgroup1, libcpuset1 і lxc. Всі ці пакети відсутні в стандартному дистрибутиві OpenSuSE 12.1 - їх треба встановити окремо, як і пакети libbitmask1 і libcap-progs, необхідні для libcpuset1 і lxc відповідно. Далі розглянемо тільки пакет libcgroup1, який безпосередньо пов'язаний з cgroups.

Якщо не застосовувати спеціальні утиліти, то для роботи з cgroups можна використовувати базові засоби Linux, змонтувавши віртуальну файлову систему tmpfs:

mount -t tmpfs name / куди / монтувати,

де name - мітка, з якої монтується tmpfs. Далі потрібно змонтувати віртуальну файлову систему типу cgroup, вказавши в параметрі -o команди mount список імен підсистем, які будуть приписані ієрархії контрольних груп:

mount -t cgroup -o спісок_імен_подсістем ім'я / куди / монтувати / ім'я,

де довільне ім'я задає назву ієрархії груп.

При створенні контрольної групи просто формуються відповідні підкаталоги, тому для створення підгруп у цій ієрархії можна скористатися звичайною командою mkdir. У разі OpenSuSE 12.1 для створення ієрархії cgroups досить просто виконати розпоряджається створення ієрархії mycgroup:

mkdir / sys / fs / cgroup / cpuset / mycgroup.

При виконанні mkdir в каталозі автоматично створюються псевдофайла, вміст яких використовується для установки значень параметрів підсистем. Строго кажучи, ієрархія починається з каталогу / куди / монтувати / ім'я, або конкретно в нашому випадку - з / sys / fs / cgroup / cpuset, оскільки там також є набір псевдофайла для параметрів. Імена псевдофайла мають вигляд імя.параметр_подсістеми, де ім'я задає підсистему, тому у різних підсистем імена псевдофайла завжди різняться. Для того щоб встановити конкретні параметри для контрольної групи, потрібно просто зробити запис в псевдофайла відповідного каталогу. Наприклад, послідовність типу:

cd / sys / fs / cgroup / cpuset / mycgroup

echo 2-3> cpuset.cpus

echo 1> cpuset.mems

дозволить цій групі використовувати тільки логічні процесори 2, 3 і вузол 1 оперативної пам'яті. Тепер для того щоб процес з ідентифікатором myPID був приписаний до даної контрольній групі, потрібно виконати echo myPID> tasks.

Для створення контрольної групи використовується команда

cgcreate -g імя_подсістеми: шлях.

Наприклад, сgcreate - g cpuset: mycgroup еквівалентна команді mkdir для створення контрольної групи mycgroup.

Команда сgclassify -g імя_подсістеми: шлях спісок_PID

дозволяє приписати існуючі процеси з ідентифікаторами зі списку PID (ідентифікатори в ньому розділяються пробілами) Відповідне контрольній групі (ці ідентифікатори прописуються в псевдофайла tasks). Для того щоб з самого початку виконувати команду (запускати завдання) в певних контрольних групах, застосовується

cgexec -g імя_подсістеми: шлях команда [аргументи].

Програми cgconfigparser і демон cgrulesengd (Cgroup Rules Engine Daemon) надають кошти для роботи з cgroups високого рівня. Перша забезпечує побудову і настройку ієрархій контрольних груп, а друга відповідає за визначення відповідно до заданих правил ідентифікаторів процесів, які будуть віднесені до потрібних контрольним групам. Утиліта сgconfigparser використовує конфігураційний файл /etc/cgconfig.conf, в якому визначаються контрольні групи, їх точки монтування та параметри підсистем, керуючих контрольною групою. Конфігураційний файл cgrules.conf демона cgrulesengd складається з двох типів секцій, mount і group. У секції mount вказуються підсистеми, що керують контрольними групами, і точка монтування ієрархії контрольних груп.

Розглянемо приклад зі створенням контрольної групи mycgroup, керованої підсистемою cpuset в каталозі / mnt / cgroups. Для цього знадобиться такий файл config.conf:

mount {cpuset = / mnt / cgroups / cpuset;} group mycgroup {perm {task {uid = guest; gid = users;} admin {uid = root; gid = root;}} cpuset {cpuset.cpus = 2; cpuset.mems = 1;}}

Тут завданням групи mycgroup дозволено виконуватися тільки на логічному процесорі 2 і вузлі пам'яті 1, а файлом tasks буде володіти тільки користувач guest з групи users.

Виконання cgconfigparser створить потрібні контрольні групи з потрібними параметрами підсистем. Але приписувати процеси до групи може знадобитися динамічно, в міру їх виникнення, тому необхідний демон, який відстежує процеси і відбирає з них потрібні. Така робота реалізується демоном cgrulesengd, конфігураційний файл якого /etc/cgred.conf управляє загальними параметрами роботи, в тому числі задає ім'я файлу (повний шлях) для протоколювання і рівень подробиці.

Михайло Кузьмінський ( [email protected] ) - старший науковий співробітник Інституту органічної хімії ім. Н. Д. Зелінського РАН (Москва).