поведение daemon-reload в ExecStartPre systemd

Вопрос или проблема

У меня есть файл юнита myservice.service, который выглядит следующим образом:

...
ExecStartPre=prehook.sh
...
ExecStart=myapp
ExecStopPost=posthook.sh
...

prehook.sh выполняет различные действия, и, среди прочего, он заменяет файл юнита, если он отличается от локальной копии, и вызывает daemon-reload:

...
# Сравнить файлы
if cmp -s "$SYSTEMD_FILE" "$LOCAL_FILE"; then
  echo "Файлы юнита идентичны. Обновление не требуется."
else
  echo "Файлы юнита различаются. Обновление файла юнита systemd."
  
  # Копировать локальную версию в /lib/systemd/system
  cp "$LOCAL_FILE" "$SYSTEMD_FILE"
  systemctl daemon-reload
  
  echo "Конфигурация systemd перезагружена"
fi

# Продолжить с чем-то другим
...

Локальная копия отличается от в настоящее время загруженного файла юнита в строке ExecStart:

...
ExecStart=myappModified
...

Поведение, которого я ожидал бы, заключается в том, что, если файл юнита изменяется во время ExecStartPre, то daemon-reload влияет только на последующие вызовы systemctl start myservice, но не на текущий.

Удивительно, но systemd, похоже, перезагружает “на лету” строку ExecStart, уважая то, что указано в локальной копии.

Хотя это удобное поведение для скрипта prehook, я не могу найти никаких подтверждений этому в документации. Я что-то упускаю?

Версия systemd — 240.

Ответ или решение

Понимание поведения daemon-reload в ExecStartPre в systemd

Система инициализации systemd предоставляет пользователям серьезные возможности управления службами, в том числе возможность выполнения дополнительных действий перед стартом самой службы через директиву ExecStartPre. В вашем случае, вы задали вопрос, касающийся поведения daemon-reload при изменении файла юнита в процессе выполнения ExecStartPre. Давайте рассмотрим этот вопрос более детально.

Как работает ExecStartPre?

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

Поведение daemon-reload

Ваша проблема заключается в том, что вы обнаружили, что после исполнения команды daemon-reload в ExecStartPre, systemd, похоже, применяет изменения на лету, и вместо ожидаемого поведения, при котором изменения затрагивают только будущие запуски, ваша служба начинает использовать обновленное значение ExecStart.

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

Почему это происходит?

Когда вы выполняете команду daemon-reload, systemd пересобирает внутреннее состояние, включая все параметры, которые могут быть изменены во время работы системы. Это значит, что любые изменения, сделанные в файле юнита, даже в процессе выполнения ExecStartPre, активируются непосредственно для текущего процесса. Таким образом, если изменения в конфигурации касаются параметров запуска (например, ExecStart), systemd применит эти изменения немедленно.

Могу ли я управлять этим поведением?

На данный момент, официального метода для предотвращения этого поведения в systemd не существует. Однако, вы можете рассмотреть следующие подходы:

  1. Изменение логики вашего скрипта: Возможно, имеет смысл изменить способ определения и применения обновлений файла юнита. Например, вы можете вынести часть логики, отвечающей за обновление юнита, в отдельный исследовательский скрипт, который будет выполнен отдельно от ExecStartPre.

  2. Доступ к версии юнита: Вместо обновления юнита внутри ExecStartPre, можно периодически проверять текущую версию юнита перед его запуском.

Заключение

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

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

Оцените материал
Добавить комментарий

Капча загружается...