记录学习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 目标,定期拉取指标
相关推荐
CheungChunChiu14 分钟前
Linux 内核动态打印机制详解
android·linux·服务器·前端·ubuntu
BlueBirdssh2 小时前
linux 内核通过 dts 设备树 配置pcie 控制器 各种参数和中断等, 那freeRTOS 是通过直接设置PCIe寄存器吗
linux
小目标一个亿2 小时前
Windows平台Nginx配置web账号密码验证
linux·前端·nginx
实战项目2 小时前
软件测试自动化框架的设计与实现
运维·自动化
Aotman_2 小时前
Element-UI Message Box弹窗 使用$confirm方法自定义模版内容,修改默认样式
linux·运维·前端
Elastic 中国社区官方博客3 小时前
使用 Elastic 中的 OpenTelemetry 为 Nginx 实现端到端分布式追踪的实用指南
大数据·运维·分布式·elasticsearch·搜索引擎·信息可视化·全文检索
独自破碎E3 小时前
配置ssh解决https不稳定的问题
运维·ssh
那些年的笔记4 小时前
Linux屏幕旋转方法
linux·运维·服务器
XiaoHu02074 小时前
Linux网络编程套接字
linux·服务器·网络·git
竹之却4 小时前
CentOS 系列,防火墙相关指令
linux·运维·centos