容器生命周期完全等同于其PID 1进程的生命周期:该进程在宿主机上启动即容器运行,退出即容器终止;容器本质是受Namespace隔离和Cgroups限制的普通进程,PID 1决定存续,如bash非交互执行完退出则容器秒退。
容器生命周期就是宿主机上一个特殊进程的生命周期,二者完全同步——容器启动,对应一个 pid 1 进程在宿主机上诞生;容器停止,那个进程就退出或被终止。
容器本质是带隔离的普通进程
从内核视角看,Docker 容器不是虚拟机,它就是一个被 Linux Namespace 隔离、被 Cgroups 限制的普通进程(或进程组)。它拥有独立的 PID、网络、文件系统视图,但底层仍运行在宿主机内核中,和你手动执行 sleep 3600 或 nginx -g "daemon off;" 没有本质区别。
关键点在于:PID 1 进程决定容器存续。如果这个进程退出,整个容器立即进入 exited 状态,不管其他子进程是否还在跑。
常见状态与宿主机进程的映射关系
- created:docker create 成功后,容器配置已写入本地数据库,但宿主机上尚未生成任何进程
- running:docker run 或 docker start 后,宿主机上出现一个 PID 1 进程(如 /usr/sbin/nginx),且该进程持续运行
- exited:PID 1 进程退出(比如命令执行完、崩溃、被 kill -9),容器状态立刻变为 exited
- paused:通过 cgroups freezer 子系统将 PID 1 及其所有子进程整体冻结,进程仍在内存中但不被调度
- stopped:PID 1 已退出,资源已释放,只剩容器元数据保留在磁盘
为什么容器秒退?根本原因在进程行为
新手常遇到 docker run ubuntu:22.04 启动即退出,就是因为镜像默认 CMD 是 /bin/bash,而 bash 在非交互模式下执行完就退出了——PID 1 消失,容器生命周期终结。
要让容器“活下来”,必须确保 PID 1 是一个前台运行、不主动退出的长期服务进程,例如:
- Nginx:用 nginx -g "daemon off;" 关闭守护模式
- Python Web 应用:用 gunicorn --bind 0.0.0.0:8000 app:app,不加 -D
- 调试时:直接运行 tail -f /dev/null 或 sleep infinity
管理容器 = 管理它的主进程
docker stop 实际是对 PID 1 发送 SIGTERM,等待优雅退出;超时后发 SIGKILL。docker pause 则是调用 cgroups freezer 接口冻结整个进程树。docker logs 查看的,本质上就是该进程的标准输出和标准错误流。
你可以用 ps aux | grep nginx 在宿主机上看到容器里的 nginx 主进程,也能用 kill -15


















