标准答案

  1. 容器看到的资源上限可能来自 cgroup,而不是宿主机总资源;运行时和内核版本会影响可见字段与统计口径。
  2. memory.max 等限制约束 cgroup 的内存使用,匿名页、文件页和内核相关开销的计入要按版本和配置核对。
  3. 排查 OOM 要看 cgroup 事件、内核日志、容器状态、进程 RSS/PSS、堆配置和请求流量时间线。
  4. 修复可以减少峰值、限制并发、修正缓存或堆上限、提高资源配额并保留余量,但不能只把限制无限调大。

题目解析

cgroup 可以对进程组施加 memory.max 等边界,内核在该组无法继续分配时可能触发 cgroup 内 OOM,而宿主机整体仍有空闲内存。memory.current、memory.events、匿名页、文件页、swap 配置和 PSI 共同说明了压力来源;容器被 OOMKilled 还要看是内核 cgroup 判定、宿主机全局 OOM 还是应用自己退出。

memory limit 是保护边界,不是泄漏修复。调高 limit 之前应确认峰值来自堆、缓存、并发请求、page cache、原生库还是队列积压,并根据工作集和恢复时间设置 request/limit。修复后要在流量峰值和滚动发布场景验证,而不是只看一次容器没有被杀。

常见误区

  • 误区:只看宿主机 free。改正:同时查看目标 cgroup 的 current、max、events、匿名页和文件页。
  • 误区:把 OOM Kill 当成应用主动抛出的内存异常。改正:区分内核杀进程、容器运行时状态和应用退出日志。
  • 误区:只增加 limit。改正:先定位峰值和工作集来源,再调整并发、缓存、队列或资源预算。

作者信息