Docker 笔记(二)容器篇:生命周期、资源限制、退出码与健康检查
容器不是一个小型虚拟机,它是被 namespace 隔离、被 cgroup 限制的一个进程。理解了这点,「为什么一启动就退出」「为什么 JVM 以为自己有 64G 内存」「为什么 exit 137」都能自己解释。这篇讲生命周期、run 参数、cgroup 限制与 JVM 的关系、退出码速查、优雅停机和健康检查。
从一个关键词,发现新的思路。
容器不是一个小型虚拟机,它是被 namespace 隔离、被 cgroup 限制的一个进程。理解了这点,「为什么一启动就退出」「为什么 JVM 以为自己有 64G 内存」「为什么 exit 137」都能自己解释。这篇讲生命周期、run 参数、cgroup 限制与 JVM 的关系、退出码速查、优雅停机和健康检查。
容器的「网络不通」和「文件没权限」是运维群里最高频的两类问题,绝大多数不是 Docker 的 bug,而是网络模型与宿主机的差异没搞清。这篇讲四种网络模式、bridge 到底靠什么打通、-p 与 EXPOSE 的区别、容器间怎么互访、localhost 的陷阱,以及 volume/bind mount/tmpfs 怎么选和权限、时区怎么配。
前四篇是按知识点讲的,这篇是反过来用的:命令忘了、线上出事了,回来翻。上半部分按镜像、容器、网络、存储、Compose、系统清理分组整理常用命令,能直接复制;下半部分是 12 个真实场景案例,每个给出现象、怎么查、结论三步。
老 JDK 不识别 cgroup,容器限 2G 却按宿主机 64G 算堆,还按 32 核起线程,结果被 OOMKilled 或越跑越慢。讲清 UseContainerSupport、MaxRAMPercentage、堆外开销、cgroup v1/v2 文件,以及容器里 jstack/jmap 的正确姿势。
容器写挂载目录报 Permission denied,根因常是 UID 不一致,也可能是 SELinux 或只读挂载。顺带整理容器时区不对、构建缓存导致改了代码镜像没更新两个小坑,每条都给出复现现象与 id、ls -ln、docker exec 排查命令。
docker ps 里一个容器永远显示 Restarting,日志什么都没有。docker inspect 看 OOMKilled 与 ExitCode 137,配合 docker events、stats、dmesg 定位内存超限,讲清 restart policy 如何放大故障、-m 与 swap 的关系,附 exit code 速查表。
容器访问宿主机 MySQL 报 Connection refused,同一 compose 里 localhost 也不通。梳理 host.docker.internal 与 host-gateway、服务名 DNS、-p 与 EXPOSE、默认 bridge 无 DNS、ufw 被 Docker 绕过,附 docker network inspect 与 nsenter 排查命令和网络拓扑图。