소켓에서 서비스 중지

소켓에서 서비스 중지

원격으로 서비스를 중지하는 데 문제가 있습니다.

간단한 소켓/서비스 쌍이 있습니다.

# /etc/systemd/system/foo.socket
[Unit]
Description=The socket

[Socket]
ListenStream=11111
# /etc/systemd/system/foo.service
[Unit]
Description=The service

[Service]
Type=simple
ExecStart=sleep infinity

그 후에는 systemctl start foo.socket다음과 같습니다:

foo.socket:  active (listening)
foo.service: inactive (dead)

그런 다음 다른 시스템에 대한 연결을 설정하면 다음과 같은 결과를 netcat 10.10.1.16 11111얻습니다.

foo.socket:  active (running)
foo.service: active (running)

완벽한!

SIGTERM이제 연결( to ) 을 종료하면 netcat다음을 얻습니다.

foo.socket:  active (running)
foo.service: active (running)

하지만 나는 다음과 같이 예상했습니다.

foo.socket:  active (listening)
foo.service: inactive (dead)

TCP 연결을 사용하여 원격으로 서비스를 중지하는 방법은 무엇입니까?

나는 시도했다:

  • Accept=yes그리고[email protected]
  • 서비스를 제공 PartOf=foo.socket하거나Requires=foo.socket
  • StandardInput=socket그리고 표준 출력과 표준 오류.

답변1

대신에 /bin/sleep infinity다른 것을 실행하고 싶습니다.

[Service]
Type=simple
ExecStart=foo
StandardInput=socket

다음은 어디에 있습니까 foo?

#include <stdio.h>
int main(int, char**) {
  char buf[256];
  while(scanf("%255s",buf) > 0) {}
  return 0;
}
#!/bin/sh
while read line; do
  echo "$line"
done < "${1:-/dev/stdin}"
#!/usr/bin/python3
import sys
for line in sys.stdin:
    pass
#!/usr/bin/perl
while (<>) {
  if (eof()) { exit }
}

설명하다:

서비스 를 사용하면 Type=simple프로세스가 종료되는 즉시 서비스가 중지됩니다 ExecStart. 따라서 연결을 닫더라도 애플리케이션이 종료되어야 한다는 것을 모르기 때문에 서비스가 중지되지 않습니다. Systemd는 SIGTERM을 보내지 않으며 그럴 필요도 없습니다.

ExecStart대신, 동일한 작업을 수행하는 네 가지 프로세스(C, sh, python, perl)의 구현을 제공합니다 . 즉, stdin을 더 이상 사용할 수 없을 때까지 stdin에서 읽습니다. 연결이 닫히면 스트림이 종료됩니다. 이는 stdin이 종료됨을 의미합니다. 따라서 EOF를 얻을 때까지 stdin을 계속 읽은 다음 종료하십시오. 프로세스가 종료되면 서비스가 중지됩니다.


내장 기능

위 스크립트 중 하나를 배포하지 않으려면 stdin을 수신하고 EOF에서 종료하는 내장 도구 중 하나를 사용하세요. 부작용은 그들이 실제로 뭔가를 할 수도 있다는 것입니다. 가장 먼저 생각할 수 있는 것은 입니다 grep -. EXIT_FAILURE일치하는 항목이 없으면 반환되므로 -연결이 닫힐 때마다 서비스가 실패하지 않도록 접두사를 붙입니다.

[Service]
Type=simple
ExecStart=-/bin/grep -
StandardInput=socket

이 프로세스를 활용하는 것이 재미있을 것이라고 생각한다면 연결을 통해 유용한 일을 할 수 있습니다. 제가 생각할 수 있는 두 번째 프로그램은 python3. 이제 전체 통역사가 유휴 상태로 앉아 귀하를 위해 무언가를 하도록 할 수 있습니다. 샌드박싱을 추가하지 않았지만 systemd가 작동하는 경우 위험할 수 있습니다 DynamicUser=.

[Service]
Type=simple
ExecStart=/usr/bin/python3
StandardInput=socket
DynamicUser=yes

클라이언트 측에서 연결이 설정되었는지 확인하려면 cat먼저 다음과 같은 상용구 텍스트를 작성하는 것이 좋습니다.

echo "established" > /usr/local/etc/simple/start_text

그런 다음 systemd에게 해당 텍스트를 cat하고 stdin을 지정하도록 지시합니다.

[Service]
Type=simple
ExecStart=-cat /usr/local/etc/simple/start_text -
StandardInput=socket

이제 netcat연결이 설정되면 클라이언트가 인쇄물을 받게 됩니다.

Accept=yesand 를 사용해야 한다는 점도 주목할 가치가 있습니다 [email protected]. 그렇지 않으면 systemd는 애플리케이션이 들어오는 연결을 수락할 것으로 예상하지만 여기서는 그렇지 않습니다.

관련 정보