You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Supervisord容器通过Shell脚本管理容器的PID显示异常问题

解决方案:让supervisorctl显示Docker容器的PID

问题核心是Supervisor默认监控的是它启动的子进程(即脚本中的docker start -a进程),而Docker容器的PID属于宿主机的PID命名空间,与Supervisor容器的命名空间隔离。要让supervisorctl status显示容器PID,需要通过PID文件映射的方式实现:

1. 修改启动脚本kafka_start.sh

更新脚本逻辑,在启动容器后将容器的宿主机PID写入指定文件,并添加信号处理确保停止时正确清理:

#!/bin/bash

# 定义容器停止与清理函数
stop_container() {
    docker stop lbrain-kafka > /dev/null 2>&1
    rm -f /var/log/supervisor/kafka_container.pid
    exit 0
}

# 捕获Supervisor发送的停止信号,触发容器停止操作
trap stop_container SIGTERM SIGINT

# 清理旧容器(如果存在)
if docker ps -a --filter name=lbrain-kafka -q | grep -q .; then
    docker stop lbrain-kafka && docker rm lbrain-kafka
fi

# 创建并启动Kafka容器
docker create -p 9092:9092 -p 19092:19092 --privileged \
    -v /etc/localtime:/etc/localtime:ro \
    -v /opt/qihoo/soc/kafka/config/kraft/server.properties:/opt/kafka/config/kraft/server.properties:ro \
    -v /data01/entdata/kafka:/tmp/kafka-logs \
    -e JAVA_OPTS="$JAVA_OPTS -Duser.timezone=Asia/Shanghai" \
    -e KAFKA_HEAP_OPTS="-Xmx1g -Xms1g" \
    --name lbrain-kafka kafka:2.13-3.5.1

docker start lbrain-kafka

# 获取容器的宿主机PID并写入文件(路径需在Supervisor容器内可访问)
CONTAINER_PID=$(docker inspect --format '{{.State.Pid}}' lbrain-kafka)
echo $CONTAINER_PID > /var/log/supervisor/kafka_container.pid

# 阻塞脚本直到容器停止,避免Supervisor误判进程退出
docker wait lbrain-kafka

# 容器停止后清理PID文件
rm -f /var/log/supervisor/kafka_container.pid

2. 修改Supervisor配置kafka.ini

添加pidfile参数指定容器PID文件路径,并配置进程停止相关选项:

[program:kafka]
command=sh /opt/supervisor/script/kafka_start.sh
environment=JAVA_OPTS="-Dfastjson.parser.safeMode=true"
priority=150
autostart=false
startsecs=30
user=root
redirect_stderr=true
stdout_logfile_maxbytes=10MB
stdout_logfile_backups=10
stdout_logfile=/var/log/supervisor/kafka_supervisord.log
# 指定容器PID文件路径,Supervisor将读取此文件显示PID
pidfile=/var/log/supervisor/kafka_container.pid
# 停止时终止整个进程组,确保脚本与容器都能正确停止
stopasgroup=true
killasgroup=true
# 定期检查进程状态,确保PID文件更新后能被识别
check_interval=5

3. 生效配置

重启Supervisor容器或重新加载配置:

docker exec -it lbrain-supervisor supervisorctl reload

原理说明

  • Supervisor通过pidfile选项读取外部文件中的PID,从而在supervisorctl status中显示容器的宿主机PID。
  • 脚本通过docker wait保持运行,避免Supervisor误判进程退出;同时添加信号捕获,确保执行supervisorctl stop kafka时能先停止容器再退出脚本。
  • 由于/var/log/supervisor已挂载到宿主机目录,PID文件会持久化,Supervisor容器内可正常读取。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 03:43:19