Управление, мониторинг и обновление ядра#

Следующие разделы содержат информацию о ядре Linux и RPM-пакете ядра Linux. Неотъемлемой частью этой главы является инструкция о том, как обновлять ядро, что гарантирует наличие в операционной системе всех последних исправлений ошибок, улучшений производительности и фиксов, а также ее совместимость с новым оборудованием.

Ядро Linux#

Ядро — это основная часть операционной системы Linux, которая управляет системными ресурсами и обеспечивает интерфейс между аппаратными и программными приложениями. Ядра упакованы в формате RPM, поэтому они легко обновляются и проверяются менеджером пакетов yum.

Пакет RPM#

Пакет RPM — это файл, содержащий другие файлы и их метаданные (информацию о файлах, которые необходимы системе). В частности, пакет RPM состоит из cpio архива.

В cpio архиве есть:

  • файлы;

  • заголовок RPM (метаданные пакета) Диспетчер rpm пакетов использует эти метаданные для определения зависимостей, места установки файлов и другой информации.

Типы пакетов RPM#

Существует два типа пакетов RPM. Оба типа имеют общий формат файла и инструменты, но имеют разное содержимое и служат разным целям:

  • Исходный оборот в минуту (SRPM) SRPM содержит исходный код и файл SPEC, в котором описывается, как встроить исходный код в двоичный RPM. При желании также включены исправления для исходного кода.

  • Двоичный об/мин Бинарный RPM содержит бинарные файлы, созданные из исходников и патчей.

Обзор RPM-пакета ядра Linux#

RPM — это метапакет kernel, который не содержит никаких файлов, а скорее обеспечивает правильную установку следующих необходимых подпакетов:

  • kernel-core — содержит двоичный образ ядра, все объекты, связанные с initramfs, для начальной загрузки системы и минимальное количество модулей ядра для обеспечения функциональности ядра. Только этот подпакет можно использовать в виртуализированных и облачных средах, чтобы обеспечить ядро SberLinux быстрой загрузкой и небольшим размером диска.

  • kernel-modules — содержит остальные модули ядра, которых нет в kernel-core.

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

Необязательные пакеты ядра, например:

  • kernel-modules-extra — содержит модули ядра для редкого оборудования и модули, загрузка которых отключена по умолчанию.

  • kernel-debug — содержит ядро с включенными многочисленными опциями отладки для диагностики ядра за счет снижения производительности.

  • kernel-tools — содержит инструменты для управления ядром Linux и сопроводительную документацию.

  • kernel-devel — содержит заголовки ядра и make-файлы, достаточные для сборки модулей из kernel пакета.

  • kernel-abi-stablelists — содержит информацию, относящуюся к ABI ядра SberLinux, включая список символов ядра, которые необходимы внешним модулям ядра Linux, и yum подключаемый модуль для обеспечения соблюдения.

  • kernel-headers— включает файлы заголовков C, которые определяют интерфейс между ядром Linux и библиотеками и программами пользовательского пространства. Файлы заголовков определяют структуры и константы, необходимые для построения большинства стандартных программ.

Отображение содержимого пакета ядра#

Следующая процедура описывает, как просмотреть содержимое пакета ядра и его подпакетов без их установки с помощью команды.

Предварительные условия:

  • Получены kernel, kernel-core, kernel-modules, kernel-modules-extra пакеты RPM для архитектуры ЦП

Процедура

  • Список модулей для kernel:


$ rpm -qlp <kernel_rpm>
(contains no files)
...

  • Список модулей для kernel-core:


$ rpm -qlp <kernel-core_rpm>
...
/lib/modules/4.18.0-80.el8.x86_64/kernel/fs/udf/udf.ko.xz
/lib/modules/4.18.0-80.el8.x86_64/kernel/fs/xfs
/lib/modules/4.18.0-80.el8.x86_64/kernel/fs/xfs/xfs.ko.xz
/lib/modules/4.18.0-80.el8.x86_64/kernel/kernel
/lib/modules/4.18.0-80.el8.x86_64/kernel/kernel/trace
/lib/modules/4.18.0-80.el8.x86_64/kernel/kernel/trace/ring_buffer_benchmark.ko.xz
/lib/modules/4.18.0-80.el8.x86_64/kernel/lib
/lib/modules/4.18.0-80.el8.x86_64/kernel/lib/cordic.ko.xz
...

  • Список модулей для kernel-modules:


$ rpm -qlp <kernel-modules_rpm>
...
/lib/modules/4.18.0-80.el8.x86_64/kernel/drivers/infiniband/hw/mlx4/mlx4_ib.ko.xz
/lib/modules/4.18.0-80.el8.x86_64/kernel/drivers/infiniband/hw/mlx5/mlx5_ib.ko.xz
/lib/modules/4.18.0-80.el8.x86_64/kernel/drivers/infiniband/hw/qedr/qedr.ko.xz
/lib/modules/4.18.0-80.el8.x86_64/kernel/drivers/infiniband/hw/usnic/usnic_verbs.ko.xz
/lib/modules/4.18.0-80.el8.x86_64/kernel/drivers/infiniband/hw/vmw_pvrdma/vmw_pvrdma.ko.xz
...

  • Список модулей для kernel-modules-extra:


$ rpm -qlp <kernel-modules-extra_rpm>
...
/lib/modules/4.18.0-80.el8.x86_64/extra/net/sched/sch_cbq.ko.xz
/lib/modules/4.18.0-80.el8.x86_64/extra/net/sched/sch_choke.ko.xz
/lib/modules/4.18.0-80.el8.x86_64/extra/net/sched/sch_drr.ko.xz
/lib/modules/4.18.0-80.el8.x86_64/extra/net/sched/sch_dsmark.ko.xz
/lib/modules/4.18.0-80.el8.x86_64/extra/net/sched/sch_gred.ko.xz
...

Обновление ядра#

Следующая процедура описывает, как обновить ядро с помощью менеджера пакетов yum.

Процедура:

Чтобы обновить ядро, введите следующую команду:


# yum update kernel

Эта команда обновляет ядро вместе со всеми зависимостями до последней доступной версии.

Перезагрузите систему, чтобы изменения вступили в силу.

Установка определенных версий ядра#

Следующая процедура описывает, как установить новые ядра с помощью менеджера пакетов yum.

Процедура:

Чтобы установить конкретную версию ядра, введите следующую команду:


# yum install kernel-{version}

Управление модулями ядра#

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

Введение в модули ядра#

Ядро SberLinux может быть дополнено необязательными дополнительными функциями, называемыми модулями ядра, без перезагрузки системы. В SberLinux модули ядра представляют собой дополнительный код ядра, встроенный в сжатые <KERNEL_MODULE_NAME>.ko.xz объектные файлы.

Наиболее распространенные функции, предоставляемые модулями ядра:

  • Драйвер устройства, добавляющий поддержку нового оборудования;

  • Поддержка файловой системы, такой как GFS2 или NFS;

  • Системные вызовы.

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

Как и само ядро, модули могут принимать параметры, которые при необходимости настраивают их поведение.

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

Зависимости модуля ядра#

Некоторые модули ядра иногда зависят от одного или нескольких других модулей ядра. Файл /lib/modules/<KERNEL_VERSION>/modules.dep содержит полный список зависимостей модулей ядра для соответствующей версии ядра.

Файл зависимостей генерируется depmod программой, входящей в состав kmod пакета. Многие из предоставляемых утилит kmod учитывают зависимости модулей при выполнении операций, поэтому ручное отслеживание зависимостей требуется редко.

Предупреждение: Код модулей ядра выполняется в пространстве ядра в неограниченном режиме. Из-за этого помните о том, какие модули загружаете.

Список установленных модулей ядра#

Команда grubby --info=ALL отображает проиндексированный список установленных ядер !BLS, а BLS устанавливает.

Процедура:

Перечислите установленные ядра, используя следующую команду:


# grubby --info=ALL | grep title

Список загруженных в данный момент модулей ядра#

Следующая процедура описывает, как просмотреть загруженные в данный момент модули ядра.

Предварительные условия:

Пакет kmod установлен.

Процедура

  • Чтобы получить список всех загруженных на данный момент модулей ядра, выполните:


$ lsmod

Module                  Size  Used by
fuse                  126976  3
uinput                 20480  1
xt_CHECKSUM            16384  1
ipt_MASQUERADE         16384  1
xt_conntrack           16384  1
ipt_REJECT             16384  1
nft_counter            16384  16
nf_nat_tftp            16384  0
nf_conntrack_tftp      16384  1 nf_nat_tftp
tun                    49152  1
bridge                192512  0
stp                    16384  1 bridge
llc                    16384  2 bridge,stp
nf_tables_set          32768  5
nft_fib_inet           16384  1
...

В приведенном выше примере:

  • Первый столбец содержит имена загруженных в данный момент модулей.

  • Во втором столбце отображается объем памяти на модуль в килобайтах.

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

Список всех установленных ядер#

Следующая процедура описывает, как использовать grubby утилиту для получения списка всех установленных ядер в системе.

Предварительные условия:

Права root пользователя.

Процедура

  • Чтобы получить список всех установленных ядер, выполните:


# grubby --info=ALL | grep ^kernel

kernel="/boot/vmlinuz-4.18.0-305.10.2.el8_4.x86_64"
kernel="/boot/vmlinuz-4.18.0-240.el8.x86_64"
kernel="/boot/vmlinuz-0-rescue-41eb2e172d7244698abda79a51778f1b"

Вывод отображает путь ко всем установленным ядрам, а также отображает их соответствующие версии.

Установка ядра по умолчанию#

Следующая процедура описывает, как установить конкретное ядро по умолчанию с помощью grubby инструмента командной строки и GRUB.

Процедура:

  • Установка ядра по умолчанию с помощью grubby инструмента:

    • Выполните следующую команду, чтобы установить ядро по умолчанию с помощью grubby инструмента:


# grubby --set-default $kernel_path

Команда использует идентификатор машины без суффикса .conf в качестве аргумента. Идентификатор машины находится в **/boot/loader/entries/**каталоге.

  • Установка ядра по умолчанию с использованием id аргумента:

    • Перечислите загрузочные записи, используя id аргумент, а затем установите предполагаемое ядро по умолчанию:


# grubby --info ALL | grep id
# grubby --set-default /boot/vmlinuz-<version>.<architecture>

Примечание: Чтобы получить список загрузочных записей с помощью title аргумента, выполните команду.


# grubby --info=ALL | grep title

  • Установка ядра по умолчанию только для следующей загрузки:

    • Выполните следующую команду, чтобы установить ядро по умолчанию только для следующей перезагрузки с помощью grub2-reboot команды:


# grub2-reboot <index|title|id>

Предупреждение: С осторожностью установите ядро по умолчанию только для следующей загрузки. Установка новых RPM ядер, самосборных ядер и ручное добавление записей в /boot/loader/entries/ каталог может изменить значения индекса.

Отображение информации о модулях ядра#

При работе с модулем ядра может понадобиться дополнительная информация об этом модуле. Эта процедура описывает, как отобразить дополнительную информацию о модулях ядра.

Предварительные условия:

Пакет kmod установлен.

Процедура:

  • Чтобы отобразить информацию о любом модуле ядра, выполните:


$ modinfo <KERNEL_MODULE_NAME>

Например:


$ modinfo virtio_net

filename:       /lib/modules/4.18.0-94.el8.x86_64/kernel/drivers/net/virtio_net.ko.xz
license:        GPL
description:    Virtio network driver
sloversion:    8.1
srcversion:     2E9345B281A898A91319773
alias:          virtio:d00000001v*
depends:        net_failover
intree:         Y
name:           virtio_net
vermagic:       4.18.0-94.el8.x86_64 SMP mod_unload modversions
...
parm:           napi_weight:int
parm:           csum:bool
parm:           gso:bool
parm:           napi_tx:bool

Команда modinfo отображает некоторую подробную информацию об указанном модуле ядра. Можно запросить информацию обо всех доступных модулях, независимо от того, загружены они или нет. Записи parm показывают параметры, которые пользователь может установить для модуля, и тип ожидаемого значения.

Примечание: При вводе имени модуля ядра не добавляйте .ko.xz расширение в конец имени. Имена модулей ядра не имеют расширений; их соответствующие файлы делают.

Загрузка модулей ядра во время выполнения системы#

Оптимальный способ расширить функциональность ядра Linux — загрузить модули ядра. Следующая процедура описывает, как использовать modprobe команду для поиска и загрузки модуля ядра в работающее в данный момент ядро.

Предварительные условия:

  • root права;

  • Пакет kmod установлен;

  • Соответствующий модуль ядра не загружен. Чтобы убедиться, что это так, перечислите загруженные модули ядра (см. «Список загруженных в данный момент модулей ядра»).

Процедура:

  1. Выберите модуль ядра, который необходимо загрузить.

Модули находятся в /lib/modules/$(uname -r)/kernel// каталоге.

  1. Загрузите соответствующий модуль ядра:


# modprobe <MODULE_NAME>

Примечание: При вводе имени модуля ядра не добавляйте .ko.xz расширение в конец имени. Имена модулей ядра не имеют расширений; их соответствующие файлы делают.

При необходимости убедитесь, что соответствующий модуль был загружен:


$ lsmod | grep <MODULE_NAME>

Если модуль был загружен правильно, эта команда отображает соответствующий модуль ядра. Например:


$ lsmod | grep serio_raw
serio_raw 16384 0

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

Выгрузка модулей ядра во время работы системы#

Следующая процедура описывает, как использовать modprobe команду для поиска и выгрузки модуля ядра во время выполнения системы из загруженного в данный момент ядра.

Предварительные условия:

  • Права root пользователя.

  • Пакет kmod установлен.

Процедура:

  1. Выполните lsmod команду и выберите модуль ядра, который нужно выгрузить.

Если модуль ядра имеет зависимости, выгрузите их перед выгрузкой модуля ядра. Подробнее об идентификации модулей с зависимостями см. в разделе "Список загруженных в данный момент модулей ядра" и "Зависимости модулей ядра".

  1. Выгрузите соответствующий модуль ядра:


# modprobe -r <MODULE_NAME>

  1. При вводе имени модуля ядра не добавляйте .ko.xz расширение в конец имени. Имена модулей ядра не имеют расширений; их делают соответствующие файлы.

Предупреждение: Не выгружайте модули ядра, когда они используются работающей системой. Это может привести к нестабильности или неработоспособности системы.

  1. При необходимости убедитесь, что соответствующий модуль был выгружен:


$ lsmod | grep <MODULE_NAME>

Если модуль был успешно выгружен, эта команда ничего не выводит.

Примечание: После завершения этой процедуры модули ядра, которые определены для автоматической загрузки при загрузке, не останутся незагруженными после перезагрузки системы. Информацию о том, как противостоять этому результату, см. в разделе «Предотвращение автоматической загрузки модулей ядра во время загрузки системы».

Выгрузка модулей ядра на ранних стадиях процесса загрузки#

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

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

Предварительные условия:

Существует загружаемый модуль ядра, который нужно по какой-то причине не загружать.

Процедура:

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

  1. Используйте клавиши курсора, чтобы выделить соответствующую запись загрузчика.

  2. Нажмите клавишу Е, чтобы отредактировать запись.

  3. С помощью клавиш курсора перейдите к строке, начинающейся с linux.

  4. Добавить modprobe.blacklist=module_name в конец строки.

  5. Нажмите клавиши CTRL+xдля загрузки с измененной конфигурацией.

Проверка:

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


# lsmod | grep serio_raw

Рисунок. Модуль ядра не загружен

Автоматическая загрузка модулей ядра во время загрузки системы#

Следующая процедура описывает, как настроить модуль ядра, чтобы он загружался автоматически во время процесса загрузки.

Предварительные условия:

  • Права root пользователя.

  • Пакет kmod установлен.

Процедура:

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

Модули находятся в /lib/modules/$(uname -r)/kernel// каталоге.

  1. Создайте файл конфигурации для модуля:


# echo <MODULE_NAME> > /etc/modules-load.d/<MODULE_NAME>.conf

Примечание: При вводе имени модуля ядра не добавляйте .ko.xz расширение в конец имени. Имена модулей ядра не имеют расширений; их делают соответствующие файлы.

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


$ lsmod | grep <MODULE_NAME>

Приведенная выше примерная команда должна завершиться успешно и отобразить соответствующий модуль ядра.

Примечание: Изменения, описанные в этой процедуре, сохранятся после перезагрузки системы.

Предотвращение автоматической загрузки модулей ядра во время загрузки системы#

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

Предварительные условия:

  • Права root пользователя.

  • Пакет kmod установлен.

  • Модуль ядра в списке запрещенных не является важным для текущей конфигурации системы.

Процедура:

  1. Выберите модуль ядра, который необходимо поместить в список запрещенных:


$ lsmod

Module                  Size  Used by
fuse                  126976  3
xt_CHECKSUM            16384  1
ipt_MASQUERADE         16384  1
uinput                 20480  1
xt_conntrack           16384  1
...

  1. Команда lsmod отображает список модулей, загруженных в работающее в данный момент ядро.

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

  • Все модули ядра находятся в /lib/modules/<KERNEL_VERSION>/kernel// каталоге.

  1. Создайте файл конфигурации для запрещенного списка:


# vim /etc/modprobe.d/blacklist.conf

    # Blacklists <KERNEL_MODULE_1>
    blacklist <MODULE_NAME_1>
    install <MODULE_NAME_1> /bin/false

    # Blacklists <KERNEL_MODULE_2>
    blacklist <MODULE_NAME_2>
    install <MODULE_NAME_2> /bin/false

    # Blacklists <KERNEL_MODULE_n>
    blacklist <MODULE_NAME_n>
    install <MODULE_NAME_n> /bin/false
...

В примере показано содержимое blacklist.conf файла, отредактированное vim редактором. Строка blacklist гарантирует, что соответствующий модуль ядра не будет автоматически загружен в процессе загрузки. Однако эта blacklist команда не предотвращает загрузку модуля в качестве зависимости для другого модуля ядра, которого нет в списке запрещенных. Поэтому эта install строка заставляет /bin/false работать вместо установки модуля.

Строки, начинающиеся со знака решетки, являются комментариями, чтобы сделать файл более читабельным.

Примечание: При вводе имени модуля ядра не добавляйте .ko.xz расширение в конец имени. Имена модулей ядра не имеют расширений; их соответствующие файлы делают.

  1. Перед перестроением создайте резервную копию текущего исходного образа виртуального диска:


# cp /boot/initramfs-$(uname -r).img /boot/initramfs-$(uname -r).bak.$(date +%m-%d-%H%M%S).img

Приведенная выше команда создает резервную копию initramfs на случай, если в новой версии возникнут непредвиденные проблемы.

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


# cp /boot/initramfs-<SOME_VERSION>.img /boot/initramfs-<SOME_VERSION>.img.bak.$(date +%m-%d-%H%M%S)

  1. Создайте новый начальный образ виртуального диска, чтобы отразить изменения:


# dracut -f -v

  1. Если создается начальный образ виртуального диска для версии ядра, отличной от той, в которую произошла загрузка в данный момент, укажите и целевую версию, initramfs и версию ядра:


# dracut -f -v /boot/initramfs-<TARGET_VERSION>.img <CORRESPONDING_TARGET_KERNEL_VERSION>

  1. Перезагрузите систему:


$ reboot

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

Компиляция пользовательских модулей ядра#

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

Предварительные условия:

  • Установлены пакеты kernel-devel, gcc и .elfutils-libelf-devel

  • Права root пользователя.

  • Создан /root/testmodule/ каталог, в котором компилируете пользовательский модуль ядра.

Процедура:

  1. Создайте /root/testmodule/test.c файл со следующим содержимым.


#include <linux/module.h>
#include <linux/kernel.h>

int init_module(void)
    { printk("Hello World\n This is a test\n"); return 0; }

void cleanup_module(void)
    { printk("Good Bye World"); }

Файл test. представляет собой исходный файл, обеспечивающий основную функциональность модуля ядра. Файл был создан в специальном /root/testmodule/ каталоге для организационных целей. После компиляции модуля /root/testmodule/ каталог будет содержать несколько файлов.

Файл test.c включает в себя из системных библиотек:

  • Заголовочный linux/kernel.h файл необходим для printk() функции в примере кода.

  • Файл linux/module.h содержит объявления функций и определения макросов, которые будут совместно использоваться несколькими исходными файлами, написанными на языке программирования C.

Затем следуйте функциям init_module() и cleanup_module() для запуска и завершения функции ведения журнала ядра printk(), которая печатает текст.

  1. Создайте /root/testmodule/Makefile файл со следующим содержимым:


obj-m := test.o

Makefile содержит инструкции, которые компилятор должен создать объектный файл со специальным именем test.o. Директива obj-mу указывает, что полученный test.ko файл будет скомпилирован как загружаемый модуль ядра. В качестве альтернативы obj-y директива предписывает собирать test.ko как встроенный модуль ядра.

  1. Скомпилируйте модуль ядра.


# make -C /lib/modules/$(uname -r)/build M=/root/testmodule modules
make: Entering directory '/usr/src/kernels/4.18.0-305.el8.x86_64'
  CC [M]  /root/testmodule/test.o
  Building modules, stage 2.
  MODPOST 1 modules
WARNING: modpost: missing MODULE_LICENSE() in /root/testmodule/test.o
see include/linux/module.h for more information
  CC      /root/testmodule/test.mod.o
  LD [M]  /root/testmodule/test.ko
make: Leaving directory '/usr/src/kernels/4.18.0-305.el8.x86_64'

Компилятор создает объектный файл (test.o) для каждого исходного файла (test.c) в качестве промежуточного шага перед их объединением в окончательный модуль ядра (test.ko).

После успешной компиляции /root/testmodule/ содержит дополнительные файлы, относящиеся к скомпилированному пользовательскому модулю ядра. Сам скомпилированный модуль представлен test.ko файлом.

Проверка:

  1. Необязательно: проверьте содержимое /root/testmodule/ каталога:


# ls -l /root/testmodule/
total 152
-rw-r—r--. 1 root root 16 Jul 26 08:19 Makefile
-rw-r—r--. 1 root root 25 Jul 26 08:20 modules.order
-rw-r—r--. 1 root root 0 Jul 26 08:20 Module.symvers
-rw-r—r--. 1 root root 224 Jul 26 08:18 test.c
-rw-r—r--. 1 root root 62176 Jul 26 08:20 test.ko
-rw-r—r--. 1 root root 25 Jul 26 08:20 test.mod
-rw-r—r--. 1 root root 849 Jul 26 08:20 test.mod.c
-rw-r—r--. 1 root root 50936 Jul 26 08:20 test.mod.o
-rw-r—r--. 1 root root 12912 Jul 26 08:20 test.o

  1. Скопируйте модуль ядра в /lib/modules/$(uname -r)/ каталог:


# cp /root/testmodule/test.ko /lib/modules/$(uname -r)/

  1. Обновите список модульных зависимостей:


# depmod -a

  1. Загрузите модуль ядра:


# modprobe -v test
insmod /lib/modules/4.18.0-305.el8.x86_64/test.ko

  1. Убедитесь, что модуль ядра был успешно загружен:


# lsmod | grep test
test                   16384  0

  1. Прочитайте последние сообщения из кольцевого буфера ядра:


# dmesg
[74422.545004] Hello World
                This is a test

Настройка параметров командной строки ядра#

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

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

Понимание параметров командной строки ядра#

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

  • ядро SberLinux;

  • начальный RAM-диск;

  • возможности пользовательского пространства.

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

По умолчанию параметры командной строки ядра для систем, использующих загрузчик GRUB, определяются в kernel opts переменной /boot/grub2/grubenv файла для каждой загрузочной записи ядра.

Утилита grubby#

grubby — это утилита для управления файлами конфигурации загрузчика.

Также можно использовать grubby для изменения загрузочной записи по умолчанию и для добавления/удаления аргументов из пункта меню GRUB.

Загрузочные записи#

Загрузочная запись — это набор параметров, которые хранятся в файле конфигурации и привязаны к конкретной версии ядра. На практике есть как минимум столько же загрузочных записей, сколько ядер установлено в системе. Файл конфигурации загрузочной записи находится в /boot/loader/entries/ каталоге и может выглядеть так:


6f9cc9cb7d7845d49698c9537337cedc-4.18.0-5.el8.x86_64.conf

Приведенное выше имя файла состоит из идентификатора машины, хранящегося в /etc/machine-id файле, и версии ядра.

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

Переменная kernelopts среды определена в /boot/grub2/grubenv файле.

Изменение параметров командной строки ядра для всех загрузочных записей#

Эта процедура описывает, как изменить параметры командной строки ядра для всех загрузочных записей в системе.

Предварительные условия:

Убедитесь, что grubby утилита установлена в системе.

Процедура:

  • Чтобы добавить параметр:


# grubby --update-kernel=ALL --args="<NEW_PARAMETER>"

Для систем, использующих загрузчик GRUB, команда обновляет /boot/grub2/grubenv файл, добавляя новый параметр ядра к kernelopts переменной в этом файле.

  • Чтобы удалить параметр, введите:


# grubby --update-kernel=ALL --remove-args="<PARAMETER_TO_REMOVE>"

  • После каждого обновления пакета ядра распространяйте сконфигурированные параметры ядра на новые ядра:


# grub2-mkconfig -o /etc/grub2.cfg

Примечание: Новые установленные ядра не наследуют параметры командной строки ядра от ранее сконфигурированных ядер. Необходимо запустить grub2-mkconfig команду на только что установленном ядре, чтобы распространить необходимые параметры на новое ядро.

Изменение параметров командной строки ядра для одной загрузочной записи#

Эта процедура описывает, как изменить параметры командной строки ядра для одной загрузочной записи в системе.

Предварительные условия:

Убедитесь, что в системе установлены утилиты grubby и zipl.

Процедура:

  • Чтобы добавить параметр, введите:


# grubby --update-kernel=/boot/vmlinuz-$(uname -r) --args="<NEW_PARAMETER>"

  • Чтобы удалить параметр, используйте следующее:


# grubby --update-kernel=/boot/vmlinuz-$(uname -r) --remove-args="<PARAMETER_TO_REMOVE>"

Примечание: В системах, использующих этот grub.cfg файл, по умолчанию есть options параметр для каждой загрузочной записи ядра, для которого задана kernelopts переменная. Эта переменная определена в / boot/grub2/grubenv файле конфигурации.

Предупреждение: В системах GRUB2:

  • Если параметры командной строки ядра изменены для всех загрузочных записей, grubby утилита обновляет kernelopts переменную в /boot/grub2/grubenv файле.

  • Если параметры командной строки ядра изменяются для одной загрузочной записи, kernelopts переменная расширяется, параметры ядра изменяются, а результирующее значение сохраняется в файле соответствующей загрузочной записи /boot/loader/entries/<RELEVANT_KERNEL_BOOT_ENTRY.conf>.

В системах zIPL:

  • grubby изменяет и сохраняет параметры командной строки ядра для отдельной загрузочной записи ядра в файле /boot/loader/entries/.conf.

Временное изменение параметров командной строки ядра во время загрузки#

Следующая процедура позволяет вносить временные изменения в запись меню ядра, изменяя параметры ядра только во время одного процесса загрузки.

Процедура:

  1. Выберите ядро, которое нужно запустить, когда появится меню загрузки GRUB 2, и нажмите клавишу e, чтобы отредактировать параметры ядра.

  2. Найдите командную строку ядра, переместив курсор вниз. Командная строка ядра начинается с linux в 64-разрядных системах IBM Power Series и x86-64 на базе BIOS или linuxefi в системах с UEFI.

  3. Переместите курсор в конец строки.

Примечание: Нажмите Ctrl + a, чтобы перейти к началу строки, и Ctrl + e, чтобы перейти к концу строки. В некоторых системах также могут работать клавиши Home и End.

  1. Отредактируйте параметры ядра по мере необходимости. Например, чтобы запустить систему в аварийном режиме, добавьте параметр Emergency в конец строки linux:


linux ($root)/vmlinuz-4.18.0-348.12.2.el8_5.x86_64 root=/dev/mapper/sberlinux-root ro crashkernel=auto resume=/dev/mapper/sberlinux-swap rd.lvm.lv=sberlinux/root rd.lvm.lv=sberlinux/swap rhgb quiet emergency

Чтобы включить системные сообщения, удалите параметры rhgb и quiet.

Нажмите Ctrl + x для загрузки с выбранным ядром и измененными параметрами командной строки.

Примечание: Нажмите клавишу Esc, чтобы выйти из режима редактирования командной строки, и все изменения, сделанные пользователем, будут удалены.

Примечание: Эта процедура применяется только для однократной загрузки и не вносит постоянные изменения.

Настройка параметров GRUB для включения подключения к последовательной консоли#

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

Необходимо настроить некоторые параметры GRUB по умолчанию, чтобы использовать соединение с последовательной консолью.

Предварительные условия:

Права root пользователи.

Процедура:

  1. Добавьте следующие две строки в /etc/default/grub файл:


GRUB_TERMINAL="serial"
GRUB_SERIAL_COMMAND="serial --speed=9600 --unit=0 --word=8 --parity=no --stop=1"

Первая строка отключает графический терминал. Ключ GRUB_TERMINAL переопределяет значения ключей GRUB_TERMINAL_INPUT и GRUB_TERMINAL_OUTPUT.

Вторая строка настраивает скорость передачи данных –speed, контроль четности и другие значения в соответствии со средой и оборудованием. Обратите внимание, что гораздо более высокая скорость передачи, например 115200, предпочтительнее для таких задач, как просмотр файлов журнала.

  1. Обновите файл конфигурации GRUB.

  • На машинах с BIOS:


# grub2-mkconfig -o /boot/grub2/grub.cfg

  • На машинах на базе UEFI:


# grub2-mkconfig -o /boot/efi/EFI/sberlinux/grub.cfg

  • Перезагрузите систему, чтобы изменения вступили в силу.

Настройка параметров ядра во время выполнения#

Системному администратору можно изменять многие аспекты поведения ядра SberLinux во время выполнения. В этом разделе описывается, как настроить параметры ядра во время выполнения с помощью sysctl команды и путем изменения файлов конфигурации в /etc/sysctl.d/ и ./proc/sys/ каталогах.

Параметры ядра#

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

Можно обращаться к параметрам ядра через:

  • команду sysctl_;

  • виртуальную файловую систему, смонтированную в /proc/sys/ каталоге;

  • файлы конфигурации в /etc/sysctl.d/ каталоге;

  • настраиваемые элементы разделены на классы подсистемой ядра. SberLinux имеет следующие настраиваемые классы, представленные в таблице ниже.

Таблица. Классы в sysctl

Настраиваемый класс

Подсистема

abi

Домены исполнения и личности.

crypto

Криптографические интерфейсы.

debug

Интерфейсы отладки ядра.

dev

Информация об устройстве.

fs

Глобальные и специальные настройки файловой системы.

kernel

Глобальные настройки ядра.

net

Сетевые настройки.

sunrpc

Удаленный вызов процедур Sun (NFS).

user

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

vm

Настройка и управление памятью, буферами и кешем

Примечание: Настройка параметров ядра в производственной системе требует тщательного планирования. Незапланированные изменения могут сделать ядро нестабильным, что потребует перезагрузки системы. Перед изменением каких-либо значений ядра убедитесь, что используются допустимые параметры.

Временная настройка параметров ядра с помощью sysctl#

Следующая процедура описывает, как использовать sysctl команду для временной установки параметров ядра во время выполнения. Команда также полезна для вывода списка и фильтрации настраиваемых параметров.

Предварительные условия:

Права root пользователя.

Процедура:

  1. Чтобы перечислить все параметры и их значения, используйте следующее:


# sysctl -a

Примечание: Команда # sysctl -a отображает параметры ядра, которые можно настроить во время выполнения и во время загрузки.

  1. Чтобы временно настроить параметр, используйте команду, как в следующем примере:


# sysctl <TUNABLE_CLASS>.<PARAMETER>=<TARGET_VALUE>

Приведенная выше примерная команда изменяет значение параметра во время работы системы. Изменения вступают в силу немедленно, без необходимости перезапуска.

Примечание: Изменения возвращаются к значениям по умолчанию после перезагрузки системы.

Постоянная настройка параметров ядра с помощью sysctl#

Следующая процедура описывает, как использовать sysctl команду для постоянной установки параметров ядра.

Предварительные условия:

Права root пользователя.

Процедура:

  1. Чтобы перечислить все параметры, используйте следующее:


# sysctl -a

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

  1. Чтобы настроить параметр на постоянной основе:


# sysctl -w <TUNABLE_CLASS>.<PARAMETER>=<TARGET_VALUE> >> /etc/sysctl.conf

Пример команды изменяет настраиваемое значение и записывает его в /etc/sysctl.conf файл, который переопределяет значения параметров ядра по умолчанию. Изменения вступают в силу немедленно и постоянно, без необходимости перезапуска.

Примечание: Чтобы навсегда изменить параметры ядра, можно вручную изменить файлы конфигурации в /etc/sysctl.d/ каталоге.

Использование файлов конфигурации в /etc/sysctl.d/ для настройки параметров ядра#

Следующая процедура описывает, как вручную изменить файлы конфигурации в /etc/sysctl.d/ каталоге, чтобы установить постоянные параметры ядра.

Предварительные условия:

Права root пользователя.

Процедура:

  1. Создайте новый файл конфигурации в /etc/sysctl.d/:


# vim /etc/sysctl.d/<some_file.conf>

  1. Включите параметры ядра, по одному в строке, следующим образом:


<TUNABLE_CLASS>.<PARAMETER>=<TARGET_VALUE>
<TUNABLE_CLASS>.<PARAMETER>=<TARGET_VALUE>

  1. Сохраните файл конфигурации.

  2. Перезагрузите машину, чтобы изменения вступили в силу.

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


# sysctl -p /etc/sysctl.d/<some_file.conf>

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

Временная настройка параметров ядра через /proc/sys/#

Следующая процедура описывает, как временно установить параметры ядра с помощью файлов в каталоге виртуальной файловой системы /proc/sys/.

Предварительные условия:

Права root пользователя.

Процедура:

  1. Определите параметр ядра, который необходимо настроить:


# ls -l /proc/sys/<TUNABLE_CLASS>/

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

  1. Присвойте целевое значение параметру ядра:


# echo <TARGET_VALUE> > /proc/sys/<TUNABLE_CLASS>/<PARAMETER>

Команда вносит изменения в конфигурацию, которые исчезают после перезапуска системы.

  1. При желании проверьте значение вновь установленного параметра ядра:


# cat /proc/sys/<TUNABLE_CLASS>/<PARAMETER>

Начало работы с ведением журнала ядра#

Файлы журналов — это файлы, содержащие сообщения о системе, включая ядро, службы и запущенные в ней приложения. Система журналирования в SberLinux основана на встроенном протоколе системного журнала. Различные утилиты используют эту систему для записи событий и организации их в файлы журналов. Эти файлы полезны при проверке операционной системы или устранении неполадок.

Кольцевой буфер ядра#

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

Упомянутый выше буфер представляет собой циклическую структуру данных фиксированного размера, жестко запрограммированную в ядре. Пользователи могут отображать данные, хранящиеся в кольцевом буфере ядра, с помощью dmesg команды или /var/log/boot.log файла. Когда кольцевой буфер заполнен, новые данные перезаписывают старые.

Роль printk на уровнях журнала и ведении журнала ядра#

Каждое сообщение от ядра имеет связанный с ним уровень журнала, который определяет важность сообщения. Кольцевой буфер ядра, собирает сообщения ядра всех уровней журнала. Это kernel.printk параметр, определяющий, какие сообщения из буфера выводятся на консоль.

Значения уровня журнала разбиваются в следующем порядке:

0 — аварийная ситуация с ядром. Система непригодна для использования.

1 — Оповещение ядра. Действия должны быть приняты немедленно.

2 — Состояние ядра считается критическим.

3 — Состояние общей ошибки ядра.

4 — Общее состояние предупреждения ядра.

5 — Уведомление ядра о нормальном, но серьезном состоянии.

6 — Информационное сообщение ядра.

7 — сообщения уровня отладки ядра.

По умолчанию kernel.printk в SberLinux содержатся следующие четыре значения:


# sysctl kernel.printk

kernel.printk = 7 4 1 7

Четыре значения определяют следующее:

  1. Уровень журнала консоли определяет самый низкий приоритет сообщений, выводимых на консоль.

  2. Уровень журнала по умолчанию для сообщений без явного прикрепленного к ним уровня журнала.

  3. Устанавливает наименьшую возможную конфигурацию уровня журнала для уровня журнала консоли.

  4. Устанавливает значение по умолчанию для уровня журнала консоли во время загрузки.

Каждое из этих значений определяет отдельное правило обработки сообщений об ошибках.

Примечание: Значение по умолчанию 7 4 1 7 printkзначение позволяет лучше отлаживать активность ядра. Однако в сочетании с последовательной консолью этот printkпараметр может вызвать интенсивные всплески ввода-вывода, которые могут привести к тому, что система временно перестанет отвечать на запросы. Чтобы избежать таких ситуаций, установка printk значения 4 4 1 7 обычно работает, но за счет потери дополнительной отладочной информации.

Также обратите внимание, что некоторые параметры командной строки ядра, такие как quiet или debug, изменяют значения по умолчанию kernel.printk.

Установка kdump#

Служба kdump устанавливается и активируется по умолчанию в новых установках SberLinux. В следующих разделах объясняется, что kdump такое и как установить, kdump если он не включен по умолчанию.

Служба kdump#

kdump — это служба, предоставляющая механизм аварийного dump для ядра. Сервис позволяет сохранять содержимое системной памяти для анализа. kdump использует системный вызов kexec для загрузки второго ядра (ядро захвата) без перезагрузки; а затем захватывает содержимое памяти сбойного ядра (аварийный dump или vmcore) и сохраняет его в файл. Второе ядро находится в зарезервированной части системной памяти.

Примечание: dump сбоя ядра может быть единственной доступной информацией в случае системного сбоя (критической ошибки). Поэтому оперативность kdump важна в критически важных средах. Рекомендуется, чтобы системные администраторы регулярно обновляли и тестировали kexec-tools обычный цикл обновления ядра. Это особенно важно, когда реализуются новые функции ядра.

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

При kdump установке создается /etc/kdump.conf файл по умолчанию. Файл включает минимальную kdump конфигурацию по умолчанию. Можно отредактировать этот файл, чтобы настроить kdump конфигурацию, но это не обязательно.

Установка kdump с помощью Anaconda#

Программа установки Anaconda предоставляет экран графического интерфейса для kdump настройки во время интерактивной установки. Экран установщика называется KDUMP и доступен на главном экране сводки установки. Можно включить kdump и зарезервировать необходимый объем памяти.

Процедура:

  1. Перейдите в KDUMP поле.

  2. Включите kdump, если еще не включено.

Рисунок. Включение kdump

  1. Определите, сколько памяти должно быть зарезервировано для файлов kdump.

Рисунок. Память для файлов kdump

Установка kdump из командной строки#

Некоторые параметры установки, такие как выборочная установка Kickstart, в некоторых случаях не устанавливаются или не включаются kdump по умолчанию. В этом случае - выполните описанную ниже процедуру.

Предварительные условия:

  • Пакет kexec-tools установлен.

  • Выполнены требования к kdump конфигурациям и целям. Подробнее см. в разделе «Поддерживаемые конфигурации и цели kdump».

Процедура:

  1. Проверьте, установлен ли kdump в системе:


# rpm -q kexec-tools

Вывод, если пакет установлен:


kexec-tools-2.0.17-11.el8.x86_64

Вывод, если пакет не установлен:


package kexec-tools is not installed

Установите kdump и другие необходимые пакеты:


# dnf install kexec-tools

Настройка kdump в командной строке#

В следующих разделах объясняется, как планировать и создавать kdump среду.

Оценка размера kdump#

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

Команда makedumpfile --mem-usage оценивает, сколько места требуется для файла аварийного dump. Создает отчет об использовании памяти. Отчет поможет определить уровень dump и какие страницы можно безопасно исключить.

Процедура:

  • Выполните следующую команду, чтобы создать отчет об использовании памяти:


# makedumpfile --mem-usage /proc/kcore

TYPE        PAGES    EXCLUDABLE    DESCRIPTION
-------------------------------------------------------------
ZERO                    501635      yes        Pages filled with zero
CACHE                  51657       yes        Cache pages
CACHE_PRIVATE 5442        yes        Cache pages + private
USER                    16301       yes        User process pages
FREE                     77738211    yes        Free pages
KERN_DATA.        1333192     no         Dumpable kernel data

Примечание: Команда makedumpfile --mem-usage сообщает требуемую память в страницах. Это означает, что нужно рассчитать размер используемой памяти в зависимости от размера страницы ядра.

Настройка использования памяти kdump#

Память для kdump резервируется во время загрузки системы. Размер памяти настраивается в системном файле конфигурации Grand Unified Bootloader (GRUB). Размер памяти зависит от значения crashkernel= параметра, указанного в файле конфигурации, и размера физической памяти системы.

Опция crashkernel= может быть определена несколькими способами. Можно указать crashkernel= значение или настроить auto параметр. Параметр crashkernel=auto резервирует память автоматически, исходя из общего объема физической памяти в системе. При настройке ядро автоматически резервирует соответствующий объем необходимой памяти для ядра захвата. Это помогает предотвратить ошибки нехватки памяти (OOM).

Предварительные условия:

  • root права;

  • Выполнены требования к kdump конфигурациям и целям. Подробнее см. в разделе "Поддерживаемые конфигурации и цели kdump".

Процедура:

  1. Отредактируйте /etc/default/grub файл.

  2. Установите crashkernel= параметр.

Например, чтобы зарезервировать 128 МБ памяти, используйте следующее:


crashkernel=128M

Кроме того, можно установить объем зарезервированной памяти переменной в зависимости от общего объема установленной памяти. Синтаксис резервирования памяти в переменную: crashkernel=:,:. Например:


crashkernel=512M-2G:64M,2G-:128M

В приведенном выше примере резервируется 64 МБ памяти, если общий объем системной памяти составляет от 512 МБ до 2 ГБ. Если общий объем памяти превышает 2 ГБ, резервируется 128 МБ.

  • Смещение зарезервированной памяти. Некоторым системам требуется резервировать память с определенным фиксированным смещением, поскольку crashkernelрезервирование происходит очень рано, и требуется зарезервировать некоторую область для специального использования. Если установлено смещение, зарезервированная память начинается там. Чтобы компенсировать зарезервированную память, используйте следующий синтаксис:


crashkernel=128M@16M

В приведенном выше примере kdump резервируется 128 МБ памяти, начиная с 16 МБ (физический адрес 0x01000000). Если параметр смещения установлен на 0 или полностью опущен, kdump автоматически смещается зарезервированная память. Также можно использовать этот синтаксис при настройке резервирования переменной памяти. В этом случае смещение всегда указывается последним (например, crashkernel=512M-2G:64M,2G-:128M@16M).

  1. Используйте следующую команду для обновления файла конфигурации GRUB:


# grub2-mkconfig -o /boot/grub2/grub.cfg

Примечание: Альтернативный способ настроить память для kdump — добавить параметр crashkernel=<SOME_VALUE> к переменной kernelopts с помощью команды grub2-editenv, которая обновит все загрузочные записи. Или можно использовать утилиту grubbyдля обновления одной загрузочной записи, нескольких загрузочных записей или всех загрузочных записей.

Настройка цели kdump#

Аварийный dump обычно хранится в виде файла в локальной файловой системе и записывается непосредственно на устройство. Кроме того, можно настроить отправку аварийного dump по сети с использованием протоколов NFS или SSH. Одновременно можно установить только один из этих параметров для сохранения файла аварийного dump. Поведение по умолчанию — хранить его в /var/crash/ каталоге локальной файловой системы.

Предварительные условия:

  • Права root пользователя.

  • Выполнены требования к kdump конфигурациям и целям. Подробнее см. в разделе «Поддерживаемые конфигурации и цели kdump».

Процедура:

Чтобы сохранить файл аварийного dump в /var/crash/ каталоге локальной файловой системы, отредактируйте /etc/kdump.confфайл и укажите путь:


path /var/crash

Параметр path /var/crash представляет собой путь к файловой системе, в которой kdump сохраняется файл аварийного dump. Когда указана цель dump в /etc/kdump.conf файле, то path относится к указанной цели dump.

Если цель dump не указана в /etc/kdump.conf файле, то path представляет собой абсолютный путь от корневого каталога. В зависимости от того, что смонтировано в текущей системе, цель dump и скорректированный путь dump выбираются автоматически.

Предупреждение: kdump сохраняет файл аварийного dump в /var/crash/var/crash каталоге, когда цель dump смонтирована в /var/crash и параметр path установлен как /var/crash в /etc/kdump.conf файле. Например, в следующем примере ext4 файловая система уже смонтирована в /var/crash и path установлена как /var/crash:


# grep -v ^# /etc/kdump.conf | grep -v ^$
ext4 /dev/mapper/vg00-varcrashvol
path /var/crash
core_collector makedumpfile -c --message-level 1 -d 31

Эти результаты в /var/crash/var/crash пути. Чтобы решить эту проблему, используйте опцию path / вместо path /var/crash.

  • Чтобы изменить локальный каталог, в котором должен быть сохранен аварийный dump, от имени пользователя root отредактируйте файл конфигурации /etc/kdump.conf, как описано ниже.

    1. Удалите знак решетки ("#") в начале #path /var/crash строки.

    2. Замените значение предполагаемым путем к каталогу. Например:


path /usr/local/cores

Примечание: Каталог, определенный как цель kdump с помощью директивы пути, должен существовать при запуске службы kdump systemd, иначе служба не работает.

  • Чтобы записать файл в другой раздел, от имени пользователя root, отредактируйте файл конфигурации /etc/kdump.conf, как описано ниже.

  1. Удалите знак решетки (" #") в начале #ext4 строки, в зависимости от выбора:

  • имени устройства ( #ext4 /dev/vg/lv_kdump строка)

  • метки файловой системы ( #ext4 LABEL=/boot строка)

  • UUID (#ext4 UUID=03138356-5e61-4ab3-b58e-27507ac41937 строка)

  • записи аварийного dump непосредственно на устройство, для этого отредактируйте /etc/kdump.conf файл конфигурации:

    • Удалите знак решетки (#) в начале #raw /dev/vg/lv_kdump строки.

    • Замените значение предполагаемым именем устройства. Например:


raw /dev/sdb1

  • Чтобы сохранить аварийный dump на удаленной машине с использованием NFS протокола, отредактируйте /etc/kdump.conf файл конфигурации:

    • Удалите знак решетки (#) в начале #nfs my.server.com:/export/tmp строки.

    • Замените значение допустимым именем хоста и путем к каталогу. Например:


nfs penguin.example.ru:/export/cores

  • Чтобы сохранить аварийный dump на удаленной машине с использованием SSH протокола, отредактируйте /etc/kdump.conf файл конфигурации:

    • Удалите знак решетки ("#") в начале строки #ssh user@my.server.com.

    • Замените значение допустимым именем пользователя и именем хоста.

    • Включите свой SSH ключ в конфигурацию.

  • Удалите знак решетки с начала #sshkey /root/.ssh/kdump_id_rsa строки.

    • Измените значение на расположение ключа, действительного на сервере, на который выполняется dump. Например:


ssh john@penguin.example.ru
sshkey /root/.ssh/mykey

Настройка сборщика ядер kdump#

Служба kdump использует core_collector программу для захвата образа аварийного dump. В SberLinux makedumpfile утилита является основным сборщиком по умолчанию. Это помогает уменьшить файл dump:

  • сжатие размера файла аварийного dump и копирование только необходимых страниц с использованием различных уровней dump;

  • исключение ненужных страниц аварийного dump;

  • фильтрация типов страниц для включения в аварийный dump.

Синтаксис:


core_collector makedumpfile -l --message-level 1 -d 31

Опции:

  • -c, -lили -p: укажите формат файла dump сжатия для каждой страницы, используя zlib для -c опции, lzo для -l опции или snappy для -p опции.

  • -d (dump_level): исключает страницы, чтобы они не копировались в файл dump.

  • –message-level: укажите типы сообщений. Можно ограничить вывод на печать, указав message_level эту опцию. Например, если указать 7 как, message_level будут напечатаны общие сообщения и сообщения об ошибках. Максимальное значение message_level- 31

Предварительные условия:

  • Права root пользователя.

  • Выполнены требования к kdump конфигурациям и целям.

Процедура:

  1. Как пользователь root, отредактируйте /etc/kdump.conf файл конфигурации и удалите знак решетки (#) в начале файла #core_collector makedumpfile -l --message-level 1 -d 31.

  2. Чтобы включить сжатие файла аварийного dump, выполните:


core_collector makedumpfile -l --message-level 1 -d 31

Параметр -l указывает dump формат сжатого файла. Параметр -d указывает уровень dump как 31. Параметр –message-level указывает уровень сообщения как 1.

Кроме того, рассмотрите следующие примеры с опциями -c и -p:

  • Чтобы сжать файл аварийного dump, используйте -c:


core_collector makedumpfile -c -d 31 --message-level 1

  • Чтобы сжать файл аварийного dump, используйте -p:


core_collector makedumpfile -p -d 31 --message-level 1

Настройка реакции kdump на сбой по умолчанию#

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

Предварительные условия:

  • Права root пользователя.

  • Выполнены требования к kdump конфигурациям и целям.

Процедура:

  1. Как пользователь root, удалите знак решетки (" #") в начале #failure_action строки в /etc/kdump.conf файле конфигурации.

  2. Замените значение желаемым действием.


failure_action poweroff

Файл конфигурации для kdump#

Файл конфигурации для kdump ядра /etc/sysconfig/kdump. Этот файл управляет параметрами kdump командной строки ядра.

Для большинства конфигураций используйте параметры по умолчанию. Однако в некоторых сценариях может потребоваться изменить определенные параметры для управления kdump поведением ядра. Например, изменение для добавления kdump командной строки ядра для получения подробного вывода отладки.

В этом разделе содержится информация об изменении параметров KDUMP_COMMANDLINE_REMOVE и KDUMP_COMMANDLINE_APPEND для kdump. Информацию о дополнительных параметрах конфигурации см. в файле /etc/sysconfig/kdump.

KDUMP_COMMANDLINE_REMOVE

Эта опция удаляет аргументы из текущей kdump командной строки. Опция удаляет параметры, которые могут вызвать kdump ошибки или kdump сбои при загрузке ядра. Эти параметры могли быть проанализированы из предыдущего KDUMP_COMMANDLINE процесса или унаследованы от /proc/cmdline файла. Когда эта переменная не настроена, она наследует все значения из /proc/cmdline файла. Настройка этого параметра также предоставляет информацию, полезную при отладке проблемы.

Тестирование конфигурации kdump#

Можно проверить, что процесс аварийного dump работает и действителен.

Предупреждение: Приведенные ниже команды вызывают сбой ядра. Соблюдайте осторожность при выполнении этих шагов и никогда не применяйте их небрежно в активной производственной системе.

Процедура:

  1. Перезагрузите систему с kdump включенным.

  2. Убедитесь, что kdump запущен:


**# systemctl is-active kdump**
active

  1. Принудительный сбой ядра Linux:


echo 1 > /proc/sys/kernel/sysrq

echo c > /proc/sysrq-trigger

Предупреждение: Приведенная выше команда приводит к сбою ядра, требуется перезагрузка.

После повторной загрузки файл с адресом address-YYYY-MM-DD-HH:MM:SS/vmcore создается в месте, которое указано в файле /etc/kdump.conf(по умолчанию /var/crash/).

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

Включение kdump#

Можно включить и запустить kdump службу для всех ядер, установленных на машине.

Включение kdump для всех установленных ядер#

Предварительные условия:

Права администратора

Процедура:

  1. Добавьте параметр командной строки crashkernel=auto ко всем установленным ядрам:


# grubby --update-kernel=ALL --args="crashkernel=auto"

  1. Включите kdump службу.


# systemctl enable --now kdump.service

Проверка:

Убедитесь, что kdump служба запущена:


# systemctl status kdump.service

○ kdump.service - Crash recovery kernel arming
Loaded: loaded (/usr/lib/systemd/system/kdump.service; enabled; vendor preset: disabled)
Active: active (live)

Включение kdump для определенного установленного ядра#

Можно включить kdump службу для определенного ядра на машине.

Предварительные условия:

Права администратора

Процедура:

  1. Перечислите ядра, установленные на машине.


# ls -a /boot/vmlinuz-

/boot/vmlinuz-0-rescue-2930657cd0dc43c2b75db480e5e5b4a9 /boot/vmlinuz-4.18.0-330.el8.x86_64 /boot/vmlinuz-4.18.0-330.rt7.111.el8 .x86_64

  1. Добавьте конкретное kdump ядро в системный файл конфигурации Grand Unified Bootloader (GRUB). Например:


# grubby --update-kernel=vmlinuz-4.18.0-330.el8.x86_64 --args="crashkernel=auto"

  1. Включите kdump службу.


# systemctl enable --now kdump.service

Проверка:

Убедитесь, что kdump служба запущена:


# systemctl status kdump.service

○ kdump.service - Crash recovery kernel arming
Loaded: loaded (/usr/lib/systemd/system/kdump.service; enabled; vendor preset: disabled)
Active: active (live)

Отключение службы kdump#

Чтобы отключить kdump службу во время загрузки, выполните описанную ниже процедуру.

Предварительные условия:

  • Выполнены требования к kdump конфигурациям и целям.

  • Все конфигурации для установки kdump настроены в соответствии с потребностями. Дополнительные сведения см. в разделе «Установка kdump».

Процедура:

  1. Чтобы остановить kdump службу в текущем сеансе:


# systemctl stop kdump.service

  1. Чтобы отключить kdump службу:


# systemctl disable kdump.service

Предупреждение: Рекомендуется установить kptr_restrict=1. В этом случае служба kdumpctl загружает аварийное ядро независимо от того, включено или нет расположение адресного пространства ядра (KASLR).

Устранение неполадок:

Когда для kptr_restrict не установлено значение (1) и если KASLR включен, содержимое файла /proc/kcore генерируется как все нули. Следовательно, служба kdumpctl не может получить доступ к /proc/kcore и загрузить аварийное ядро.

Чтобы обойти эту проблему, в файле /usr/share/doc/kexec-tools/kexec-kdump-howto.txt отображается предупреждающее сообщение, в котором рекомендуется параметр kptr_restrict=1.

Чтобы убедиться, что служба kdumpctl загружает аварийное ядро, убедитесь, что в файле sysctl.conf указано значение kernel.kptr_restrict = 1.

Поддерживаемые конфигурации и цели kdump#

Требования к памяти для kdump#

Чтобы kdump можно было захватить dump сбоя ядра и сохранить его для дальнейшего анализа, часть системной памяти должна быть постоянно зарезервирована для ядра захвата. Зарезервированная часть системной памяти недоступна основному ядру.

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

Таблица. Минимальный объем зарезервированной памяти, необходимый для kdump

Доступная память

Минимальная зарезервированная память

от 1 ГБ до 4 ГБ

160 Мбайт оперативной памяти.

от 4 ГБ до 64 ГБ

192 Мбайт оперативной памяти.

от 64 ГБ до 1 ТБ

256 Мбайт оперативной памяти.

1 ТБ и более

512 Мбайт оперативной памяти

На многих системах kdump умеет оценивать объем требуемой памяти и автоматически резервировать ее. Это поведение включено по умолчанию, но работает только в системах с более чем определенным объемом доступной памяти.

Примечание: Автоматическая конфигурация зарезервированной памяти на основе общего объема памяти в системе — это наилучшая оценка. Фактический требуемый объем памяти может варьироваться в зависимости от других факторов, таких как устройства ввода-вывода. Использование недостаточного количества памяти может привести к тому, что ядро отладки не сможет загрузиться как ядро захвата в случае Kernel panic (критической ошибки ядра). Чтобы избежать этой проблемы, достаточно увеличить память аварийного ядра.

Минимальный порог для автоматического резервирования памяти#

В некоторых системах возможно выделение памяти kdump автоматически, либо с помощью crashkernel=auto параметра в файле конфигурации загрузчика, либо путем включения этой опции в графической утилите настройки. Чтобы это автоматическое резервирование работало, в системе должен быть доступен определенный объем общей памяти.

Для x86_64 архитектуры пороговое значение для автоматического выделения памяти - 2 Гбайта. Если в системе имеется память меньше указанного порогового значения, необходимо настроить память вручную.

Поддерживаемые цели kdump#

Когда фиксируется сбой ядра, файл vmcore для dump может быть записан непосредственно на устройство, сохранен в виде файла в локальной файловой системе или отправлен по сети. В приведенной ниже таблице содержится полный список целей dump, которые в настоящее время поддерживаются или явно не поддерживаются kdump.

Тип

Поддерживаемые цели

Неподдерживаемые цели

Необработанное устройство

Все локально подключенные необработанные диски и разделы

Локальная файловая система

ext4 файловая система на напрямую подключенных дисках, аппаратных логических дисках RAID, устройствах LVM и mdraid массивах

Любая локальная файловая система, явно не указанная в этой таблице как поддерживаемая, включая auto тип (автоматическое определение файловой системы)

Удаленный каталог

Удаленные каталоги, доступ к которым осуществляется по протоколу NFS или SSH через IPv4

Удаленные каталоги в rootfs файловой системе, доступ к которым осуществляется по NFS протоколу

Доступ к удаленным каталогам осуществляется с использованием iSCSI протокола через аппаратные и программные инициаторы

Доступ к удаленным каталогам осуществляется с использованием iSCSI протокола на be2iscsi оборудовании

multipath-based хранилища

Доступ к удаленным каталогам через IPv6

Удаленные каталоги, доступ к которым осуществляется с использованием протокола SMB или CIFS

Доступ к удаленным каталогам осуществляется по протоколу FCoE (Fiber Channel over Ethernet)

Удаленные каталоги, доступ к которым осуществляется через беспроводные сетевые интерфейсы

Примечание: Использование встроенного dump (fadump) для захвата vmcore и его сохранения на удаленном компьютере с использованием протокола SSH или NFS приводит к переименованию сетевого интерфейса в kdump-. Переименование происходит, если является общим, например *eth#, net# и т. д. Эта проблема возникает из-за того, что сценарии захвата vmcore на начальном RAM-диске (initrd) добавляют префикс kdump- к имени сетевого интерфейса для обеспечения постоянного именования. Поскольку тот же самый initrd используется и для обычной загрузки, имя интерфейса изменено и для производственного ядра.

Поддерживаемые уровни фильтрации kdump#

Чтобы уменьшить размер файла dump, kdump использует основной сборщик makedumpfile для сжатия данных и, при необходимости, для исключения нежелательной информации. В приведенной ниже таблице содержится полный список уровней фильтрации, которые в настоящее время поддерживаются утилитой makedumpfile.

Вариант

Описание

1

Нулевые страницы

2

кеш страниц

4

кеш приватный

8

Пользовательские страницы

16

Свободные страницы

Примечание: Команда makedumpfile поддерживает удаление прозрачных огромных страниц и страниц hugetlbfs. Рассмотрите типы пользовательских страниц огромных страниц и удалите их, используя уровень -8.

Поддерживаемые ответы на ошибки по умолчанию#

По умолчанию, когда kdump не может создать dump ядра, операционная система перезагружается. Однако можно настроить kdump на выполнение другой операции в случае, если ему не удастся сохранить dump ядра в первичную цель. В таблицах ниже перечислены все действия по умолчанию, которые в настоящее время поддерживаются.

Вариант

Описание

dump_to_rootfs

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

reboot

Перезагрузите систему, потеряв при этом dump ядра.

halt

Остановите систему, потеряв при этом dump ядра.

poweroff

Выключите систему, потеряв при этом dump ядра.

shell

Запустите сеанс оболочки из initramfs, что позволит пользователю вручную записать dump ядра.

final_action

Включите дополнительные операции, такие как reboot, halt и poweroff питания после успешного выполнения kdump или после завершения действия shell или dump_to_rootfs. Параметр final_action по умолчанию — reboot.

Использование параметра final_action#

Final_action параметр позволяет использовать некоторые дополнительные операции, такие как reboot, halt и poweroff после успешного kdump или после завершения вызванного механизма failure_response с использованием shell или dump_to_rootfs. Если final_action параметр не указан, по умолчанию используется reboot.

Процедура:

  1. Отредактируйте `/etc/kdump.confфайл и добавьте final_action параметр.


final_action <reboot | halt | poweroff>

  1. Перезапустите kdump службу:


kdumpctl restart

Установка лимитов для приложений#

Можно использовать функциональные возможности ядра групп управления (cgroups) для установки ограничений, определения приоритетов или изоляции аппаратных ресурсов процессов. Это позволяет детально контролировать использование ресурсов приложениями, чтобы использовать их более эффективно.

Общие сведения о контрольных группах#

Группы управления — это функция ядра Linux, которая позволяет организовывать процессы в иерархически упорядоченные группы — cgroups. Иерархия (дерево групп управления) определяется путем предоставления структуры виртуальной файловой системе cgroups, смонтированной по умолчанию в каталоге /sys/fs/cgroup/. Диспетчер систем и служб systemd использует cgroups для организации всех модулей и служб, которыми он управляет. Кроме того, можно вручную управлять иерархиями cgroups, создавая и удаляя подкаталоги в каталоге /sys/fs/cgroup/.

Контроллеры ресурсов (компонент ядра) затем изменяют поведение процессов в cgroups, ограничивая, расставляя приоритеты или распределяя системные ресурсы (такие, как процессорное время, память, пропускная способность сети или различные комбинации) этих процессов.

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

Группы управления версия 1

Группы управления версии 1 (cgroups-v1) обеспечивают иерархию контроллеров для каждого ресурса. Это означает, что каждый ресурс, такой как ЦП, память, ввод-вывод и т. д., имеет свою собственную иерархию групп управления. Можно комбинировать различные иерархии групп управления таким образом, чтобы один контроллер мог координировать свои действия с другим при управлении соответствующими ресурсами. Однако два контроллера могут принадлежать к разным иерархиям процессов, что не позволяет обеспечить их надлежащую координацию.

Контроллеры cgroups-v1 разрабатывались в течение большого промежутка времени, и в результате поведение и имена их управляющих файлов неодинаковы.

Группы управления версия 2

Проблемы с координацией контроллеров, возникшие из-за гибкости иерархии, привели к разработке групп управления версии 2.

Группа управления версии 2 (cgroups-v2) обеспечивает единую иерархию группы управления, в которой монтируются все контроллеры ресурсов.

Поведение управляющего файла и его наименование одинаковы для разных контроллеров.

Формат вывода cgroups и irqs для обеспечения лучшей читаемости выводом команд tuna show_threads для утилиты cgroup структурирован в зависимости от размера терминала. Также можно настроить дополнительные интервалы между выводимыми данными cgroups, добавив в -z команду параметр new --spaced или show_threads. В результате можно просматривать выходные данные cgroups в удобочитаемом формате, который можно адаптировать к размеру терминала.

Контроллеры ресурсов ядра#

Функциональность контрольных групп обеспечивается контроллерами ресурсов ядра. SberLinux поддерживает различные контроллеры для контрольных групп версии 1 (cgroups-v1) и контрольных групп версии 2 (cgroups-v2).

Контроллер ресурсов, также называемый подсистемой группы управления, представляет собой подсистему ядра, представляющую один ресурс, такой как процессорное время, память, пропускная способность сети или дисковый ввод-вывод. Ядро Linux предоставляет ряд контроллеров ресурсов, которые автоматически монтируются системой systemd и диспетчером служб. Найдите список смонтированных в данный момент контроллеров ресурсов в /proc/cgroups файле.

Доступны следующие контроллеры cgroups-v1:

  • blkio - может устанавливать ограничения на доступ ввода/вывода к блочным устройствам и от них.

  • cpu- может настраивать параметры планировщика Completely Fair Scheduler (CFS) для задач контрольной группы. Монтируется вместе со cpuacct контроллером на одном креплении.

  • cpuacct - создает автоматические отчеты по ресурсам процессора, используемым задачами в контрольной группе. Монтируется вместе со cpu контроллером на одном креплении.

  • cpuset - может использоваться для ограничения задач группы управления только на указанном подмножестве ЦП и указания задачам использовать память только на указанных узлах памяти.

  • devices - может контролировать доступ к устройствам для задач в группе управления.

  • freezer - может использоваться для приостановки или возобновления задач в контрольной группе.

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

  • net_cls - может помечать сетевые пакеты идентификатором класса (classid), что позволяет контроллеру трафика Linux ( tc команде) идентифицировать пакеты, исходящие от конкретной задачи группы управления. Подсистема net_cls.

  • net_filter iptables - может использовать этот тег для выполнения действий с такими пакетами. Сетевые сокеты net_filter помечаются идентификатором межсетевого экрана (fwid), который позволяет межсетевому экрану Linux (через iptables команду) идентифицировать пакеты, исходящие от конкретной задачи группы управления.

  • net_prio - может устанавливать приоритет сетевого трафика.

  • pids - может устанавливать лимиты на количество процессов и их потомков в контрольной группе.

  • perf_event - может группировать задачи для мониторинга с помощью perf утилиты мониторинга производительности и создания отчетов.

  • rdma - может устанавливать ограничения на определенные ресурсы Remote Direct Memory Access/InfiniBand в контрольной группе.

  • hugetlb - может использоваться для ограничения использования страниц виртуальной памяти большого размера задачами в контрольной группе.

Доступны следующие контроллеры cgroups-v2:

  • io - Продолжение blkio из cgroups-v1;

  • memory - Продолжение memory из cgroups-v1;

  • pids - То же, что и pids из cgroups-v1;

  • rdma - То же, что и rdma из cgroups-v1;

  • cpu - Продолжение cpu и cpuacct из cgroups-v1;

  • cpuset - Поддерживает только основные функции(cpus{,.effective}, mems{,.effective}) с новой функцией разделов;

  • perf_event - Встроенная поддержка, нет явного управляющего файла. Можно указать v2 cgroupв качестве параметра perf команды, которая будет профилировать все задачи в этом файле cgroup.

Пространства имен#

Пространства имен — один из наиболее важных методов организации и идентификации программных объектов.

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

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

Чтобы проверить, членом каких пространств имен является процесс, Можно проверить символические ссылки в каталоге /proc//ns/.

В следующей таблице показаны поддерживаемые пространства имен и ресурсы, которые они изолируют:

Пространство имен

Ресурсы

Mount

Точки монтирования

UTS

Имя хоста и доменное имя NIS

IPC

System V IPC, очереди сообщений POSIX

PID

Идентификаторы процессов

Network

Сетевые устройства, стеки, порты и т. д.

User

Идентификаторы пользователей и групп

Control groups

Корневой каталог группы управления

Установка ограничений ЦП для приложений с помощью cgroups-v1#

Иногда приложение потребляет много процессорного времени, что может негативно сказаться на общем состоянии среды. Используйте виртуальную файловую систему /sys/fs/, чтобы настроить ограничения ЦП для приложения с помощью контрольных групп версии 1 (cgroups-v1).

Предварительные условия:

  • Права root пользователя.

  • Существует приложение, потребление ЦП которого нужно ограничить.

  • Контроллеры службы смонтированы.


# mount -l | grep cgroup
tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,seclabel,mode=755)
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,cpu,cpuacct)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,perf_event)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,pids)
...

Процедура:

  1. Определите идентификатор процесса (PID) приложения, которое необходимо ограничить потреблением ЦП:


# top
top - 12:28:42 up  1:06,  1 user,  load average: 1.02, 1.02, 1.00
Tasks: 266 total,   6 running, 260 sleeping,   0 stopped,   0 zombie
%Cpu(s): 11.0 us,  1.2 sy,  0.0 ni, 87.5 id,  0.0 wa,  0.2 hi,  0.0 si,  0.2 st
MiB Mem :   1826.8 total,    287.1 free,   1054.4 used,    485.3 buff/cache
MiB Swap:   1536.0 total,   1396.7 free,    139.2 used.    608.3 avail Mem

    PID USER      PR  NI        VIRT        RES     SHR   S  %CPU  %MEM      TIME+    COMMAND
 6955   root      20   0   228440       1752     1472  R     20.6          0.1  47:11.43    sha1sum
 5760   jdoe      20   0 3604956 208832   65316 R        2.3        11.2   0:43.50    gnome-shell
 6448  jdoe      20   0    743836     31736  19488 S        0.7          1.7   0:08.25    gnome-terminal-
   505   root      20   0               0             0          0   I        0.3          0.0   0:03.39    kworker/u4:4-events_unbound
 4217   root      20   0       74192        1612    1320  S       0.3           0.1   0:01.19     spice-vdagentd
...

Пример вывода top программы показывает, что PID 6955 (иллюстративное приложение sha1sum) потребляет много ресурсов ЦП.

  1. Создайте подкаталог в каталоге cpu контроллера ресурсов:


# mkdir /sys/fs/cgroup/cpu/Example/

Вышеупомянутый каталог представляет собой группу управления, в которую нужно поместить определенные процессы и применить к ним определенные ограничения ЦП. В то же время в каталоге будут созданы некоторые файлы интерфейса cgroups-v1 и файлы, относящиеся к контроллеру cpu.

  1. Настройте лимиты cpu для контрольной группы:


# ll /sys/fs/cgroup/cpu/Example/

-rw-r—r--. 1 root root 0 Mar 11 11:42 cgroup.clone_children
-rw-r—r--. 1 root root 0 Mar 11 11:42 cgroup.procs
-r—r—r--. 1 root root 0 Mar 11 11:42 cpuacct.stat
-rw-r—r--. 1 root root 0 Mar 11 11:42 cpuacct.usage
-r—r—r--. 1 root root 0 Mar 11 11:42 cpuacct.usage_all
-r—r—r--. 1 root root 0 Mar 11 11:42 cpuacct.usage_percpu
-r—r—r--. 1 root root 0 Mar 11 11:42 cpuacct.usage_percpu_sys
-r—r—r--. 1 root root 0 Mar 11 11:42 cpuacct.usage_percpu_user
-r—r—r--. 1 root root 0 Mar 11 11:42 cpuacct.usage_sys
-r—r—r--. 1 root root 0 Mar 11 11:42 cpuacct.usage_user
-rw-r—r--. 1 root root 0 Mar 11 11:42 cpu.cfs_period_us
-rw-r—r--. 1 root root 0 Mar 11 11:42 cpu.cfs_quota_us
-rw-r—r--. 1 root root 0 Mar 11 11:42 cpu.rt_period_us
-rw-r—r--. 1 root root 0 Mar 11 11:42 cpu.rt_runtime_us
-rw-r—r--. 1 root root 0 Mar 11 11:42 cpu.shares
-r—r—r--. 1 root root 0 Mar 11 11:42 cpu.stat
-rw-r—r--. 1 root root 0 Mar 11 11:42 notify_on_release
-rw-r—r--. 1 root root 0 Mar 11 11:42 tasks

Файл cpu.cfs_period_us представляет собой период времени в микросекундах (мкс, представленный здесь как нас) для того, как часто должен перераспределяться доступ контрольной группы к ресурсам ЦП. Верхний предел составляет 1 секунду, а нижний предел — 1000 микросекунд.

Файл cpu.cfs_quota_us представляет собой общее количество времени в микросекундах, в течение которого все процессы в группе управления могут выполняться в течение одного периода (как определено параметром cpu.cfs_period_us). Как только процессы в контрольной группе в течение одного периода израсходуют все время, указанное в квоте, они будут регулироваться на оставшуюся часть периода, и им не разрешается выполняться до следующего периода. Нижний предел составляет 1000 микросекунд.

Приведенные выше примеры команд устанавливают ограничения времени ЦП, чтобы все процессы в совокупности в Example группе управления могли работать только в течение 0,2 секунды (определяется cpu.cfs_quota_us) из каждой 1 секунды (определяется cpu.cfs_period_us).

  1. Добавьте PID приложения в Example группу управления:


# echo "6955" > /sys/fs/cgroup/cpu/Example/cgroup.procs

или


# echo "6955" > /sys/fs/cgroup/cpu/Example/tasks

Предыдущая команда гарантирует, что желаемое приложение станет членом Example контрольной группы и, следовательно, не превысит ограничения ЦП, настроенные для Example контрольной группы. PID должен представлять существующий процесс в системе. Здесь PID 6955 был назначен процессу sha1sum /dev/zero &, используемый для иллюстрации варианта использования cpu контроллера.

  1. Убедитесь, что приложение работает в указанной группе управления:


# cat /proc/6955/cgroup

12:cpuset:/
11:hugetlb:/
10:net_cls,net_prio:/
9:memory:/user.slice/user-1000.slice/user@1000.service
8:devices:/user.slice
7:blkio:/
6:freezer:/
5:rdma:/
4:pids:/user.slice/user-1000.slice/user@1000.service
3:perf_event:/
2:cpu,cpuacct:/Example
1:name=systemd:/user.slice/user-1000.slice/user@1000.service/terminal-server.service

В приведенном выше примере выходных данных показано, что процесс нужного приложения выполняется в группе управления Example, которая применяет ограничения cpu к процессу приложения.

  1. Определите текущее потребление cpu регулируемым приложением:


# top
top - 12:28:42 up  1:06,  1 user,  load average: 1.02, 1.02, 1.00
Tasks: 266 total,   6 running, 260 sleeping,   0 stopped,   0 zombie
%Cpu(s): 11.0 us,  1.2 sy,  0.0 ni, 87.5 id,  0.0 wa,  0.2 hi,  0.0 si,  0.2 st
MiB Mem :   1826.8 total,    287.1 free,   1054.4 used,    485.3 buff/cache
MiB Swap:   1536.0 total,   1396.7 free,    139.2 used.    608.3 avail Mem

    PID USER      PR  NI        VIRT        RES     SHR   S  %CPU  %MEM      TIME+    COMMAND
 6955   root      20   0   228440       1752     1472  R     20.6          0.1  47:11.43    sha1sum
 5760   jdoe      20   0 3604956 208832   65316 R        2.3        11.2   0:43.50    gnome-shell
 6448  jdoe      20   0    743836     31736  19488 S        0.7          1.7   0:08.25    gnome-terminal-
   505   root      20   0               0             0          0   I        0.3          0.0   0:03.39    kworker/u4:4-events_unbound
 4217   root      20   0       74192        1612    1320  S       0.3           0.1   0:01.19     spice-vdagentd
...

Обратите внимание, что потребление ЦП PID 6955уменьшилось с 99% до 20%.

Примечание: Аналогом cgroups-v2 для cpu.cfs_period_us и cpu.cfs_quota_us является cpu.max файл. Файл cpu.max доступен через cpu контроллер.

Команда rteval#

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

Отчет rteval записывается в XML-файл вместе с журналом загрузки системы и сохраняется в сжатом файле rteval--N-tar.bz2. Где date указывает дату создания отчета и N является счетчиком для N-го запуска.

Чтобы сгенерировать отчет rteval, введите следующую команду:


# rteval --summarize rteval-<date>-N.tar.bz2

Настройка политик CPU Affinity и NUMA с помощью systemd#

Параметры управления ЦП, управления памятью и пропускной способности ввода-вывода связаны с разделением доступных ресурсов.

Настройка привязки ЦП с помощью systemd#

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

Маска привязки ЦП по умолчанию применяется ко всем службам, управляемым systemd.

Чтобы настроить маску соответствия ЦП для конкретной службы systemd, systemd предоставляет CPUAffinity= как параметр файла модуля, так и параметр конфигурации менеджера в файле /etc/systemd/system.conf.

Параметр файла модуля CPUAffinity= задает список ЦП или диапазонов ЦП, которые объединяются и используются в качестве маски сходства. Параметр CPUAffinity в файле /etc/systemd/system.conf определяет маску сходства для процесса с идентификационным номером (PID) 1 и всех процессов, ответвленных от PID1. Затем нужно переопределить CPUAffinity для каждой службы.

Примечание: После настройки маски соответствия ЦП для конкретной службы systemdнеобходимо перезапустить систему, чтобы изменения вступили в силу.

Процедура:

Чтобы установить маску привязки ЦП для конкретной службы systemd, используя параметр файла модуля CPUAffinity:

  1. Проверьте значения параметра файла модуля CPUAffinity в выбранном сервисе:


$ systemctl show --property <CPU affinity configuration option> <service name>

  1. В качестве пользователя root установите требуемое значение параметра файла модуля CPUAffinity для диапазонов ЦП, используемых в качестве маски сходства:


# systemctl set-property <service name> CPUAffinity=<value>

  1. Перезапустите службу, чтобы применить изменения.


# systemctl restart <service name>

Чтобы установить маску соответствия ЦП для конкретной службы systemd, используя параметр конфигурации менеджера:

  1. Отредактируйте файл /etc/systemd/system.conf:


# vi /etc/systemd/system.conf

  1. Найдите параметр CPUAffinity= и установите номера процессоров.

  2. Сохраните отредактированный файл и перезапустите сервер, чтобы изменения вступили в силу.

Настройка политик NUMA с помощью systemd#

Non-uniform memory access (NUMA) — это конструкция подсистемы памяти компьютера, в которой время доступа к памяти зависит от расположения физической памяти относительно процессора.

Память, близкая к ЦП, имеет меньшую задержку (локальная память), чем память, локальная для другого ЦП (внешняя память) или совместно используемая набором ЦП.

Что касается ядра Linux, политика NUMA определяет, где (например, на каких узлах NUMA) ядро выделяет страницы физической памяти для процесса.

systemd предоставляет параметры файла модуля NUMAPolicy и NUMAMask для управления политиками выделения памяти для служб.

Процедура:

Чтобы установить политику памяти NUMA с помощью параметра файла модуля NUMAPolicy:

  1. Проверьте значения параметра файла модуля NUMAPolicy в выбранном сервисе:


$ systemctl show --property <NUMA policy configuration option> <service name>

  1. В качестве пользователя root установите требуемый тип политики в параметре модуля NUMAPolicy:


# systemctl set-property <service name> NUMAPolicy=<value>

  1. Перезапустите службу, чтобы применить изменения.


# systemctl restart <service name>

Чтобы установить глобальный параметр NUMAPolicy с помощью параметра конфигурации менеджера:

  1. Найдите в файле /etc/systemd/system.conf параметр NUMAPolicy.

  2. Измените тип политики, сохраните файл.

  3. Перезагрузите конфигурацию systemd службы:


# systemd daemon-reload

  1. Перезагрузите сервер.

Предупреждение: При настройке строгой политики NUMA, например bind, убедитесь, что также правильно установлен параметр файла модуля CPUAffinity=.

Параметры конфигурации политики NUMA для systemd#

Systemd предоставляет следующие параметры для настройки политики NUMA:

NUMAPolicy Управляет политикой памяти NUMA исполняемых процессов. Возможны следующие типы политик:

  • default;

  • preferred;

  • bind;

  • interleave;

  • local.

NUMAMask Управляет списком узлов NUMA, связанным с выбранной политикой NUMA.

Обратите внимание, что параметр NUMAMask не требуется указывать для следующих политик:

  • default;

  • local.

Для предпочтительной политики в списке указан только один узел NUMA.

Повышение безопасности с помощью подсистемы целостности ядра#

Можно усилить защиту своей системы, используя компоненты подсистемы целостности ядра. В следующих разделах представлены соответствующие компоненты и даны рекомендации по их настройке.

Подсистема целостности ядра#

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

Подсистема целостности ядра может использовать доверенный платформенный модуль (TPM), чтобы повысить безопасность системы. TPM — это спецификация Trusted Computing Group (TCG) для важных криптографических функций. Модули TPM обычно представляют собой специальное аппаратное обеспечение, которое подключается к материнской плате платформы и предотвращает программные атаки, предоставляя криптографические функции из защищенной и защищенной от несанкционированного доступа области аппаратного чипа. Некоторые из функций TPM:

  • Генератор случайных чисел;

  • Генератор и безопасное хранилище криптографических ключей;

  • хеш-генератор;

  • Удаленная аттестация.

Надежные и зашифрованные ключи#

В следующем разделе представлены доверенные и зашифрованные ключи как важная часть повышения безопасности системы.

Надежные и зашифрованные ключи — это симметричные ключи переменной длины, сгенерированные ядром, которые используют службу набора ключей ядра. Тот факт, что этот тип ключей никогда не появляется в пользовательском пространстве в незашифрованном виде, означает, что их целостность может быть проверена. Программы пользовательского уровня могут получить доступ к ключам только в виде зашифрованных больших двоичных объектов.

Для доверенных ключей требуется аппаратный компонент: микросхема доверенного платформенного модуля (Trusted Platform Module (TPM)), которая используется как для создания, так и для шифрования (запечатывания) ключей. Доверенный платформенный модуль запечатывает ключи с помощью 2048-битного ключа RSA, называемого корневым ключом хранилища (storage root key (SRK)).

Примечание: Чтобы использовать спецификацию TPM 1.2, включите и активируйте ее с помощью параметра микропрограммы машины или с помощью команды tpm_setactive из пакета утилит tpm-tools. Кроме того, необходимо установить программный стек TrouSers и запустить демон tcsd для связи с TPM (выделенным оборудованием). Демон tcsd является частью пакета TrouSers, который доступен в пакете TrouSers. В более позднем и обратно несовместимом TPM 2.0 используется другой программный стек, в котором утилиты tpm2-tools или ibm-tss предоставляют доступ к выделенному оборудованию.

Кроме того, пользователь может запечатать доверенные ключи с помощью набора значений для регистра конфигурации платформы (platform configuration register (PCR)) TPM. PCR содержит набор значений управления целостностью, которые отражают встроенное ПО, загрузчик и операционную систему. Это означает, что ключи, запечатанные PCR, могут быть расшифрованы доверенным платформенным модулем только в той же системе, в которой они были зашифрованы. Однако, как только доверенный ключ, запечатанный PCR, загружен (добавлен в связку ключей) и, таким образом, проверены связанные с ним значения PCR, он может быть обновлен новыми (или будущими) значениями PCR, так что новое ядро, например, может быть загруженным. Один ключ также можно сохранить в виде нескольких больших двоичных объектов, каждый из которых имеет разные значения PCR.

Зашифрованные ключи не требуют доверенного платформенного модуля, поскольку они используют расширенный стандарт шифрования ядра (Advanced Encryption Standard (AES)), что делает их быстрее, чем доверенные ключи. Зашифрованные ключи создаются с использованием случайных чисел, сгенерированных ядром, и шифруются главным ключом при экспорте в большие двоичные объекты пользовательского пространства. Главный ключ — это либо доверенный ключ, либо пользовательский ключ. Если мастер-ключ не является доверенным, зашифрованный ключ безопасен настолько, насколько безопасен пользовательский ключ, используемый для его шифрования.

Работа с доверенными ключами#

В следующем разделе описывается, как создавать, экспортировать, загружать или обновлять доверенные ключи с помощью утилиты keyctl для повышения безопасности системы.

Предварительные условия:

  • Необходимо загрузить доверенный модуль ядра. Дополнительные сведения о загрузке модулей ядра см. в разделе «Управление модулями ядра».

  • Доверенный платформенный модуль (TPM) должен быть включен и активен. Дополнительные сведения о TPM см. в разделах "Подсистема целостности ядра" и «Доверенные и зашифрованные ключи».

Процедура:

  1. Чтобы создать доверенный ключ с помощью TPM, выполните:


# keyctl **Add** trusted <name> "new <key_length> [options]" <key_ring>

  • На основе синтаксиса создайте пример команды следующим образом:


# keyctl **Add** trusted kmk "new 32" @u

642500861

Команда создает доверенный ключ kmk длиной 32 байта (256 бит) и помещает его в связку ключей пользователя (@u). Ключи могут иметь длину от 32 до 128 байт (от 256 до 1024 бит).

  • Чтобы просмотреть текущую структуру связок ключей ядра:


# keyctl show

Session Keyring
-3 --alswrv 500 500 keyring: ses 97833714 --alswrv 500 -1 \ keyring: uid.1000 642500861 --alswrv 500 500 \ trusted: kmk

  • Чтобы экспортировать ключ в большой двоичный объект пользовательского пространства, выполните:


# keyctl pipe 642500861 > kmk.blob

Команда использует pipe подкоманду и серийный номер файла kmk.

  • Чтобы загрузить доверенный ключ из большого двоичного объекта пользовательского пространства, используйте add подкоманду с большим двоичным объектом в качестве аргумента:


# keyctl **Add** trusted kmk "load `cat kmk.blob`" @u

268728824

  • Создайте безопасные зашифрованные ключи на основе доверенного ключа, запечатанного TPM:


# keyctl **Add** encrypted <pass:quotes[name]> "new [format] <pass:quotes[key_type]>:<pass:quotes[primary_key_name]> <pass:quotes[keylength]>" <pass:quotes[key_ring]>

  • На основе синтаксиса сгенерируйте зашифрованный ключ, используя уже созданный доверенный ключ:


# keyctl **Add** encrypted encr-key "new trusted:kmk 32" @u

159771175

Команда использует доверенный ключ, запечатанный TPM ( kmk), созданный на предыдущем шаге, в качестве первичного ключа для создания зашифрованных ключей.

Работа с зашифрованными ключами#

В следующем разделе описывается управление зашифрованными ключами для повышения безопасности в системах, в которых недоступен доверенный платформенный модуль (TPM).

Предварительные условия:

Необходимо загрузить encrypted-keys модуль ядра. Дополнительные сведения о загрузке модулей ядра см. в разделе «Управление модулями ядра».

Процедура:

  1. Используйте случайную последовательность чисел для генерации пользовательского ключа:


# keyctl **Add** user kmk-user "$(dd if=/dev/urandom bs=1 count=32 2>/dev/null)" @u

427069434

Команда генерирует пользовательский ключ с именем kmk-user, который действует как первичный ключ и используется для запечатывания фактических зашифрованных ключей.

  1. Сгенерируйте зашифрованный ключ, используя первичный ключ из предыдущего шага:


# keyctl **Add** encrypted encr-key "new user:kmk-user 32" @u

1012412758

  1. При необходимости перечислите все ключи в указанной связке ключей пользователя:


# keyctl list @u
2 keys in keyring:
427069434: --alswrv 1000 1000 user: kmk-user
1012412758: --alswrv 1000 1000 encrypted: encr-key

Примечание: Имейте в виду, что зашифрованные ключи, которые не запечатаны доверенным первичным ключом, настолько же безопасны, как первичный ключ пользователя (ключ со случайным числом) для их шифрования. Следовательно, первичный пользовательский ключ следует загружать как можно более надежно и предпочтительно в самом начале процесса загрузки.