"원샷" 서비스가 처음 실패할 때 재시도하도록 하려면 어떻게 해야 합니까?

"원샷" 서비스가 처음 실패할 때 재시도하도록 하려면 어떻게 해야 합니까?

systemd 서비스 매뉴얼을 여러 번 읽었지만 여전히 기본 systemd 모드를 파악할 수 없습니다.

부팅 시 시작 프로세스(예: Docker 컨테이너 또는 드라이브 포맷)를 한 번 실행하고 성공적으로 완료하고 싶습니다. 그러나 이에 대해 Type=oneshot을 사용하면 Restart=on-failure를 사용할 수 없으며 실패할 경우 작업을 다시 시도하지 않습니다. 여기서 분명한 것을 놓치고 있습니까?

또한 Restart=on-failure를 사용하여 Type=simple 설정을 시도했지만 많은 경우 맨페이지의 원샷 서비스에서 제공하는 다음 동작이 필요합니다.

oneshot은 단순하게 동작하지만 systemd가 후속 유닛을 시작하기 전에 프로세스가 종료되어야 합니다.

고쳐 쓰다:

답변1

내가 시도하는 한 가지 가능한 해결 방법은 다음과 같습니다.

  [Unit]
    Description=Tags instance and EBS vols
    After=docker.service
    Requires=docker.service

    [Service]
    ExecStartPre=/usr/bin/docker run --rm -v /opt/tag.sh:/tag.sh -v /opt:/ack --entrypoint=/bin/sh alpine /tag.sh
    ExecStartPre=/usr/bin/sh -c '[[ -e /opt/TAG_SUCCESS ]]'
    ExecStart=/usr/bin/rm /opt/TAG_SUCCESS
    Restart=on-failure
    RestartSec=30

스크립트 실행이 끝나는 위치입니다 tag.sh. touch /ack/TAG_SUCCESS나는 이것이 원하는 동작에 매우 가깝다고 생각합니다. ExecStartPre실행은 순차적으로 이루어지며, 호출하기 전에 성공적인 완료를 기다리고 ExecStart, 유닛은 Starting한 번만 고려되며 ExecStart, 이 시점에서 우리는 시작 작업을 완료했다고 확신합니다.

하지만 여전히 거대한 해킹처럼 느껴지나요?

답변2

둘러본 후 systemd의 notify-type에 oneshot다음과 exec결합된 속성이 있음을 발견했습니다.

알림은 exec처럼 동작하지만 서비스는 시작이 완료된 후 sd_notify(3) 또는 동등한 호출을 통해 알림 메시지를 보낼 것으로 예상됩니다. 이 알림 메시지를 보낸 후 systemd는 후속 장치를 시작합니다. 이 옵션을 사용하는 경우 Systemd에서 제공하는 알림 소켓에 대한 액세스를 열도록 NotifyAccess=(아래 참조)를 설정해야 합니다. NotifyAccess=가 없거나 없음으로 설정된 경우 기본으로 강제 설정됩니다.

안에:

exec 유형은 단순 유형과 유사하지만 서비스 관리자는 기본 서비스 바이너리를 실행한 후 즉시 해당 단위가 시작되는 것으로 간주합니다. 서비스 관리자는 이 시간까지 후속 장치의 시작을 연기합니다. (즉, 단순은 fork()가 반환된 후 즉시 추가 작업을 계속하는 반면, exec는 서비스 프로세스의 fork() 및 execve()가 성공할 때까지 계속되지 않습니다.) 이는 exec 서비스를 시작하는 명령줄을 의미합니다. systemctl을 사용하면 서비스 바이너리를 성공적으로 호출할 수 없는 경우(예: 선택한 User=가 존재하지 않거나 서비스 바이너리가 누락된 경우) 실패를 보고합니다.

즉, 조합 simpleoneshot동작:

# <your service>.service
[Unit]
Description=Your awesome service

[Service]
ExecStart=/usr/local/bin/your-daemon-script
Restart=on-failure
RestartSec=30
NotifyAccess=all 
# your-daemon-script
# Start everything
# ...
# If an error happens here, the service will restart
# If everything went fine systemd-notify --ready is used to notify systemd about that.
# After notifying systemd, systemd will switch the services state into ready and then starts other services which had to wait for this serivce to get ready.
systemd-notify --ready

관련 정보