记录学习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 目标,定期拉取指标
相关推荐
tt666qq2 分钟前
linux进程与服务
linux·运维·网络
青草地溪水旁9 分钟前
从“快递签收规则”看 sigaction:信号处理的“总开关”
linux·信号处理
云泽80816 分钟前
Linux 入门指南:从零掌握基础文件与目录操作命令
linux·运维·服务器
Hello_wshuo22 分钟前
记一次手机付费充电设备研究
linux·单片机
心灵宝贝44 分钟前
unzip-6.0-21.el7.x86_64.rpm怎么安装?CentOS 7手动安装rpm包详细步骤
linux·运维·centos
Lin_Aries_04211 小时前
基于 CI/CD 平台将应用程序自动部署到 Kubernetes 集群
运维·ci/cd·docker·云原生·容器·kubernetes·jenkins
报错小能手1 小时前
linux学习笔记(11)fork详解
linux·笔记·学习
你的人类朋友2 小时前
DevOps是什么?
运维·自动化运维·devops
努力学习的小廉2 小时前
深入了解linux网络—— 基于UDP实现翻译和聊天功能
linux·网络·udp
大聪明-PLUS2 小时前
从技术史看:Unix 从何而来
linux·嵌入式·arm·smarc