You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

CentOS7下Systemd管理Docker容器无法进入Active(Running)状态的解决咨询

解决systemd无法正确识别Docker容器运行状态的问题

你的问题核心在于systemd服务类型和Docker容器启动方式不匹配,导致systemd无法正确判断容器是否处于运行状态。下面我会分析问题原因,并给出几种可行的解决方案:

问题根源分析

  1. Type=forking不适合当前场景:这个类型要求ExecStart的进程fork后父进程退出,systemd追踪子进程。但你用docker start -a会附着到容器进程,一直阻塞systemd,导致服务卡在Activating(start);去掉-a的话,docker start执行完就退出,systemd找不到要追踪的子进程,直接标记服务为Inactive(dead)
  2. 超时问题:即使设置了TimeoutStartSec=3000,systemd对forking类型的进程有默认的进程追踪逻辑,一旦它认为找不到预期的子进程,就会提前触发超时,和你设置的时间无关。

解决方案

方案一:改用Type=simple,让systemd直接监控前台运行的容器

这是最推荐的方案,能让systemd准确追踪容器状态,还能实现容器崩溃自动重启。修改你的[Service]部分如下:

[Service]
Type=simple
TimeoutStartSec=3000
WorkingDirectory=/home/user/Downloads/MS_0.3.4_artifact
ExecStartPre=-/bin/docker rm -f eb-mapping-service-container
ExecStartPre=/home/user/Downloads/MS_0.3.4_artifact/deploy.sh /home/user/Downloads/MS_0.3.4_artifact/eb-mapping-service.tgz
# 去掉-d参数,让docker run在前台运行,systemd直接监控这个进程
ExecStart=/bin/docker run -v /dev/log:/dev/log --log-driver=journald --network=bridge -p 9090:9090 --name eb-mapping-service-container eb-mapping-service /bin/bash -c "cd /build/MappingService; ./start_multiple_clients_mapping_service.sh"
ExecStop=/bin/docker stop eb-mapping-service-container
# 可选:容器崩溃时自动重启
Restart=always

为什么这样有效Type=simple适用于ExecStart启动的进程就是前台运行的主进程,docker run去掉-d后会在前台运行容器,systemd能直接监控这个进程的状态,容器正常运行时服务就会显示Active(Running),容器崩溃时systemd还能自动重启它。

方案二:使用Type=oneshot+RemainAfterExit=yes,适配后台容器

如果你习惯用-d后台启动容器,可以用这个方案,让systemd知道服务执行完启动命令后,容器会在后台持续运行:

[Service]
Type=oneshot
# 告诉systemd,即使ExecStart的命令执行完退出,也要保持服务为Active状态
RemainAfterExit=yes
TimeoutStartSec=3000
WorkingDirectory=/home/user/Downloads/MS_0.3.4_artifact
ExecStartPre=-/bin/docker rm -f eb-mapping-service-container
ExecStartPre=/home/user/Downloads/MS_0.3.4_artifact/deploy.sh /home/user/Downloads/MS_0.3.4_artifact/eb-mapping-service.tgz
ExecStart=/bin/docker run -v /dev/log:/dev/log -d --log-driver=journald --network=bridge -p 9090:9090 --name eb-mapping-service-container eb-mapping-service /bin/bash -c "cd /build/MappingService; ./start_multiple_clients_mapping_service.sh"
ExecStop=/bin/docker stop eb-mapping-service-container
# 可选:停止后清理容器
ExecStopPost=-/bin/docker rm -f eb-mapping-service-container

注意:这个方案下服务状态会显示为Active(Exited),但这是正常的,因为服务的启动命令已经执行完成,容器在后台运行,systemd会正确执行ExecStop来停止容器。

验证修改效果

修改完服务文件后,执行以下命令生效:

sudo systemctl daemon-reload
sudo systemctl restart MappingService.service
sudo systemctl status MappingService.service

现在你应该能看到服务处于正常的Active状态,不会再卡在启动阶段或提前超时。

内容的提问来源于stack exchange,提问作者Oren_C

火山引擎 最新活动