KillMode=: почему systemctl stop иногда оставляет процессы
Остановить сервис через:
systemctl stop myapp.service
не всегда означает, что исчезнет только один процесс. У systemd есть отдельная настройка, определяющая, какие процессы будут остановлены вместе с unit.
Это KillMode=.
▪️Например:
[Service]
ExecStart=/opt/myapp/start.sh
KillMode=control-group
По умолчанию systemd работает с control group сервиса. При остановке он может завершить все процессы внутри cgroup, а не только основной PID.
Проверить:
systemctl show myapp.service -p KillMode
▪️Самый интересный вариант - process
[Service]
KillMode=process
В этом режиме сигнал отправляется только основному процессу сервиса.
Если start.sh породил:
myapp
├─ worker1
└─ worker2
дочерние процессы могут продолжить работу после остановки unit.
▪️control-group
[Service]
KillMode=control-group
systemd отслеживает cgroup целиком:
myapp.service
├─ PID 1200
├─ PID 1201
└─ PID 1202
При остановке unit процессы внутри группы также попадут под завершение.
▪️Проверить, кто реально принадлежит сервису
systemctl status myapp.service
или:
systemctl show myapp.service -p ControlGroup
Затем:
systemd-cgls
Можно увидеть дерево процессов по cgroup.
▪️Ещё один режим
KillMode=mixed
При остановке SIGTERM получает основной процесс, а при последующем принудительном завершении systemd применяет его ко всей control group.
Это позволяет дать главному процессу шанс корректно завершиться, не оставляя дочерние процессы навсегда.
▪️Почему это важно
Особенно легко получить «призраков» при запуске приложения через shell-обёртку:
ExecStart=/bin/bash /opt/start.sh
Если скрипт запускает фоновые процессы, нужно понимать, в какой cgroup они окажутся и как KillMode повлияет на их завершение.
systemctl stop - это не просто отправка SIGTERM одному PID. В systemd процесс существует внутри cgroup, и политика KillMode определяет масштаб остановки.
BashTex 📱 #bash #linux
Остановить сервис через:
systemctl stop myapp.service
не всегда означает, что исчезнет только один процесс. У systemd есть отдельная настройка, определяющая, какие процессы будут остановлены вместе с unit.
Это KillMode=.
▪️Например:
[Service]
ExecStart=/opt/myapp/start.sh
KillMode=control-group
По умолчанию systemd работает с control group сервиса. При остановке он может завершить все процессы внутри cgroup, а не только основной PID.
Проверить:
systemctl show myapp.service -p KillMode
▪️Самый интересный вариант - process
[Service]
KillMode=process
В этом режиме сигнал отправляется только основному процессу сервиса.
Если start.sh породил:
myapp
├─ worker1
└─ worker2
дочерние процессы могут продолжить работу после остановки unit.
▪️control-group
[Service]
KillMode=control-group
systemd отслеживает cgroup целиком:
myapp.service
├─ PID 1200
├─ PID 1201
└─ PID 1202
При остановке unit процессы внутри группы также попадут под завершение.
▪️Проверить, кто реально принадлежит сервису
systemctl status myapp.service
или:
systemctl show myapp.service -p ControlGroup
Затем:
systemd-cgls
Можно увидеть дерево процессов по cgroup.
▪️Ещё один режим
KillMode=mixed
При остановке SIGTERM получает основной процесс, а при последующем принудительном завершении systemd применяет его ко всей control group.
Это позволяет дать главному процессу шанс корректно завершиться, не оставляя дочерние процессы навсегда.
▪️Почему это важно
Особенно легко получить «призраков» при запуске приложения через shell-обёртку:
ExecStart=/bin/bash /opt/start.sh
Если скрипт запускает фоновые процессы, нужно понимать, в какой cgroup они окажутся и как KillMode повлияет на их завершение.
systemctl stop - это не просто отправка SIGTERM одному PID. В systemd процесс существует внутри cgroup, и политика KillMode определяет масштаб остановки.
BashTex 📱 #bash #linux