종료 시 시스템 사용자 범위 종료 방지

종료 시 시스템 사용자 범위 종료 방지

나는 LXC 컨테이너 관리자 역할을 할 Debian Bookworm 머신을 만듭니다. 시스템 사용자 범위를 생성하는 lxc-unpriv-start 명령으로 시작된 권한 없는 LXC 컨테이너를 사용합니다. 서버 시작 시 컨테이너를 시작하고 서비스 중지 시 완전한 종료를 시작하는 서비스를 만듭니다. 모든 컨테이너를 종료하는 데 2~3분 정도 걸릴 수 있습니다. 기본 서비스를 수동으로 중지하면 모든 것이 잘 작동합니다. 내 서비스가 컨테이너 종료를 올바르게 기다리지만 systemd-logind가 모든 사용자 세션을 종료하여 내 컨테이너도 잔인하게 종료하기 때문에 서버를 종료할 때 문제가 발생합니다.

수면 전용 쉘을 생성하는 상황을 시뮬레이션하고 다음과 같이 실행합니다.

/usr/bin/systemd-run --user --scope -p "Delegate=yes" wait.sh &

종료하면 종료됩니다. 이 살인을 어떻게 피할 수 있습니까?

답변1

링거가 그 문제를 해결해야 합니다.

에서https://www.freedesktop.org/software/systemd/man/loginctl.html

한 명 이상의 사용자에 대해 사용자 지연을 활성화/비활성화합니다. 특정 사용자에 대해 활성화된 경우 부팅 시 해당 사용자에 대해 사용자 관리자가 생성되고 로그아웃 후에도 유지됩니다. 이를 통해 로그인하지 않은 사용자가 장기 실행 서비스를 실행할 수 있습니다. 하나 이상의 사용자 이름이나 숫자 UID를 인수로 사용합니다. 인수를 지정하지 않으면 호출자 세션의 사용자에 대해 느린 시간을 활성화/비활성화합니다.

loginctl enable-linger <username>

사용자 세션에 대해 링거를 활성화하면 로그아웃한 후에도 또는 시스템 종료 중에도 컨테이너가 계속 실행될 수 있습니다. 이렇게 하면 systemd-logind가 사용자 세션 및 관련 컨테이너를 강제로 종료하는 것을 방지하여 정상적으로 종료할 수 있는 기회를 제공합니다.

답변2

컨테이너 중지 명령이 "차단"(즉, 컨테이너가 중지된 후 종료)된다고 가정하면 쉘에서 직접 실행하는 대신 시스템 사용자 서비스를 사용하여 컨테이너 시작 명령을 실행할 수 있습니다. 여러 컨테이너를 시작해야 한다고 가정하면 서비스 템플릿을 $HOME/.config/systemd/user/. 서비스 템플릿의 파일 이름은 @앞에 있어야 합니다 .service(예: [email protected]).

다음은 귀하를 위한 예입니다.

[Unit]
PartOf=%i.scope
After=%i.scope

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/systemd-run --user --scope -u %i sh -c 'sleep 1d &'
ExecStop=/usr/bin/sleep 1m

보시다시피, 범위 이름은 생성된 이름 대신 "알려진" 이름이어야 합니다.

템플릿을 사용하면 이제 예를 들어 컨테이너를 시작할 수 있습니다 systemctl --user start test@container-a. 이제 "에이전트" 서비스가 중지될 때까지(즉, ExecStop=명령이 종료될 때까지) 해당 범위가 유지되는 것을 볼 수 있습니다 .

systemctl --user daemon-reload서비스(템플릿) 파일을 변경할 때마다 실행해야 할 수도 있습니다 .

PS 분명히 컨테이너 시작/중지 명령에 추가 컨테이너별 인수(범위 이름과 동일한 문자열이 아님)를 전달해야 하는 경우 템플릿을 사용하는 대신 여러 서비스 파일을 작성해야 할 수 있습니다.

관련 정보