SIGKILL을 통해 종료되도록 버기 시스템 서비스 구성


20

배경

systemd새로운 서비스에 대한 스크립트 를 작성하라는 요청을 받았습니다.이 서비스 foo_daemon는 때때로 "나쁜 상태"에 빠지고 SIGTERM(사용자 지정 신호 처리기 때문에) 죽지 않을 것 입니다. 개발자는 다음을 통해 서비스를 시작 / 중지 / 다시 시작하라는 지시를 받으므로 문제가됩니다.

  • systemctl start foo_daemon.service
  • systemctl stop foo_daemon.service
  • systemctl restart foo_daemon.service

문제

때로는 foo_daemon나쁜 상태에 빠지기 때문에 다음을 통해 강제로 종료해야합니다.

  • systemctl kill -s KILL foo_daemon.service

의문

어떻게 내가 설정 내 systemd을위한 스크립트를 foo_daemon되도록, 정지에 대한 사용자 시도 / 서비스를 다시 시작 때마다 systemd것입니다 :

  • foo_daemonvia 의 정상적인 종료를 시도하십시오 SIGTERM.
  • 종료 / 종료 foo_daemon가 완료 될 때까지 최대 2 초를 제공하십시오 .
  • 프로세스가 아직 활성 상태 인 경우 강제로 foo_daemon비아를 종료 SIGKILL하십시오 (따라서 PID가 재활용 될 위험이없고 잘못된 PID에 대해 systemd문제 가 발생하지 않습니다 SIGKILL). 우리가 테스트하는 장치는 수많은 프로세스를 빠르게 생성 하므로 문제를 일으키는 PID 재활용에 대해서는 드물지만 매우 우려됩니다.
  • 실제로 PID 재활용에 대해 편집증을 앓고 SIGKILL있다면 재활용 PID를 죽일 염려없이 프로세스 PID에 대해 스크립트를 발행 하는 것이 좋습니다.


2
2 초 안에 4 백만 개 이상의 PID를 롤링 할 수있을 정도로 프로세스를 빠르게 생성하더라도 systemd "이 pid가 아직 살아 있습니까?이 pid가 아직 살아 있습니까?" 필요 하지 않기 때문에 ; 이미 직계 자식 프로세스가 아직 존재하는지 여부에 대해 이미 알고 있습니다 (일반 SIGCHLD 및 waitpid ()를 통해). 따라서 SIGTERM 이후에 프로세스가 종료 된 것을 확인하면 해당 시점에서 단순히 서비스를 '비활성'으로 표시합니다. SIGKILL을 확인, 대기 및 전송하는 데 전혀 영향을 미치지 않습니다.
grawity

답변:


26

systemd는 이미 이것을 즉시 지원하며 기본적으로 활성화되어 있습니다.

사용자 정의 할 수있는 유일한 작업은 시간 초과입니다 TimeoutStopSec=. 예를 들면 다음과 같습니다.

[Service]
TimeoutStopSec=2

이제 systemd는 SIGTERM을 전송하고 서비스가 종료 될 때까지 2 초 동안 기다립니다. 그렇지 않으면 SIGKILL을 전송합니다.

서비스가 시스템을 인식하지 못하는 경우을 사용하여 PID 파일의 경로를 제공해야 할 수 있습니다 PIDFile=.

마지막으로, 데몬이 많은 프로세스를 생성한다고 언급했습니다. 이 경우 KillMode=control-groupcgroup의 모든 프로세스에 신호를 보내도록 설정 하고 systemd 할 수 있습니다.


고맙습니다. 마지막 질문 : 서비스가 시스템을 인식하지 못한다고 가정 해 봅시다. systemd가 PID 파일을 작성 / 관리 할 수 ​​있도록이 서비스의 시스템 스크립트에 무엇을 추가 할 수 있습니까? 또한 서비스는 템플릿 단위를 통해 다중 인스턴스가 될 수 있으므로 일반적으로`systemctl start foo_dameon@1.service "를 통해 서비스를 시작하므로 스크립트의 PID 파일 논리에 영향을 미치겠습니까?
Cloud

4
@DevNull systemd는 PID 파일을 만들거나 관리하지 않습니다. 그렇게 할 이유가 없습니다. 서비스가 자체 PID 파일을 작성하지 않는 경우 가능하면 포 그라운드에서 (데몬 화 대신) 실행되고 시스템 Type=simple단위로 설정되도록 구성하십시오 .
Michael Hampton

1
서비스에 종속 된 서비스가있는 Type=forking경우 Type = simple이 수행 할 수없는 '완료'상태 일 때 시스템에 서비스를 올바르게 알리는 이점이 있습니다. PID 파일이 없어도 데몬 화는 문제가되지 않습니다. systemd는 어쨌든 주요 프로세스를 추적합니다.
grawity

1
@grawity 사실 충분히 ... 서비스가 실제로 서비스를 시작할 준비가되기 전에 서비스를 초기화하는 것은 내 경험이었습니다. systemd-aware 서비스를 사용하는 Type=notify것이 systemd에 가장 적합하며 많은 공통 서비스가 이미이를 수행합니다. 그러나 아마도이 레거시 서비스는 아닙니다. OP의 경우 많은 프로세스를 생성하는 서비스가 있습니다. 체계화 된 문서 는이 경우에 대해 경고 합니다.
Michael Hampton

1

아무도 필요 없음을 언급하지 않았 Type=oneshot으므로 시간 초과 실패로 인해 종료되는 완전한 예제가 있습니다.

[Unit]
Description=timeout test

[Service]
Type=oneshot
TimeoutStartSec=2
ExecStart=/bin/sleep 10
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.