qemu를 관리하기 위해 systemd를 사용하려고합니다. qemu가 충돌하면 자동으로 다시 시작할 수 있습니다. 다음과 같은 단위 파일이 있습니다.
[Unit]
Description=vm manager
After=network.target
Before=shutdown.target reboot.target poweroff.target halt.target
[Service]
Type=forking
ExecStart=/root/vm/vm-manager.sh start-vm
ExecStop=/root/vm/vm-manager.sh stop-vm
KillSignal=SIGCONT
PIDFile=/root/vm/run/pid
WatchdogSec=30s
Restart=on-failure
[Install]
WantedBy=multi-user.target
애플리케이션에서 sd_notify(0, "WATCHDOG=1")를 호출하지 않지만 30초 후에도 서비스가 "실패" 상태로 전환되지 않습니다. 두 가지 질문이 있습니다.
- 이 서비스는 30초 후에 다시 시작되어야 할 것 같습니다. 서비스를 종료하거나 중지할 때까지 계속 실행되는 이유는 무엇입니까?
- qemu를 수동으로 종료하면(qemu 프로세스가 기본 프로세스로 설정되어 있음) 서비스가 기다리지 않고 즉시 다시 시작됩니다.
위 두 가지 질문 외에도 유닛 파일에 오류나 제안 사항이 있으면 자유롭게 제출해 주세요.
감사해요!
답변1
"데몬" 실패와 "서비스" 실패 상태 사이에는 차이가 있습니다.
데몬 실패는 단순히 프로그램이 종료 코드로 0을 반환하는 것 이외의 다른 방식으로 종료되었음을 의미합니다. 이는 Restart=on-failure
"실패한 경우 데몬을 다시 시작합니다"를 의미합니다. 또한 다른 조건에서도 다시 시작할 수 있습니다. 아래 표를 참조하세요.다시 시작 =이는 또한 "실패"가 정확히 무엇을 의미하는지 설명합니다.
귀하의 서비스 파일에 따르면 "서비스" 실패에 대한 정의가 없습니다. 기본 정의는 기본적으로 "데몬이 종료 코드로 0을 반환하는 것 이외의 다른 방식으로 종료되었으며 현재 실행되고 있지 않습니다"라고 생각합니다. 그러나 서비스 파일에는 데몬 프로세스 지금 다시 시작하세요. 따라서 "실패" 상태가 되었지만 잠시 동안 사용자는 이를 알아차리지 못했을 수도 있습니다. 로그 확인을 사용할 수 있습니다 journalctl -u foo.service
.
또한, 메인 프로세스의 PID가 30초 전과 여전히 동일한지 확인해야 합니다. PID가 다른 경우 이는 데몬이 호출되지 않았기 때문에 systemd가 데몬을 종료하고 sd_notify
서비스 파일이 실패 시 다시 시작하라고 말하고 시작 사이에 다시 시작하라고 지시하지 않기 때문에 데몬을 빠르게 다시 시작한다는 의미입니다. (아래 참조).
서비스에 오류 정의가 포함되도록 하려면 다음과 같은 것을 사용해야 합니다.
StartLimitInterval=5min
StartLimitBurst=4
이러한 옵션은 잘 문서화되어 있습니다.여기그러나 이 예에서 둘 다의 기본 의미는 "데몬을 5분 간격으로 4번 이하로 시작합니다. 시작 후 실패하면 해당 간격에 4번 이하로 데몬을 시작합니다. 서비스가 실패한 상태로 간주됩니다." 이런 일이 발생하면 StartLimitAction=
기본값은 없음으로 설정됩니다.
또 다른 구성 가능한 값은 입니다 RestartSec=
. ~에서문서:
서비스를 다시 시작하기 전에 절전 시간을 구성합니다(Restart=를 사용하여 구성). 초 단위의 단위 없는 값 또는 "5min >20s"와 같은 시간 범위 값을 사용합니다. 기본값은 100밀리초입니다.
RestartSec=
이는 기본적으로 systemd가 데몬을 다시 시작하기 전에 최소한 기다려야 함을 의미합니다 .
따라서 이러한 옵션을 모두 결합할 수 있지만 다음 값을 사용한다고 가정합니다.
StartLimitInterval=5min
StartLimitBurst=4
RestartSec=2min
실패의 정의는 다음과 같으므로 서비스는 실패 상태로 전환되지 않습니다.
주어진 5분 간격 내에 서비스가 시작되면 4번 실패합니다.
그러나 systemd는 마지막 실패 후 2분 이내에 서비스를 다시 시작하지 않으므로 서비스가 StartLimitBurst
도착 하지 않습니다 StartLimitInterval
.