У меня есть подразделение, которое я просто позвоню eth-service
это требует другого подразделения, которое я позвоню eth-server
. В модульном файле eth-service
у меня есть
Requires=eth-server.service
After=eth-server.service
Теперь, когда я бегу systemctl stop eth-server
, затем eth-service
останавливается, как и должно. Однако позже, когда я бегу systemctl start eth-server
, К сожалению eth-service
остается неактивным, поэтому мне нужно не забыть перезапустить его.
Я пытаюсь сделать настройку моего файла модуля максимально защищенной от идиотов (особенно против меня самого) - можно ли настроить мои файлы модуля так, чтобы при запуске сервера служба тоже делала это? Если бы я положил в свой eth-server
файл модуля:
Requires=eth-service.service
Before=eth-service.service
так что они взаимно требуют друг друга, что вызовет запуск службы, когда это делает сервер, но это также означает, что когда я запускаю systemctl stop eth-service
затем eth-server
тоже останавливается, так как теперь требуется услуга, что нежелательно.
Позвольте мне посмотреть, понял ли я сценарий использования:
eth-service
должен начать оба eth-server
и eth-service
.eth-server
должен начать оба eth-server
и eth-service
.eth-server
должен остановить оба eth-server
и eth-service
.eth-service
должен ТОЛЬКО остановиться eth-service
и уходи eth-server
Бег.Вы можете добиться этого, добавив WantedBy=eth-server.service
в раздел [Установить] eth-service.service
файл или Wants=eth-service.service
в раздел [Unit] eth-server.service
.
Согласно документация systemd Wants
это более слабая версия Requires
, и кажется, что если Wanted
блок остановлен, запрошенный блок не затронут. Но в этой настройке может быть нежелательный побочный эффект, когда eth-server
начнется независимо от того, если eth-service
не запускается или нет.
Следующие образцы файлов модулей можно сохранить в домашнем каталоге (~/.config/systemd/user
) и используется с systemctl --user
параметр.
Сервисы, описываемые этими юнит-файлами, ничего не делают, но RemainAfterExit=yes
заставляет systemd предполагать, что служба все еще работает, даже если /bin/true
команда не остается после выполнения.
[Unit]
Description=eth Service
Requires=eth-server.service
[Service]
Type=oneshot
ExecStart=/bin/true
RemainAfterExit=yes
[Install]
WantedBy=eth-server.service
[Unit]
Description=eth Server
[Service]
Type=oneshot
ExecStart=/bin/true
RemainAfterExit=yes
Включите eth-service.service
модуль с systemctl --user enable eth-service.service
.
Ниже приведены результаты тестов с запуском / остановкой служб:
$> systemctl --user status eth-service
● eth-service.service - eth Service
Loaded: loaded (/home/ektich/.config/systemd/user/eth-service.service; enabled; vendor preset: enabled)
Active: inactive (dead)
$> systemctl --user status eth-server
● eth-server.service - eth Server
Loaded: loaded (/home/ektich/.config/systemd/user/eth-server.service; static; vendor preset: enabled)
Active: inactive (dead)
Система возвращается в исходное состояние перед выполнением команд в следующих двух разделах.
Обе server
и service
запущены (игнорируйте exited
строки: и сервер, и служба являются выполнением / bin / true, который завершается после завершения, но файлы модулей записываются так, что systemd будет думать, что службы работают, пока они не будут остановлены)
$> systemctl --user start eth-service.service
$> systemctl --user status eth-service
● eth-service.service - eth Service
Loaded: loaded (/home/ektich/.config/systemd/user/eth-service.service; enabled; vendor preset: enabled)
Active: active (exited) since Tue 2018-05-29 20:50:01 IST; 28s ago
Process: 1578 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
Main PID: 1578 (code=exited, status=0/SUCCESS)
$> systemctl --user status eth-server
● eth-server.service - eth Server
Loaded: loaded (/home/ektich/.config/systemd/user/eth-server.service; static; vendor preset: enabled)
Active: active (exited) since Tue 2018-05-29 20:50:01 IST; 2min 59s ago
Process: 1579 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
Main PID: 1579 (code=exited, status=0/SUCCESS)
Обе службы запущены:
$> systemctl --user start eth-server.service
$> systemctl --user status eth-service
● eth-service.service - eth Service
Loaded: loaded (/home/ektich/.config/systemd/user/eth-service.service; enabled; vendor preset: enabled)
Active: active (exited) since Tue 2018-05-29 20:56:03 IST; 7s ago
Process: 1681 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
Main PID: 1681 (code=exited, status=0/SUCCESS)
$> systemctl --user status eth-server
● eth-server.service - eth Server
Loaded: loaded (/home/ektich/.config/systemd/user/eth-server.service; static; vendor preset: enabled)
Active: active (exited) since Tue 2018-05-29 20:56:03 IST; 12s ago
Process: 1680 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
Main PID: 1680 (code=exited, status=0/SUCCESS)
Команды в следующих двух разделах выполняются там, где запущены обе службы:
$> systemctl --user status eth-service
● eth-service.service - eth Service
Loaded: loaded (/home/ektich/.config/systemd/user/eth-service.service; enabled; vendor preset: enabled)
Active: inactive (dead)
$> systemctl --user status eth-server
● eth-server.service - eth Server
Loaded: loaded (/home/ektich/.config/systemd/user/eth-server.service; static; vendor preset: enabled)
Active: inactive (dead)
Вы можете видеть, что обе службы были остановлены
$> systemctl --user stop eth-service
$> systemctl --user status eth-service
● eth-service.service - eth Service
Loaded: loaded (/home/ektich/.config/systemd/user/eth-service.service; enabled; vendor preset: enabled)
Active: inactive (dead) since Tue 2018-05-29 21:05:25 IST; 34s ago
Process: 1800 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
Main PID: 1800 (code=exited, status=0/SUCCESS)
May 29 21:04:23 ektich systemd[479]: Starting eth Service...
May 29 21:04:23 ektich systemd[479]: Started eth Service.
May 29 21:05:25 ektich systemd[479]: Stopped eth Service.
$> systemctl --user status eth-server
● eth-server.service - eth Server
Loaded: loaded (/home/ektich/.config/systemd/user/eth-server.service; static; vendor preset: enabled)
Active: active (exited) since Tue 2018-05-29 21:04:23 IST; 2min 58s ago
Process: 1799 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
Main PID: 1799 (code=exited, status=0/SUCCESS)
May 29 21:04:23 ektich systemd[479]: Starting eth Server...
May 29 21:04:23 ektich systemd[479]: Started eth Server.
Ты это видишь eth-service
был остановлен (Active: inactive (dead)
) но eth-server
все еще "работает" (Active: active
)
Команда статуса для etc-service
произвел больше результатов по сравнению с другими случаями, я предполагаю, потому что «транзакция» еще не завершена (etc-server
все еще работает). Дополнительные строки из journalctl
показать, что что касается systemd, одна из служб была остановлена, а другая все еще работает.
PS согласно домашняя страница systemd это пишется systemdне SystemD (просто педантично)
В systemctl start xxx
в общем-то не возвращается последствия предыдущего systemctl stop xxx
.
Админы должны понимать это в ходе своей карьеры, так или иначе. Хорошая новость в том, что этому действительно легко научиться, потому что обратная связь сразу же.
Один из способов отменить ручные остановки и ручные запуски:
systemctl default
Но этот способ вряд ли является надежным, так как он останавливает службы, которые не включен, например, службы, работающие в различных кластерах (в частности, кардиостимулятор даже не видит в этом проблему / сбой и не реагирует на нее - он рассматривает это как запланированное действие администратора).
А также есть systemctl snapshot
но это еще более сложно и, следовательно, менее надежно.
Что вы можете сделать в рамках своих услуг (чтобы стать более защищенным от дурака)? Обратите внимание, как с этим справились другие программисты. Они избегают зависимостей и предпочитают упаковывать несколько процессов в одну зонтичную службу. В стандартной установке RHEL7 нет никаких зависимостей служб. Например постфикс:
$ systemctl status postfix
[...] Tasks: 3
CGroup: /system.slice/postfix.service
├─1288 /usr/libexec/postfix/master -w
├─1290 qmgr -l -t unix -u
└─7340 pickup -l -t unix -u
$ cat /usr/lib/systemd/system/postfix.service
[Unit]
Description=Postfix Mail Transport Agent
After=syslog.target network.target
Conflicts=sendmail.service exim.service
[Service]
Type=forking
PIDFile=/var/spool/postfix/pid/master.pid
EnvironmentFile=-/etc/sysconfig/network
ExecStartPre=-/usr/libexec/postfix/aliasesdb
ExecStartPre=-/usr/libexec/postfix/chroot-update
ExecStart=/usr/sbin/postfix start
ExecReload=/usr/sbin/postfix reload
ExecStop=/usr/sbin/postfix stop
[Install]
WantedBy=multi-user.target