记录学习K8s 集群中OOM Killer的决策基准及执行流程

OOM Killer(Out-of-Memory Killer)在 Kubernetes 中决定是否终止 Pod 的核心基准是内存资源的超额使用,其决策和执行流程涉及多个组件的协同工作。以下是完整的基准和流程说明:


⚖️ ​​一、决策基准:工作集内存(Working Set Memory)​

OOM Killer 主要依据 ​container_memory_working_set_bytes​ 指标判断是否终止 Pod。

该指标表示容器​​活跃使用的物理内存页​​(无法被内核回收的内存),包括:

  • ​堆内存(Heap)​:应用程序运行时直接分配的内存。
  • ​栈内存(Stack)​:线程执行所需的临时内存。
  • ​内核数据结构​:如进程页表、套接字缓冲区等。

💡 为何不用 container_memory_usage_bytes

后者包含缓存(如文件系统缓存),这些内存在压力下可被回收,不能反映真实的内存压力。


⚙️ ​​二、完整流程:从监控到终止​

1. ​​内存监控与上报​

  • ​容器运行时(如 Docker)​ :持续收集容器的内存使用数据(通过 Cgroups 接口 /sys/fs/cgroup/memory/)。
  • ​cAdvisor​ :集成在 kubelet 中,将容器的 working_set指标暴露给 Kubernetes。

2. ​​阈值检测与触发​

  • ​kubelet​ ​ 比较容器内存使用量与预设的 limits.memory

    • working_setlimits.memory,触发 OOM 事件。
  • ​Linux 内核的 OOM Killer​​:收到 kubelet 的终止请求后,按优先级选择进程终止(通常选择内存超额最多的容器)。

3. ​​Pod 终止与状态更新​

  • ​终止动作​ ​:内核发送 SIGKILL信号(Exit Code 137)强制结束容器。

  • ​Kubernetes 状态更新​ ​:Pod 状态变更为 OOMKilled,并记录事件:

    yaml 复制代码
    kubectl describe pod <pod-name>  # 输出示例
    Last State:     Terminated
      Reason:       OOMKilled
      Exit Code:    137

4. ​​后续行为​

  • ​重启策略​ :若 Pod 配置了 restartPolicy: Always/OnFailure,kubelet 会自动重启容器。
  • ​CrashLoopBackOff​:若反复 OOM,Kubernetes 会指数级延迟重启,避免雪崩。

⚠️ ​​三、两类 OOMKilled 场景​

  1. ​宿主机级 OOM​

    • ​原因​:Pod 未设内存限制,耗尽节点物理内存。
    • ​特征​ :内核日志(/var/log/messages)显示 Out of memory: Kill process
  2. ​Cgroups 级 OOM​

    • ​原因​ :Pod 内存使用超过 limits.memory
    • ​特征​ :Pod 事件明确标记 OOMKilled

🔍 ​​四、调试建议​

  • ​实时监控​​:

    bash 复制代码
    kubectl top pods   # 查看 Pod 内存使用
  • ​分析工作集内存​​:

    通过容器内文件 /sys/fs/cgroup/memory/memory.stat检查 working_set明细。

  • ​调整资源限制​​:

    在 YAML 中合理设置 requestslimits,避免低估堆外内存(如 JVM 的 Native 内存)。


💎 ​​总结​

OOM Killer 的决策基准是 ​​工作集内存是否突破限制​ ​,流程涵盖监控→阈值检测→内核终止→状态更新。理解 working_set的构成和 Cgroups 机制,是定位内存问题的关键。


附录

​1. container_memory_working_set_bytes指标来源:Cgroup 内存子系统​

该指标的数据来源于 Linux Cgroup 的 ​​内存控制组(Memory Subsystem)​​,具体文件路径为:

/sys/fs/cgroup/memory/<cgroup_path>/memory.statmemory.usage_in_bytes

关键字段包括:

  1. memory.usage_in_bytes:容器当前总内存使用量(含缓存、RSS、Swap等)。
  2. total_inactive_file:可回收的非活跃文件缓存(如未使用的文件页缓存)。

计算公式​​:

ini 复制代码
container_memory_working_set_bytes=memory.usageinbytes−totalinactivefile

2. 指标采集流程:cAdvisor 与 Kubelet​

​2.1 cAdvisor 采集数据​

  • cAdvisor(Container Advisor)作为 Kubelet 的内置组件,定期(默认10秒)扫描容器的 Cgroup 目录,读取 memory.statmemory.usage_in_bytes文件

  • 根据公式计算 working_set值,并生成指标 container_memory_working_set_bytes

​2.2 指标暴露与聚合​

  • cAdvisor 通过 Kubelet 的 /metrics/cadvisor接口暴露指标(如 container_memory_working_set_bytes{container="xxx"}
  • 监控系统(如 Prometheus)通过 Service Discovery 发现 Kubelet 目标,定期拉取指标
相关推荐
十五年专注C++开发32 分钟前
CMake进阶: externalproject_add用于在构建阶段下载、配置、构建和安装外部项目
linux·c++·windows·cmake·自动化构建
Skylar_.1 小时前
嵌入式 - Linux软件编程:进程
java·linux·服务器
rannn_1111 小时前
【Linux学习|黑马笔记|Day4】IP地址、主机名、网络请求、下载、端口、进程管理、主机状态监控、环境变量、文件的上传和下载、压缩和解压
linux·笔记·后端·学习
長琹1 小时前
9、C 语言内存管理知识点总结
linux·c语言
白书宇2 小时前
5.从零开始写LINUX内核--从实模式到保护模式的过渡实现
linux·汇编·数据库·开源
bkspiderx2 小时前
Nginx 屏蔽服务器名称与版本信息(源码级修改)
运维·服务器·nginx
TLucas3 小时前
在CentOS 7上将PostgreSQL数据库从默认路径迁移到自定义目录
linux·运维·postgresql·centos
guidovans4 小时前
基于tkinter开发电脑工具集(源码在底部)
linux·windows·python·gui·tkinter
ZoeLandia4 小时前
nginx实战分析
运维·前端·nginx