클라우드 가상 머신에서 정기적인 작업이 실행되고 있습니다. 이 머신 유형은 매우 비싸기 때문에 부팅 시 시작하고 스크립트를 실행한 다음 머신을 종료하여 비용을 절약하는 systemd 장치 서비스를 가지고 있습니다. 이는 설계된 대로 작동합니다.
로그인하고 service [] stop
명령을 실행하면 당연히 시스템이 즉시 종료되기 때문에 시스템을 유지 관리하는 데 어려움을 겪고 있습니다.
나는 이것을 사용할 수 있어야 한다고 생각 OnFailure
하지만, 어떤 이유로든 스크립트가 실패하는 경우(충돌 시 VM이 회전하는 대신) 시스템이 종료되기를 원합니다. 아니면 일부 용도 ExecStop
?
세 가지 상황이 발생합니다.
- 프로세스가 올바르게 실행되고 종료되며(예: 종료 코드 0) 시스템 전원이 꺼집니다.
- 프로세스 충돌(예: 종료 코드 != 0), 시스템 전원 공급 중단
- 사용자에 의해 서비스가 종료/일시 중단되었습니까? 시스템이 켜져 있음
간단한 해결책은 시작, 로그인, 비활성화, 다시 시작(서비스가 이미 시작되었으므로), 유지 관리 작업 수행 및 다시 활성화하기 전에 서비스에 1분의 유예 기간을 제공하는 것입니다. 그런데 이건 좀 엉성한 것 같습니다. 참고로 서비스 정의는 다음과 같습니다.
[Unit]
Description="Run job"
After=network.target
StartLimitInterval=200
StartLimitBurst=30
OnFailure=systemd-poweroff.service
[Service]
Type=simple
Restart=on-failure
RestartSec=30
ExecStartPre=/bin/sleep 60
ExecStart=/my/script.sh
ExecStopPost=sudo systemctl poweroff -i
User=foo
[Install]
WantedBy=multi-user.target
보안 인식보다는 환경 설정으로 인해 스크립트가 일반 사용자로 실행되므로 여기서는 sudo가 사용됩니다(이 계정에는 전원 끄기를 위한 비밀번호 없는 sudo 권한이 특별히 부여됩니다).
답변1
poweroff
액션에서 실행하는 대신 ExecStopPost
별도의 서비스로 이동하세요. 즉, "작업 실행" 서비스를 다음과 같이 만드세요.
[Unit]
Description="Run job"
After=network.target
Requires=my-poweroff.service
Before=my-poweroff.service
[Service]
Type=oneshot
Restart=on-failure
RestartSec=30
ExecStart=/my/script.sh
User=foo
[Install]
WantedBy=multi-user.target
스크립트가 완료될 때까지 서비스가 "시작"되지 않으므로 Type=oneshot
대신 사용하고 있습니다 . 를 사용하여 /dependent 를 통해 정전을 트리거하면 이 작업과 종료 작업이 시작되기 Type=simple
때문에 이는 중요합니다.Requires=
Before=
Type=simple
동시에. 사용은 Type=oneshot
서비스가 종료될 때까지 종료 작업이 실행되지 않음을 의미합니다.
그런 다음 에는 my-poweroff.service
다음이 있습니다.
[Unit]
ConditionPathExists=!/run/nopoweroff
[Service]
Type=simple
ExecStart=/usr/bin/systemctl poweroff -i
이제 "작업 실행" 서비스가 완료될 때까지 poweroff
차단 하려면 .touch /run/nopoweroff