====== systemd ====== https://www.freedesktop.org/software/systemd/man/index.html\\ [[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://systemd-by-example.com/ - примеры с тестами в браузере.\\ ===== Unit-файл ===== https://www.freedesktop.org/software/systemd/man/systemd.unit.html Это скрипт запуска приложения - как его запускать, под каким пользователем и т. д. Системные юнит-файлы лежат в ''/lib/systemd/system'' (есть варианты), свои можно создавать в ''/etc/systemd/system''. Также в ''/etc/systemd/system'' находятся ссылки на системные юнит-файлы, эти ссылки делаются с помощью команды ''systemctl enable''. После создания юнит-файла можно управлять запуском приложения - например, добавить в автозагрузку. Пример unit-файла: [Unit] Description=OpenSSH server daemon Documentation=man:sshd(8) man:sshd_config(5) # After - запускать после network.target и sshd-keygen.service After=network.target sshd-keygen.service # Wants - слабая зависимость: sshd-keygen.service должен запускаться, но sshd запустится вне зависимости от результатов sshd-keygen. Wants=sshd-keygen.service [Service] EnvironmentFile=/etc/sysconfig/sshd # Файл с переменными ExecStart=/usr/sbin/sshd -D $OPTIONS # Строка запуска, $OPTIONS - это из EnvironmentFile ExecReload=/bin/kill -HUP $MAINPID # Строка для reload KillMode=process # Как systemd будет останавливать сервис. Здесь: остановить только основной процесс, но не трогать дочерние (чтобы уже запущенные сессии ssh не отвалились) Restart=on-failure # Перезапуск сервиса при сбое RestartSec=42s # Через сколько перезапускать [Install] WantedBy=multi-user.target # Работать под runlevel multi-user https://fedoramagazine.org/systemd-converting-sysvinit-scripts/ man systemd.unit # Справка по юнитам cat /proc/$(pidof cron)/environ # Вывести переменные процесса cron journalctl -u cron.service -n 10 # Лог (последние 10 записей) journalctl -u cron.service --since yesterday # Лог со вчерашнего дня Типы юнитов systemd target # группирует модули service # отвечает за запуск сервисов (служб) и поддерживает вызов интерпретаторов для исполнения пользовательских скриптов mount # занимается монтированием файловых систем automount # автомонтирование файловых систем, используется при обращении к точке монтирования swap # отвечает за подключение файла подкачки timer # запускает модули по расписанию, аналог cron socket # запуск модуля при подключении к сокету slice # группировка других модулей в контейнер (дерево) cgroups device # использует реакцию на подключение какого-либо устройства path # запуск модуля по событию доступа по конкретному пути в файловой системе Управление процессами systemd systemctl list-units --type service --all # просмотр всех юнитов в системе systemctl list-unit-files --type service systemctl start name # запустить сервис systemctl stop name # остановить сервис systemctl restart name # перезапустить сервис systemctl status name # посмотреть статус сервиса systemctl reload name # перечитать конфигурацию systemctl daemon-reload # перечитать конфигурацию для всех systemctl try-restart name # перезапустить, если запущен systemctl enable name # включить автозапуск сервиса systemctl disable name # отключить автозапуск сервиса systemctl list-unit-files --type service # список установленных юнит-файлов сервисов ==== Зависимость между юнитами и порядок запуска ==== Перед запуском юнит может ''wants'' или ''requires'' другой юнит. Разница: * Если unit1 ''Wants=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. Wants=sshd-keygen.service After=network.target sshd-keygen.service https://fedoramagazine.org/systemd-unit-dependencies-and-order/ ==== Target unit ==== Используется для связи и группировки других юнитов вместе, чтобы описать желаемое состояние системы. Некоторые из этих юнитов могут быть сервисами, некоторые - другими таргетами со своими группами юнитов. В примере нет выполняемой команды, таргет работает как связующее звено между другими таргетами. [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 * ''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 ===== Если в ''/etc/resolv.conf'' есть заглушка ''nameserver 127.0.0.53'', значит, работает сервис ''systemd-resolve''. Конфигурация ''systemd-resolve'' находится в ''/run/systemd/resolve/resolv.conf''. Статус ''systemd-resolve'' можно проверить командой sudo resolvectl status https://wiki.archlinux.org/title/Systemd-resolved ===== Пользовательские юниты ===== Непривилегированный пользователь тоже может запускать службы systemd от своего имени. Юнит-файлы нужно класть в ''~/.config/systemd/user''. Нюанс в том, что эти службы будут работать до тех пор, пока пользователь находится в системе. Если он выходит, то службы останавливаются. Чтобы службы работали вне зависимости от сеанса, нужно выполнить команду loginctl enable-linger $USER # Проверить, включена ли эта опция loginctl user-status ... Linger: yes # или показать только yes/no loginctl show-user $USER -p Linger |cut -d= -f2 Пример unit-файла [Unit] Description=Minecraft Java server [Service] WorkingDirectory=/opt/minecraft ExecStart=/usr/bin/java -Xmx1024M -Xms1024M -jar minecraft.jar nogui Restart=on-failure [Install] WantedBy=multi-user.target Управление службой такое же, нужно только добавлять параметр ''%%--user%%''. # После добавления юнита перечитать список демонов systemctl --user daemon-reload ===== systemd-run ===== systemd-run позволяет превратить любую команду в фоновую задачу. unitname=minecraft-server systemd-run --user --unit=$unitname java -Xmx1024M -Xms1024M -jar minecraft.jar nogui systemctl --user status $unitname # Если вы ошиблись в команде или она завершилась с ошибкой systemctl reset-failed Удаление юнита systemctl --user stop $unitname find /run -name "*$unitname*" -exec rm -rf {} + 2> /dev/null systemctl --user daemon-reload systemctl --user reset-failed https://superuser.com/questions/513159/how-to-remove-systemd-services Поиск systemctl --user list-units --all -t service --full --no-legend "$unitname.service" |xargs |cut -d' ' -f1 https://stackoverflow.com/questions/24398242/check-if-service-exists-in-bash-centos-and-ubuntu\\ https://stackoverflow.com/questions/369758/how-to-trim-whitespace-from-a-bash-variable ===== Таймер для периодического запуска ===== Сервис типа oneshot, запускающий скрипт [Unit] Description=Testlog service #Wants=testlog.timer [Service] Type=oneshot ExecStart=/home/user/testlog.sh [Install] WantedBy=multi-user.target Таймер запуска каждые 3 минуты [Unit] Description=Testlog timer #Requires=testlog.service [Timer] #Unit=testlog.service OnCalendar=*:0/3 [Install] WantedBy=timers.target [[https://habr.com/ru/companies/ruvds/articles/512868/|Использование таймеров systemd вместо заданий cron]]\\ https://www.freedesktop.org/software/systemd/man/latest/systemd.timer.html\\ https://www.digitalocean.com/community/tutorials/understanding-systemd-units-and-unit-files\\ https://unix.stackexchange.com/questions/126786/systemd-timer-every-15-minutes\\