首页/云/Docker 容器速查/PID 1 信号与僵尸进程:--init
容器排障52 条

PID 1 信号与僵尸进程:--init

容器里 PID 1 承担信号转发与孤儿进程回收:shell 当 PID 1 时常把 SIGTERM 吞掉、留下僵尸;--init 注入轻量 init 解决。

Docker 容器速查云更新于 2026-10-13

1 号进程的职责

容器里的 1 号进程承担信号转发与孤儿进程回收:用 shell 当 1 号进程时,常把终止信号吞掉并留下僵尸进程。注入一个轻量 init 进程是代价很小的解决办法。

基本信息

症状停止容器无响应、僵尸进程累积
机制1 号进程需要转发信号并回收子进程
解决方案注入 init 进程、用直接执行形式入口、或应用自带处理
排查看进程列表与状态字段
典型环境入口是 shell 脚本的镜像

典型使用场景

  • 停止容器要等超时才退出甚至被强杀
  • 容器内出现大量僵尸进程
  • 排查应用升级后停止行为变化的原因
  • 给无法修改入口的镜像做低成本的信号处理补救
  • 梳理镜像入口写法是否合理

验证与观察

验证与观察
docker run -d --init --name app app/base:2.0
docker exec app sh -c 'ps -eo pid,ppid,stat,comm | head -15'   # 观察僵尸进程
docker top app | head -8                                         # 进程视角
docker stop -t 5 app                                             # 验证能否快速优雅退出

有 init 与没有的差别

维度有 init 进程无 init 进程
1 号进程轻量 init镜像入口命令
信号转发由 init 负责shell 未处理则不转发
孤儿进程自动回收累积成僵尸
停止表现收到信号即退出可能等到超时
入口用直接执行形式(数组写法)能让应用直接成为 1 号进程,比 shell 包装更干净。
shell 形式的入口下信号只发给 shell,没写处理逻辑就永远不会转发。
既有镜像没法改入口时,注入 init 是代价很小的补救,但它本身也会占用一个进程。
僵尸进程的父进程通常是 1 号进程,排查时先看进程之间的父子关系。
停止无响应与僵尸进程往往同时出现,属于同一个根因的两种表现。
应用自身实现了信号处理时,优先让应用直接作为 1 号进程运行,减少中间层。
容器内进程很少、入口就是单个可执行文件时,多余包装反而增加排查成本,按实际需要决定是否引入 init。

易错点

  • shell 形式的入口下信号只发给 shell,没写处理逻辑就永远不转发
  • 用强杀代替优雅停止,数据未落盘或连接未清理会留下脏状态
  • 移植到其他编排系统时忽略 1 号进程职责,问题会换个形式复现
  • 只看有没有僵尸进程而不看信号转发,排查方向会偏

数据来源与参考

  • Docker 官方 CLI 参考:docker run --init(docs.docker.com)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌