Systemd 未在慢速设备上启动依赖服务
Systemd not starting dependent service on slow device
我有一个有趣的问题,我有一个复制器。使用一个容器来划分这个系统并使其可重现,我可以在我强大的笔记本电脑上成功 运行,但是当 运行 在慢速 raspberry Pi 上运行时它失败了。
::::::::::::::
A.service
::::::::::::::
[Unit]
Description=Service A
After=B.service
BindsTo=B.service
[Service]
Type=simple
Restart=always
RestartSec=1
ExecStartPre=/bin/sleep 1
ExecStart=/bin/sleep 100
ExecStartPost=/bin/sleep 1
TimeoutStartSec=10s
[Install]
WantedBy=multi-user.target
::::::::::::::
B.service
::::::::::::::
[Unit]
Description=Service A
After=C.service
BindsTo=C.service
[Service]
Type=simple
Restart=always
RestartSec=1
ExecStartPre=/bin/sleep 1
ExecStart=/bin/sleep 100
ExecStartPost=/bin/sleep 1
TimeoutStartSec=10s
[Install]
WantedBy=multi-user.target
::::::::::::::
C.service
::::::::::::::
[Unit]
Description=Service A
[Service]
Type=simple
Restart=always
RestartSec=1
ExecStartPre=/bin/sleep 1
ExecStart=/bin/sleep 100
ExecStartPost=/bin/sleep 1
TimeoutStartSec=10s
[Install]
WantedBy=multi-user.target
::::::::::::::
Dockerfile
::::::::::::::
FROM ubuntu:18.04
RUN DEBIAN_FRONTEND=noninteractive apt update && apt install -y systemd init socat
COPY *.service /etc/systemd/system/
#RUN systemctl enable A.service
ENTRYPOINT ["/sbin/init"]
::::::::::::::
run.sh
::::::::::::::
docker build -t service .
docker stop -t 0 service && docker rm service
docker run -d --name service --privileged --cap-add SYS_ADMIN service
#docker run -d --cpus="0.3" --name service --privileged --cap-add SYS_ADMIN service
sleep 3
docker exec -it service service A start
sleep 1
docker exec -it service service A status
docker exec -it service service B status
docker exec -it service service C status
这里的意图是有3个服务:A、B、C。依赖关系如下:A->B->C。启动服务 A 时,应启动 B,然后启动 C。在这种情况下,服务是虚拟服务,我尝试在 post 服务之前添加延迟,但问题仍然存在。
在我功能强大的笔记本电脑上,我可以通过在 'docker run' 行中添加“--cpus=0.3”来重现该问题。
对什么可能是罪魁祸首有什么想法吗?
我发现 service
有一个有趣的“特征”:
# avoid deadlocks during bootup and shutdown from units/hooks
# which call "invoke-rc.d service reload" and similar, since
# the synchronous wait plus systemd's normal behaviour of
# transactionally processing all dependencies first easily
# causes dependency loops
if ! systemctl --quiet is-active multi-user.target; then
sctl_args="--job-mode=ignore-dependencies"
fi
显然,如果 systemctl
与 --job-mode=ignore-dependencies
一起启动,则不太可能工作:-)。
正如预期的那样,以下序列有效:
docker run -d --name service --privileged --cap-add SYS_ADMIN service
docker exec -ti service systemctl start multi-user.target
docker exec -it service service A start
显然,最好的选择是将 service A start
替换为 systemctl start A
。顺便说一句,service
特定于 Ubuntu 而 systemctl
对几乎所有 Linux 分布都是通用的。
我认为在 docker 容器中手动启动的任何服务都会受到此问题的影响。
但是,我仍然没有解释为什么它可以在您功能强大的笔记本电脑上运行。
我有一个有趣的问题,我有一个复制器。使用一个容器来划分这个系统并使其可重现,我可以在我强大的笔记本电脑上成功 运行,但是当 运行 在慢速 raspberry Pi 上运行时它失败了。
::::::::::::::
A.service
::::::::::::::
[Unit]
Description=Service A
After=B.service
BindsTo=B.service
[Service]
Type=simple
Restart=always
RestartSec=1
ExecStartPre=/bin/sleep 1
ExecStart=/bin/sleep 100
ExecStartPost=/bin/sleep 1
TimeoutStartSec=10s
[Install]
WantedBy=multi-user.target
::::::::::::::
B.service
::::::::::::::
[Unit]
Description=Service A
After=C.service
BindsTo=C.service
[Service]
Type=simple
Restart=always
RestartSec=1
ExecStartPre=/bin/sleep 1
ExecStart=/bin/sleep 100
ExecStartPost=/bin/sleep 1
TimeoutStartSec=10s
[Install]
WantedBy=multi-user.target
::::::::::::::
C.service
::::::::::::::
[Unit]
Description=Service A
[Service]
Type=simple
Restart=always
RestartSec=1
ExecStartPre=/bin/sleep 1
ExecStart=/bin/sleep 100
ExecStartPost=/bin/sleep 1
TimeoutStartSec=10s
[Install]
WantedBy=multi-user.target
::::::::::::::
Dockerfile
::::::::::::::
FROM ubuntu:18.04
RUN DEBIAN_FRONTEND=noninteractive apt update && apt install -y systemd init socat
COPY *.service /etc/systemd/system/
#RUN systemctl enable A.service
ENTRYPOINT ["/sbin/init"]
::::::::::::::
run.sh
::::::::::::::
docker build -t service .
docker stop -t 0 service && docker rm service
docker run -d --name service --privileged --cap-add SYS_ADMIN service
#docker run -d --cpus="0.3" --name service --privileged --cap-add SYS_ADMIN service
sleep 3
docker exec -it service service A start
sleep 1
docker exec -it service service A status
docker exec -it service service B status
docker exec -it service service C status
这里的意图是有3个服务:A、B、C。依赖关系如下:A->B->C。启动服务 A 时,应启动 B,然后启动 C。在这种情况下,服务是虚拟服务,我尝试在 post 服务之前添加延迟,但问题仍然存在。
在我功能强大的笔记本电脑上,我可以通过在 'docker run' 行中添加“--cpus=0.3”来重现该问题。
对什么可能是罪魁祸首有什么想法吗?
我发现 service
有一个有趣的“特征”:
# avoid deadlocks during bootup and shutdown from units/hooks
# which call "invoke-rc.d service reload" and similar, since
# the synchronous wait plus systemd's normal behaviour of
# transactionally processing all dependencies first easily
# causes dependency loops
if ! systemctl --quiet is-active multi-user.target; then
sctl_args="--job-mode=ignore-dependencies"
fi
显然,如果 systemctl
与 --job-mode=ignore-dependencies
一起启动,则不太可能工作:-)。
正如预期的那样,以下序列有效:
docker run -d --name service --privileged --cap-add SYS_ADMIN service
docker exec -ti service systemctl start multi-user.target
docker exec -it service service A start
显然,最好的选择是将 service A start
替换为 systemctl start A
。顺便说一句,service
特定于 Ubuntu 而 systemctl
对几乎所有 Linux 分布都是通用的。
我认为在 docker 容器中手动启动的任何服务都会受到此问题的影响。
但是,我仍然没有解释为什么它可以在您功能强大的笔记本电脑上运行。