Рубрики

Виртуализация Linux: регулирование ресурсов с помощью cgroups

В статье « Виртуализация Linux — Chroot Jail» мы обсуждали пространства имен ядра и процессы джейлинга. Чтобы понять эту статью, вам может не понадобиться читать предыдущую статью, но я настоятельно рекомендую вам пройти ее один раз, прежде чем углубляться в регулирование ресурсов. Это должно очень помочь в понимании того, что происходит.

Что такое cgroups?

cgroups (сокращенно от контрольных групп) — это функция ядра Linux, которая ограничивает, учитывает и изолирует использование ресурсов (ЦП, память, дисковый ввод-вывод, сеть и т. д.) набора процессов.
Эта функция была первоначально разработана двумя инженерами из Google под названием «контейнеры процессов», но позже была объединена в основной ветке ядра Linux с именем «cgroups».

Почему это требуется?

Одна из целей разработки cgroups — предоставить унифицированный интерфейс для множества различных вариантов использования, от управления отдельными процессами (например, посредством nice) до виртуализации всей операционной системы. Проще говоря, cgroups обеспечивает:

  • Ограничение ресурса: Группы могут быть настроены так, чтобы не превышать установленный предел памяти, который также включает кэш файловой системы.
  • Расстановка приоритетов — некоторые группы могут получить большую долю использования ЦП или пропускной способности дискового ввода-вывода.
  • Учет — измеряет использование ресурсов группы, которое может использоваться, например, для выставления счетов.
  • Контроль — замораживание групп процессов, их контрольно-пропускной пункт и перезапуск.

Как они используются, прямо или косвенно?

Контрольные группы могут использоваться несколькими способами:

  1. Получая доступ к виртуальной файловой системе cgroup вручную.
  2. Создавая и управляя группами на лету, используя такие инструменты, как cgcreate, cgexec и cgclassify (из libcgroup).
  3. Посредством «демона обработчика правил», который может автоматически перемещать процессы определенных пользователей, групп или команд в cgroups, как указано в его конфигурации.
  4. Косвенно через другое программное обеспечение, которое использует cgroups, такие как Docker, виртуализация Linux Containers (LXC), libvirt, systemd, Open Grid Scheduler / Grid Engine и Google lmctfy.

Вы можете быть удивлены, но этот тихий демон составляет значительную часть вашего онлайн-опыта, так как довольно много веб-сайтов используют контейнеры / виртуализацию для размещения нескольких серверов или веб-сайтов, включая NetFlix, heruko и reddit.

Установка cgroups: Некоторые версии Linux поставляются с cgroups. Чтобы убедиться, что они уже установлены / смонтированы, проверьте вывод:

$ mount | grep "^cgroup"

Если вы видите файлы, смонтированные в / sys / fs / cgroup /, вы можете сразу перейти к следующей теме, чтобы пропустить часть установки.
Вторая команда устанавливает cgroup-tools, что облегчает контроль и мониторинг групп управления. Мы будем использовать команды из этого же руководства. Мы будем использовать утилиту iotop для мониторинга скорости дискового ввода-вывода.

$ sudo apt-get install cgroup-bin cgroup-lite libcgroup1 cgroup-lite
$ sudo apt-get install cgroup-tools
$ sudo apt-get install iotop

Если вы установили cgroups, но не видите их смонтированными в / sys / fs / cgroup, используйте эти команды,

$ mount -t tmpfs cgroup_root /sys/fs/cgroup
$ mkdir /sys/fs/cgroup/blkio
$ mount -t cgroup -o blkio none /sys/fs/cgroup/blkio

Пример 1. Мы создадим группу, управляемую диском, чтобы мы могли запустить любой процесс с конечным количеством доступных для чтения / записи дисков. то есть мы хотим ограничить чтение и запись, выполняемые процессом или группой процессов.

Шаг 1: Чтобы создать cgroup, просто создайте каталог в / sys / fs / cgroup или, если у вас есть настройка cgroup-tools, мы можем использовать их в соответствующем каталоге для подсистемы. Ядро автоматически заполняет каталог cgroup узлами файла настроек. Тем не менее, рекомендуется использовать API cgroup-tools,

# Switch to root for the rest of the commands
$ sudo su                    
$ cgcreate -g blkio:myapp  OR  mkdir /sys/fs/cgroup/blkio/myapp

Эта команда создаст подгруппу «myapp» в системе «blkio». Подсистема Block I / O (blkio) контролирует и контролирует доступ к I / O на блочных устройствах с помощью задач в cgroups. Запись значений в эти файлы обеспечивает контролируемый доступ к различным ресурсам. Вы можете проверить, создана ли ваша группа, запустив команду lscgroup, в которой перечислены все группы управления.

$ lscgroup | grep blkio:/myapp
blkio:/myapp

Важно: Эти файлы не являются обычными файлами на диске. Это псевдо-файлы, которые используются непосредственно ядром для чтения и изменения конфигурации. Не открывайте их в текстовом редакторе и не пытайтесь их сохранить. Всегда используйте команду «echo» для записи в них.

Прежде чем углубляться в простые вещи, давайте посмотрим на структуру каталогов вновь созданной группы. Вот некоторые важные файлы, которые нам понадобятся в этом руководстве, чтобы понять, как работает cgroup. (Самые важные из них выделены на изображении)

Шаг 2: Создаем 2 терминала и размещаем их один под другим. Станьте пользователем root в обоих терминалах. В верхнем терминале мы запускаем утилиту iotop для мониторинга дискового ввода-вывода,

$ sudo su
$ iotop -o 

Находясь на приведенном ниже терминале, мы создаем временный файл объемом 512 МБ с помощью команды «dd».

$ sudo su
$ dd if=/dev/zero of=~/test_if bs=1M count=512 

В команде dd «if» представляет входной файл, «of» — выходной файл, «bs» — размер блока, а «count» — количество раз, когда он записывает блок. После завершения команды создается ~ / temp_if размером 512 МБ. Вы можете увидеть скорость ввода / вывода в реальном времени в верхнем окне терминала.

Шаг 3: Теперь для нашего следующего эксперимента нам нужно убедиться, что мы сбросили все буферы файловой системы на диск и удалили все кэши, чтобы они не мешали нашим результатам.

$ free -m
$ sync
$ echo 3 > /proc/sys/vm/drop_caches
$ free -m 

Теперь вы должны увидеть увеличение доступной оперативной памяти и уменьшение размера кэша.

Шаг 3: Теперь, чтобы настроить пределы регулирования, мы используем следующие команды. Скажем, мы хотели бы установить лимит чтения / записи 5 МБ для процесса. Из документации ядра вы узнаете, что blkio.throttle.read_bps_device и blkio.throttle.write_bps_device принимают записи в формате,

<major>: <minor> <rate_per_second>

где major и minor — это значения для конкретного устройства, которое мы хотим ограничить. rate_per_second — это максимальная скорость, которая может быть достигнута процессом этой группы.

Получить старшие и младшие номера легко. На машине, на которой я работаю, есть только один диск / dev / sda, поэтому при выполнении команды ls -l / dev / sda * я могу получить основные, второстепенные числа.

Выделенные значения являются старшими и младшими номерами для моего / dev / sda диска.

Теперь мы записываем следующие значения, чтобы ограничить скорость чтения 5 Мбит / с.

$ echo "8:0 5242880" > /sys/fs/cgroup/blkio/myapp/blkio.throttle.read_bps_device
$ cat /sys/fs/cgroup/blkip/myapp/blkio.throttle.read_bps_device 

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

$ dd if=~/test_if of=/dev/null 

Шаг 5: Вы можете видеть скорость чтения в режиме реального времени в верхнем терминале. После завершения создания файла вы также можете увидеть среднюю скорость, которая отображается командой dd. Записывайте данные на диск и удаляйте все кэши, как показано ранее, чтобы избежать двусмысленности в результатах.

Чтобы запустить эту команду под управлением, мы используем cgexec

$ cgexec -g blkio:/myapp dd if=~/test_if of=/dev/null 

где мы указываем аргумент: name для аргумента -g, в данном случае это «blkio: myapp». Показатели в топ-терминале должны выглядеть примерно так.

Интересной частью этого является то, что мы можем использовать любое приложение, которое не имеет встроенного средства ограничения скорости, мы можем регулировать его по мере необходимости.

Приведенный выше график строится при чтении 2 файлов, процессы которых принадлежат одной и той же группе, с пределом чтения газа 50 Мбит / с. Как вы можете видеть вначале, скорость чтения прыгает до максимума, но как только начинается второе чтение, оно приходит в равновесие и в общей сложности составляет 50 МБ / с, как и ожидалось. Как только чтение «file-abc» заканчивается, скорость скачка снова достигает максимума.

Вы можете изменить скорость в реальном времени, отображая новые значения в файлах blkio.throttle . Ядро обновит конфигурации автоматически.

Пример 2: Мы следуем аналогичным шагам, чтобы создать приложение, регулируемое памятью. Я пропущу объяснение, так как большая его часть одинакова, и сразу перейду к командам.

Шаг 1: Я создал простую c-программу, которая выделяет 1 МБ на каждую итерацию и выполняет в общей сложности 50 итераций, выделяя всего 50 МБ.

// a simple c-program that allocates 1MB in each
// iteration and run for a total of 50 iterations,
// allocating a total of 50 MB
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    int i;
    char *p;
    for (i = 0; i < 50; ++i)
    {
        // Allocate 1 MB each time.
        if ((p = malloc(1<<20)) == NULL)
        {
            printf("Malloc failed at %d MB\n", i);
            return 0;
        }
        memset(p, 0, (1<<20));
        printf("Allocated %d to %d MB\n", i, i+1);
    }

    printf("Done!\n");
    return 0;
}
$ sudo su         # Switch to root for the rest of the comands
$ cgcreate -g memory:myapp_mem  OR  mkdir /sys/fs/cgroup/memory/myapp_mem
$ cd /sys/fs/cgroup/memory/myapp_mem
$ lscgroup        # To check if the group was created successfully. 

Теперь формат для регулирования конфигурации памяти можно получить из документации ядра (ссылка в ссылках).

$ echo "5242880" > memory.limit_in_bytes 

Перед запуском кода нам нужно отключить swap. Если программа не может получить память из ОЗУ (поскольку мы ограничены), она попытается выделить память подкачкой, что в нашем случае нежелательно.

$ sudo swapoff -a # Disable swap 

Состояние свопа должно быть таким же, как показано выше.

$ gcc mem_limit.c -o mem_limit 

Во-первых, запустите код без каких-либо ограничений памяти,

$ ./mem_limit 

Теперь сравните его вывод при запуске из контролируемой cgroup,

$ cgexec -g memory:myapp_mem /root/mem_limit 

Вы можете проверить различную информацию об учете ресурсов, такую как текущее использование памяти, максимальный объем используемой памяти, ограничение на объем памяти и т. Д.

$ cat memory.usage_in_bytes
$ cat memory.max_usage_in_bytes
$ cat memory.limit_in_bytes 

Есть и другие параметры, которые вы можете исследовать, такие как memory.failcnt, memory.kmem. * И memory.kmem.tcp. *
Чем больше вы будете читать документацию, тем лучше будет ваше понимание.

Мы можем расширить этот метод и создавать дросселированные приложения. Этот метод был создан давно, но в последнее время он широко используется во многих приложениях. Виртуальные машины, контейнеры и т. Д. Используют это для обеспечения ограничения ресурсов.
Целью понимания cgroups было понять, как на самом деле регулирование ресурсов выполняется в контейнерах. Следующая тема для изучения — контейнеры. Мы поговорим об этом подробнее в следующей статье.

Ссылки:

Об авторе:
Пинкеш Баджатия родом из IIIT Хайдарабад. В глубине души он гик, и его стоит искать. Его проектную работу можно увидеть здесь. Если вы также хотите продемонстрировать свой блог здесь, пожалуйста, смотрите GBlog для записи гостевого блога на GeeksforGeeks.

Рекомендуемые посты:

Виртуализация Linux: регулирование ресурсов с помощью cgroups

0.00 (0%) 0 votes