Предыдущая версия справа и слеваПредыдущая версияСледующая версия | Предыдущая версия |
os:linux:systemd [13.09.2024 13:43] – [Unit-файл] viacheslav | os:linux:systemd [23.03.2025 08:36] (текущий) – [Таймер для периодического запуска] viacheslav |
---|
[[https://www.redhat.com/sysadmin/systemd-automate-recovery|Set up self-healing services with systemd]]\\ | [[https://www.redhat.com/sysadmin/systemd-automate-recovery|Set up self-healing services with systemd]]\\ |
[[https://www.youtube.com/watch?v=tY9GYsoxeLg|Demystifying Systemd]]\\ | [[https://www.youtube.com/watch?v=tY9GYsoxeLg|Demystifying Systemd]]\\ |
| https://systemd-by-example.com/ - примеры с тестами в браузере.\\ |
| https://systemd.io/\\ |
| {{ :os:linux:s4a_latest.pdf |systemd для администраторов, русский перевод (Сергей Пташник, 28 октября 2017 г.)}}\\ |
| [[https://habr.com/ru/companies/timeweb/articles/824146/|systemD с 0 до 1: библия сисадмина (Хабр)]] |
===== Unit-файл ===== | ===== Unit-файл ===== |
https://www.freedesktop.org/software/systemd/man/systemd.unit.html | https://www.freedesktop.org/software/systemd/man/systemd.unit.html |
| |
Пример unit-файла: | Пример unit-файла: |
<file bash /etc/systemd/system/multi-user.target.wants/cron.service> | <file bash /etc/systemd/system/multi-user.target.wants/sshd.service> |
[Unit] | [Unit] |
Description=Regular background program processing daemon | Description=OpenSSH server daemon |
Documentation=man:cron(8) | Documentation=man:sshd(8) man:sshd_config(5) |
After=remote-fs.target nss-user-lookup.target | # After - запускать после network.target и sshd-keygen.service |
| After=network.target sshd-keygen.service |
| # Wants - слабая зависимость: sshd-keygen.service должен запускаться, но sshd запустится вне зависимости от результатов sshd-keygen. |
| Wants=sshd-keygen.service |
| |
[Service] | [Service] |
EnvironmentFile=-/etc/default/cron | EnvironmentFile=/etc/sysconfig/sshd # Файл с переменными |
ExecStart=/usr/sbin/cron -f $EXTRA_OPTS | ExecStart=/usr/sbin/sshd -D $OPTIONS # Строка запуска, $OPTIONS - это из EnvironmentFile |
IgnoreSIGPIPE=false | ExecReload=/bin/kill -HUP $MAINPID # Строка для reload |
KillMode=process | KillMode=process # Как systemd будет останавливать сервис. Здесь: остановить только основной процесс, но не трогать дочерние (чтобы уже запущенные сессии ssh не отвалились) |
Restart=on-failure | Restart=on-failure # Перезапуск сервиса при сбое |
| RestartSec=42s # Через сколько перезапускать |
| |
[Install] | [Install] |
WantedBy=multi-user.target | WantedBy=multi-user.target # Работать под runlevel multi-user |
</file> | </file> |
| https://fedoramagazine.org/systemd-converting-sysvinit-scripts/ |
| |
<code bash> | <code bash> |
</code> | </code> |
| |
==== Зависимость между юнитами ==== | ==== Зависимость между юнитами и порядок запуска ==== |
Перед запуском юнит может ''wants'' или ''requires'' другой юнит. Разница: | Перед запуском юнит может ''wants'' или ''requires'' другой юнит. Разница: |
* Если unit1 ''Wants=unit2'' и unit2 сбойнул, то это не влияет на запуск unit1. | * Если unit1 ''Wants=unit2'' и unit2 сбойнул, то это не влияет на запуск unit1. |
* Если unit1 ''Requires=unit2'' и unit2 сбойнул, то unit1 не запустится. | * Если unit1 ''Requires=unit2'' и unit2 сбойнул, то unit1 не запустится. |
| |
| Для чего нужен ''wants''? Например, в sshd.service есть ''Wants=sshd-keygen.service''. Sshd-keygen.service генерит ключи для сервера, если их нет. Если они есть, то sshd-keygen.service завершается с ошибкой, которая говорит о наличии ключей, но это не должно влиять на запуск sshd.service. |
| |
| ''Wants'' и ''requires'' - это не порядок запуска, юниты запускаются вместе. За порядок запуска в systemd отвечают параметры ''Before'' и ''After''. |
| * Если в unit1 есть параметр ''Before=unit2'', то unit1 запустится до unit2. |
| * Если в unit1 есть параметр ''After=unit2'', то unit1 запустится после unit2. |
| |
| В примере sshd.service запустится только после того, как поднялась сеть и запустился sshd-keygen. |
| <code ini> |
| Wants=sshd-keygen.service |
| After=network.target sshd-keygen.service |
| </code> |
| |
| https://fedoramagazine.org/systemd-unit-dependencies-and-order/ |
| |
| ==== Target unit ==== |
| Используется для связи и группировки других юнитов вместе, чтобы описать желаемое состояние системы. Некоторые из этих юнитов могут быть сервисами, некоторые - другими таргетами со своими группами юнитов. |
| |
| В примере нет выполняемой команды, таргет работает как связующее звено между другими таргетами. |
| <file ini multi-user.target> |
| [Unit] |
| Description=Multi-User System |
| Documentation=man:systemd.special(7) |
| Requires=basic.target |
| Conflicts=rescue.service rescue.target |
| After=basic.target rescue.service rescue.target |
| AllowIsolate=yes |
| </file> |
| |
| * ''multi-user.target'' требует (requires) успешного запуска ''basic.target''. |
| * Если ''rescue.service'' или ''rescue.target'' запустились, то это останавливает юнит, и наоборот (conflicts). |
| * Если ''multi-user.target'' запустится только после (after) ''basic.target'', либо ''rescue.service'' и ''rescue.target''. |
| |
| ''AllowIsolate'' - система рассматривает юнит как загрузочную цель (команда ''systemctl isolate''). Посмотреть текущую загрузочную цель - ''systemctl get-default''. |
| |
| Таргет может иметь каталог ''.wants'', в котором хранятся ссылки на юниты (не только сервисы, но и другие таргеты), которые будут запущены при старте основного таргета. Например, материнский таргет лежит по пути ''/usr/lib/systemd/system/multi-user.target'', значит, каталог будет ''/usr/lib/systemd/system/multi-user.target.wants''. Каждый юнит в этом каталоге может иметь собственные зависимости или опции типа ''Requires'', поэтому можно создать довольно сложную иерархическую структуру. |
===== systemd-resolve ===== | ===== systemd-resolve ===== |
Если в ''/etc/resolv.conf'' есть заглушка ''nameserver 127.0.0.53'', значит, работает сервис ''systemd-resolve''. | Если в ''/etc/resolv.conf'' есть заглушка ''nameserver 127.0.0.53'', значит, работает сервис ''systemd-resolve''. |
https://stackoverflow.com/questions/369758/how-to-trim-whitespace-from-a-bash-variable | https://stackoverflow.com/questions/369758/how-to-trim-whitespace-from-a-bash-variable |
| |
===== Таймер для периодического запуска ===== | Псевдосервис и получение его статуса для скриптов |
| <code bash> |
| systemd-run --user --unit=camunda sleep infinity |
| Running as unit: camunda.service |
| |
| systemctl --user is-active camunda.service |
| active # or inactive |
| </code> |
| ===== systemd.timer ===== |
Сервис типа oneshot, запускающий скрипт | Сервис типа oneshot, запускающий скрипт |
<code ini> | <code ini> |
https://www.digitalocean.com/community/tutorials/understanding-systemd-units-and-unit-files\\ | https://www.digitalocean.com/community/tutorials/understanding-systemd-units-and-unit-files\\ |
https://unix.stackexchange.com/questions/126786/systemd-timer-every-15-minutes\\ | https://unix.stackexchange.com/questions/126786/systemd-timer-every-15-minutes\\ |
| |
| Для работы нужно 3 компонента: скрипт, сервис systemd для запуска скрипта и таймер systemd для запуска сервиса.\\ |
| Скрипт после создания нужно сделать исполняемым - ''chmod +x /scripts/test.sh'' |
| |
| <code bash> |
| vi /etc/systemd/system/test.service |
| # Абсолютный минимум для сервиса: |
| [Service] |
| ExecStart=/scripts/test.sh |
| |
| # Вариант создания |
| systemctl edit --force --full test.service |
| # Вариант редактирования |
| systemctl edit --full test.service |
| |
| # Перечитать список сервисов (если редактировалось/создавалось с помощью systemctl edit, то не нужно) |
| sudo systemctl daemon-reload |
| # Можно запускать |
| systemctl start test.service |
| |
| # Логи сервиса test в реальном времени |
| sudo journalctl -u test -f |
| </code> |
| |
| Другие секции конфигурации сервиса |
| <code bash> |
| [Unit] |
| Description=This service runs the script /scripts/test.sh |
| |
| [Service] |
| ExecStart=/scripts/test.sh |
| User=worker # от имени кого будет работать |
| |
| # Если служба запускается по таймеру, секция [Install] не нужна |
| #[Install] |
| #WantedBy=multiuser.target # Если GUI нет |
| #WantedBy=graphical.target # Если это десктоп с GUI |
| </code> |
| |
| Таймер |
| <code bash> |
| # Кладётся в ту же папку, что и сервис |
| vi /etc/systemd/system/test.timer |
| |
| [Unit] |
| Description=This timer starts test.service |
| |
| [Timer] |
| Unit=test.service |
| # [DayOfWeek] Year-Month-Day Hour:Minute:Second |
| OnCalendar=*-*-* 20:15:00 |
| Persistent=true # Если срабатывание пропущено, запустить при загрузке системы |
| #OnBootSec=5min # Через 5 мин после загрузки |
| |
| # Секция нужна для того, чтобы таймер можно было бы включить при загрузке системы |
| [Install] |
| WantedBy=timers.target |
| |
| # Перечитать сервисы |
| sudo systemctl daemon-reload |
| # Включить таймер при загрузке системы |
| sudo systemctl enable test.timer |
| |
| # Список таймеров |
| systemctl list-timers |
| </code> |
| [[https://www.youtube.com/watch?v=8640OcCL8T8|Linux Command Line (57) systemd.timer pt1 - MichaelsTechTutorials]]\\ |
| [[https://www.youtube.com/watch?v=OV3Gc0SISUo|Linux Command Line (58) systemd.timer pt2 - MichaelsTechTutorials]]\\ |
| [[https://habr.com/ru/post/535930/|Systemd для продолжающих. Part 1 — Запуск юнитов по временным событиям]] |