记录学习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 目标,定期拉取指标
相关推荐
OliverH-yishuihan几秒前
用windows10的linux子系统在visual studio2019中用C语言开发linux项目
linux·运维·visual studio
xujiangyan_2 分钟前
k8s中的pod管理及其优化
linux·容器·kubernetes
知识分享小能手3 分钟前
Ubuntu入门学习教程,从入门到精通, Ubuntu 22.04 用户和组管理指南(8)
linux·学习·ubuntu
随风语6 分钟前
ansible
运维·自动化·ansible
脏脏a7 分钟前
【Linux】进程地址空间
linux·运维·服务器·进程地址空间
旖旎夜光7 分钟前
Linux(5)(下)
linux·学习
无泪无花月隐星沉7 分钟前
uos server 1070e部署Hadoop
大数据·运维·服务器·hadoop·分布式·uos·国产化os
tianyuanwo8 分钟前
纵深防御:构建安全高效的 Ansible 自动化运维体系
运维·安全·ansible
努力的小帅9 分钟前
Linux_进程间通信(Linux入门到精通)
linux·c++·centos·共享内存·进程通信·命名管道·管道的学习
齐鲁大虾9 分钟前
Linux 系统上的开发 C/S 架构的打印程序
linux·c语言·架构