Как проверить необходимость перезагрузки в Rocky и Alma
После выполнения dnf update старые библиотеки и ядро остаются в памяти. Используйте утилиту needs-restarting для выявления процессов, требующих перезапуска или перезагрузки ОС.
Какие обновления требуют перезагрузки в Rocky Linux и AlmaLinux
В Rocky Linux и AlmaLinux dnf update записывает новые файлы на диск и на этом завершает работу. Ядро, с которым вы загрузились, продолжает выполняться. Каждый процесс, который уже открыл библиотеку, продолжает использовать её копию, так как Linux сохраняет старый файл на диске до тех пор, пока его не закроет последний использующий его процесс. Поэтому система может сообщать об отсутствии доступных обновлений, продолжая при этом исполнять код, который был заменён этими обновлениями. В этом плане дистрибутивы не отличаются друг от друга, так как оба собираются из одних и тех же исходных кодов Red Hat, а выбор между Rocky и Alma зависит от гарантий совместимости и поддержки процессоров, а не от того, что вы увидите здесь. Приведённые ниже команды также идентичны тем, что использовались в CentOS, и это не совпадение: оба проекта были созданы как замена CentOS после анонса Stream в 2020 году.
Какие обновления требуют перезагрузки, а какие — только перезапуска сервисов, — это вопрос, который нужно задать самой системе. Команда, которая даёт ответ, — needs-restarting. Обновления делятся на три уровня. Ядро и небольшой список базовых пакетов требуют полной перезагрузки. Обычные обновления библиотек требуют перезапуска использующих их сервисов. Все остальные изменения применяются сразу же, как только завершается работа RPM.
Установка needs-restarting
needs-restarting — это плагин для DNF. Плагин поставляется в составе dnf-plugins-core, который уже присутствует в большинстве установок Rocky и Alma. Команда /usr/bin/needs-restarting представляет собой небольшую обертку, поставляемую в dnf-utils.
sudo dnf install -y dnf-utils
needs-restarting --helpОба варианта написания запускают один и тот же код, так как обертка вызывает подкоманду DNF:
needs-restarting -r
dnf needs-restarting -rОба пакета доступны в стандартных репозиториях дистрибутива, поэтому для этого не требуется включать EPEL или репозиторий CRB.
В линейке Rocky Linux 10 и AlmaLinux 10 dnf представляет собой DNF 5, а needs-restarting является одной из его встроенных команд из пакета dnf5-plugins. В этой версии dnf needs-restarting без дополнительных опций сразу выдает ответ о необходимости перезагрузки. Команда -r по-прежнему поддерживается, однако в руководстве указано, что она не выполняет никаких действий и сохранена только для совместимости со скриптами DNF 4.
Уровень 1: обновления, требующие перезагрузки
Сначала выполните проверку необходимости перезагрузки. Она считывает базу данных RPM и время загрузки системы, больше ничего, поэтому работает быстро и не требует прав root.
needs-restarting -rЕсли с момента загрузки не произошло важных изменений, утилита выводит две строки:
No core libraries or services have been updated since boot-up.
Reboot should not be necessary.Если изменения были, она выводит Core libraries or services have been updated since boot-up:, затем список найденных пакетов, а после этого:
Reboot is required to fully utilize these updates.
More information: https://access.redhat.com/solutions/27943Код завершения несет тот же смысл: 0, если перезагрузка не требуется, и 1, если требуется. Именно на этот код следует ориентироваться при написании скриптов.
if ! needs-restarting -r >/dev/null; then
logger -t updates "reboot pending on $(hostname -s)"
fiКод завершения 1 в данном случае — это нормальный ответ, а не ошибка. При использовании set -e необработанный needs-restarting -r прервет выполнение вашего скрипта на этой строке, поэтому в примере выше команда обернута в if.
Пакеты, вызывающие запрос на перезагрузку, определяются коротким жестко заданным списком внутри плагина. В текущих версиях он содержит kernel, kernel-core, kernel-rt, glibc, linux-firmware, systemd, dbus, dbus-broker, dbus-daemon и microcode_ctl. В старых сборках плагина список немного короче, поэтому проверьте свой вариант, а не полагайтесь на предположения.
Каждый элемент в этом списке находится там по причине, которую можно четко сформулировать. Новый пакет kernel записывает файлы только в /boot и /lib/modules, а работающее ядро нельзя заменить «на лету», поэтому изменения вступят в силу только после загрузки. Каждый процесс в системе использует glibc, что означает, что «перезапуск затронутых служб» потребовал бы перезапуска PID 1, а перезагрузка — это безопасный способ сделать это. dbus и dbus-broker обслуживают все клиентские соединения в системе, поэтому остановка шины на работающей машине приведет к разрыву связи с клиентами. linux-firmware и microcode_ctl загружаются при старте, и на VPS часть с микрокодом обычно ничего не меняет для пользователя, так как физическим процессором управляет гипервизор хоста.
Вы можете добавить свои пакеты. Любой файл .conf в директории /etc/dnf/plugins/needs-restarting.d/ считывается как список имен пакетов (по одному в строке), и эти имена добавляются в список для перезагрузки.
echo 'openssl-libs' | sudo tee /etc/dnf/plugins/needs-restarting.d/openssl.confЭто выбор политики, а не исправление. Он означает: «при обновлении библиотеки TLS я предпочту перезагрузиться, чем отслеживать каждый сервис, который её использует».
Откуда берется уведомление о необходимости перезагрузки
needs-restarting -r не сравнивает версию запущенного ядра с версией новейшего установленного ядра. Он сравнивает временные метки. Для каждого пакета из основного списка он считывает время установки RPM и сравнивает его со временем загрузки системы. Если основной пакет был установлен после последней загрузки, ответом будет «требуется перезагрузка». Время загрузки берется из UnitsLoadStartTimestamp через D-Bus, если это доступно, в противном случае — как более позднее из времени изменения /proc/1 и значения поля btime в /proc/stat.
У этого механизма есть одно следствие, о котором стоит знать. Если вы устанавливаете ядро, перезагружаетесь и снова оказываетесь в старом ядре из-за того, что загрузка по умолчанию зафиксирована, время установки теперь оказывается раньше времени загрузки, и needs-restarting -r замолкает. Он правильно отвечает на свой вопрос. Но это не тот вопрос, который задали вы. Проверяйте ядро отдельно.
uname -r
rpm -q --last kernel
sudo grubby --default-kernelПервая команда выводит то, что запущено в данный момент. Первая строка rpm -q --last kernel — это самое недавно установленное ядро. grubby --default-kernel выводит то, что загрузчик выберет в следующий раз. Если эти три значения не совпадают, исправьте настройки загрузки по умолчанию перед тем, как перезагружать машину, к которой у вас нет доступа через консоль.
Уровень 2: обновления, требующие перезапуска сервисов
Когда RPM заменяет общую библиотеку, он удаляет старый файл и записывает новый. Процесс, который уже отобразил старый файл в память, продолжает удерживать старый inode и исполнять старый код. openssl-libs — это наиболее важный случай: исправление в libcrypto вступит в силу для вашего веб-сервера только после его перезапуска.
sudo needs-restarting -sЭтот список содержит systemd-сервисы, чьи собственные файлы или файлы их зависимостей были обновлены после запуска сервиса. Используйте sudo. Без прав root утилита может прочитать только записи /proc для ваших собственных процессов, поэтому она выдаст неполные данные, и короткий список может создать ложное ощущение безопасности.
sudo needs-restarting
sudo needs-restarting --exclude-servicesПервая команда выводит PID и командную строку каждого затронутого процесса. Вторая отфильтровывает процессы, которые уже покрываются systemd-сервисами, оставляя только интерактивные оболочки, сессии tmux, задания cron и всё, что вы запустили вручную. Они никогда не перезапускаются автоматически.
Если сервис из списка также относится к пакетам уровня перезагрузки системы, утилита выведет над ним Warning: The following services should not be restarted but require a reboot:. Воспринимайте это буквально и выполните перезагрузку системы.
Перезапускайте остальные сервисы по одному и проверяйте каждый из них, прежде чем переходить к следующему.
sudo systemctl restart nginx
systemctl status nginxНе передавайте список через конвейер в systemctl restart. Ваша собственная SSH-сессия является причиной. В семействе RHEL sshd.service поставляется с KillMode=process, поэтому его перезапуск посылает сигнал слушающему демону, не затрагивая процессы отдельных соединений, и открытая сессия сохраняется. Подтвердите это на своей системе с помощью systemctl cat sshd | grep KillMode и в первый раз всегда держите открытой вторую сессию.
Вы также можете найти те же процессы без использования DNF, что полезно, если вы хотите увидеть соответствующие пути к файлам:
sudo dnf install -y lsof
sudo lsof -n +c 0 2>/dev/null | grep -w DELDEL помечает отображенный в память файл, который был удален с диска. Изучите пути перед выполнением действий. Удаленные временные файлы и файлы, размещенные в оперативной памяти, также отображаются здесь, и они не являются поводом для перезапуска чего-либо.
Уровень 3: всё остальное
Большинство обновлений попадают в эту категорию и не требуют дополнительных действий. Пакет, файлы которого считываются только при запуске команды, например curl, tar, vim или сам dnf, полностью обновляется сразу после завершения работы RPM, так как при следующем запуске будет считан новый исполняемый файл. Файлы конфигурации, скрипты, документация и пакеты данных ведут себя аналогично. needs-restarting не будет упоминать ни один из них, и отсутствие сообщений в данном случае является ожидаемым поведением, а не пропущенным событием.
Единственный нюанс на этом уровне — длительность работы. Процесс, запущенный до обновления, продолжает использовать старый исполняемый файл до тех пор, пока не завершится, независимо от того, насколько незначительным был пакет. Именно для этого предназначен sudo needs-restarting --exclude-services.
Почему машина с dnf-automatic может неделями работать с непримененными исправлениями
Здесь три уровня обновлений перестают быть теорией. Автоматические обновления с помощью dnf-automatic устанавливают пакеты по таймеру, а значение reboot по умолчанию в /etc/dnf/automatic.conf — never. С настройками apply_updates = yes и reboot = never машина может установить шесть обновлений ядра и исправление glibc за шесть недель, но при этом продолжать использовать ядро и библиотеку C, с которыми она загрузилась в нулевую неделю. Журнал обновлений выглядит безупречно. Работающая система не получила ни одного из них.
Решение состоит из трех строк в /etc/dnf/automatic.conf:
[commands]
upgrade_type = security
apply_updates = yes
reboot = when-needed
reboot_command = "shutdown -r +5 'Rebooting after applying package updates'"reboot принимает значения never, when-changed и when-needed. never — это значение по умолчанию, которое оставляет все решения за вами. when-changed перезагружает систему после любой транзакции, изменившей пакет; это грубый, но предсказуемый метод. when-needed запрашивает у DNF, требует ли только что примененная транзакция перезагрузки, поэтому обновление только пользовательского пространства проходит без нее. reboot_command — это то, что запускается на самом деле, а значение по умолчанию дает вошедшим в систему пользователям пять минут на предупреждение. Настройте random_sleep и расписание таймера так, чтобы это попадало в окно, когда вы можете наблюдать за возвращением машины в строй.
Проверьте, какой юнит вы включили с помощью systemctl list-timers 'dnf-*'. В состав dnf-automatic входит несколько вариантов, и они ведут себя по-разному, поэтому один лишь файл конфигурации не скажет вам, что именно выполняется.
После запланированного запуска спрашивайте саму машину, а не журнал:
needs-restarting -r; echo "exit: $?"
uname -r
rpm -q --last kernel | head -1Если перезагрузка — это то, что вы не можете запланировать, live kernel patching на VPS является альтернативным путем. Он применяет определенные исправления ядра к работающему ядру без перезагрузки. Он покрывает лишь часть проблем ядра и никак не влияет на glibc или ваши сервисы, поэтому рассматривайте его как способ увеличить интервалы между перезагрузками, а не как способ полностью от них отказаться. Когда вы все же выполняете перезагрузку, делайте это осознанно и оставайтесь в системе, пока машина не ответит, так как обновление ядра — самая частая причина, по которой машина не возвращается в строй. Прочитайте что делать, если VPS не загружается после обновления ядра перед тем, как перезагружать сервер без доступа к консоли, и включите проверку после перезагрузки в регулярный чек-лист обслуживания сервера, чтобы не вспоминать об этом только после инцидента.
Аналогичные задачи в Ubuntu и Debian
При работе со смешанным парком серверов требуются эквивалентные инструменты. В Ubuntu и Debian флаг необходимости перезагрузки реализован через файл, а не через команду: скрипты пакетов создают /run/reboot-required, а /run/reboot-required.pkgs содержит список пакетов, запросивших перезагрузку, поэтому [ -f /run/reboot-required ] является прямым аналогом needs-restarting -r. В старой документации упоминается /var/run/reboot-required — это тот же самый файл, так как /var/run является символической ссылкой на /run. На стороне сервисов используется needrestart, который по умолчанию установлен в последних релизах Ubuntu Server; он запускается во время apt upgrade, а также может быть запущен отдельно командой sudo needrestart -r l для вывода списка сервисов, требующих перезапуска, без внесения каких-либо изменений. Проблема автоматических обновлений здесь аналогична, как и способ её решения: unattended-upgrades в Ubuntu использует Unattended-Upgrade::Automatic-Reboot "true"; и Unattended-Upgrade::Automatic-Reboot-Time "02:00"; в /etc/apt/apt.conf.d/50unattended-upgrades.
Типовые сбои и их признаки
needs-restarting: command not foundозначает, чтоdnf-utilsне установлен. Установите его или используйтеdnf needs-restarting, который работает при наличииdnf-plugins-core.- Скрипт, который останавливается на проверке перезагрузки без сообщения об ошибке, получает код завершения 1 в
set -e. Этот код означает «требуется перезагрузка», поэтому обрабатывайте его как условие, а не как завершение работы скрипта. - Если
needs-restarting -sне выводит ничего сразу после обновления библиотеки, значит, вы запустили его безsudo. Без прав root утилита видит только ваши собственные процессы. - Если
needs-restarting -rсообщает, что перезагрузка не требуется, аuname -rпоказывает старую версию, значит, вы загрузились с более старым ядром. Проверка сравнивает время установки со временем загрузки, и оба значения уже неактуальны. Проверьтеgrubby --default-kernel. - Если сервис снова появляется в списке при следующем запуске через несколько минут после того, как вы его перезапустили, его обычно перезапускает что-то другое или юнит не смог корректно подняться. Изучите
systemctl statusдля этого юнита, прежде чем перезапускать его повторно.
FAQ
Перезапускает ли dnf update службы в Rocky Linux?
Как правило, нет. Транзакция записывает файлы и завершается. Некоторые пакеты содержат RPM-скрипты, которые перезапускают соответствующую службу при обновлении, поэтому поведение зависит от конкретного пакета, а не является системной гарантией. Считайте sudo needs-restarting -s основным источником информации: эта команда выводит список служб, файлы которых или файлы их зависимостей изменились после запуска службы, независимо от того, что выполнили скрипты.
Почему needs-restarting -r сообщает, что перезагрузка не требуется, хотя установлено более новое ядро?
Потому что утилита сравнивает время установки RPM-пакетов из короткого списка ключевых компонентов со временем загрузки системы. Она не сравнивает версию работающего ядра с версией самого нового установленного ядра. Если вы установили ядро, перезагрузились, но система вернулась на старую версию, так как загрузчик настроен по умолчанию на неё, время установки будет раньше времени загрузки, и проверка не выдаст предупреждений. Выполните uname -r, rpm -q --last kernel и sudo grubby --default-kernel, чтобы увидеть реальную картину.
Какие пакеты вызывают рекомендацию о перезагрузке в Rocky и Alma?
Список жестко закодирован внутри плагина. В текущих версиях он включает kernel, kernel-core, kernel-rt, glibc, linux-firmware, systemd, dbus, dbus-broker, dbus-daemon и microcode_ctl. Вы можете расширить этот список: создайте файл .conf в директории /etc/dnf/plugins/needs-restarting.d/, добавив туда имена пакетов (по одному на строку), и эти пакеты также будут учитываться при проверке необходимости перезагрузки.
Может ли dnf-automatic перезагрузить сервер самостоятельно?
Да. Установите reboot = when-needed в секции [commands] файла /etc/dnf/automatic.conf, и сервер будет перезагружаться только тогда, когда примененная транзакция требует этого. Параметр when-changed выполняет перезагрузку после любых изменений в пакетах, а never является значением по умолчанию. Параметр reboot_command управляет процессом, и по умолчанию он выдает вошедшим в систему пользователям предупреждение за пять минут до перезагрузки. Включайте эту функцию только на тех машинах, доступ к которым вы можете восстановить, так как автоматическая перезагрузка на VPS без доступа к консоли может привести к критическому сбою.
Видит ли needs-restarting процессы внутри контейнеров?
Неэффективно. Утилита сопоставляет запущенные процессы с базой данных RPM на хосте, а пакеты внутри образа контейнера в этой базе отсутствуют. Поэтому устаревшая библиотека, встроенная в образ, не будет обнаружена. Пересоберите образ и разверните его заново. Состояние хоста по-прежнему важно: среда выполнения контейнеров и ядро, которое они используют, являются пакетами хоста, и они отображаются в результатах проверки.