容器生命周期核心是pid 1进程终止直接触发exited状态,docker守护进程监听该事件并依--restart策略响应:always无条件重启,on-failure仅非零退出码重启,unless-stopped排除手动停止的容器。
容器异常退出时,生命周期触发机制的核心是主进程终止 → 容器状态变更 → 重启策略响应。docker 守护进程持续监听容器 pid 1 的运行状态,一旦该进程非正常结束(如崩溃、被 oom killer 杀掉、未处理 sigterm 等),容器立即进入 exited 状态,并依据预设的 --restart 策略决定是否重建。
主进程退出直接决定容器生命周期终点
容器不是操作系统虚拟机,它没有“后台服务”概念——其生命周期完全绑定于 PID 1 进程。只要这个进程退出(无论退出码是 0、1 还是 137),容器就停止运行,状态变为 exited。例如:
-
docker run alpine echo "done"执行完即退出,状态为Exited (0),属正常生命周期结束; -
docker run --memory=50m nginx在内存超限时被内核发 SIGKILL,退出码为 137,状态也是exited,但属于异常退出。
Docker 守护进程实时监听并驱动状态流转
守护进程通过 containerd 或 runc 底层运行时订阅容器状态事件。当检测到 exited 事件后,会立即读取容器元数据中的 restart 策略字段,触发对应动作:
- 配置
--restart=always:立刻调用containerd创建新实例,复用镜像、卷、网络等配置; - 配置
--restart=on-failure:3:先检查退出码,仅非零时尝试重启,且最多 3 次; - 配置
--restart=unless-stopped:行为同always,但跳过已被docker stop显式停用的容器。
退出码是判断“异常”的关键上下文
虽然 always 策略不区分退出原因,但运维诊断必须依赖退出码定位根因:
-
Exited (0):主进程主动结束,常见于一次性命令或脚本执行完毕; -
Exited (1):应用内部报错,如 Python 脚本抛出未捕获异常; -
Exited (137):被系统强制终止,99% 是内存超限(OOM); -
Exited (143):收到 SIGTERM 后正常退出,说明应用支持优雅关闭。
重启不是万能的,机制有明确边界
以下情况会导致自动恢复失效:
- Docker 守护进程自身宕机或未启动,所有重启逻辑停止;
- 容器配置了
--restart=no(默认值),退出后静默保持exited状态; - 宿主机资源严重不足(如磁盘满、inode 耗尽),导致新建容器失败,日志中会出现
failed to create task类错误; - 镜像损坏或挂载路径不可用,重启时拉取/初始化阶段直接失败,容器卡在
created状态无法进入running。











