Analyze Kubernetes pod OOMKilled



我们在 K8s pod 上得到了 OOMKilled 事件。我们希望在发生此类事件时在 pod 被逐出之前运行本机内存分析命令。是否可以添加这样的钩子?

更具体地说:我们使用 JVM 标志运行-XX:NativeMemoryTracking=summary。我们想在 pod 逐出之前运行jcmd <pid> VM.native_memory summary.diff以查看导致 OOM 的原因。

看起来几乎不可能处理。

基于Github上关于在OMM上优雅停止的答案 杀戮:

当前无法更改 OOM 行为。Kubernetes(或运行时)可以在容器接近其内存限制时为您的容器提供信号。不过,这将尽最大努力,因为可能无法按时处理内存峰值。

以下是官方文档:

如果节点在 kubelet 能够回收内存之前遇到系统 OOM(内存不足)事件,则节点依赖于响应oom_killer。 kubelet 根据 Pod 的服务质量为每个容器设置一个oom_score_adj值。

因此,如您所知,您没有太多机会以某种方式处理它。 这是关于 OOM 处理的大文章,我在这里只拿一小部分,关于内存控制器的内存处理:

遗憾的是,此过程可能无法执行太多其他操作来响应 OOM 情况。如果它已使用 mlock() 或 mlockall() 将其文本锁定到内存中,或者它已经驻留在内存中,则它现在知道内存控制器内存不足。但是,它不能做太多其他事情,因为大多数感兴趣的操作都需要分配更多内存。

我唯一能提供的是从 cAdvisor(在这里您可以获得 OOM Killer 事件)或 Kubernetes API 获取数据,并在您看到非常接近内存不足的指标时运行您的命令。我不确定在获得 OOM 杀手事件后您是否有时间做某事。

以下是我们用来分析 K8S 中的 pod OOMKilled 的一些步骤。

  • 通过普罗米修斯进行内存使用情况监控

    • 不仅指标container_memory_working_set_bytes用于监视内存使用情况,还用于监视container_memory_max_usage_bytes
    • 我们可以从上述指标中发现一些异常的内存增加,以便根据我们的逻辑代码进一步调查。
  • 检查系统日志

    • 在基于 systemd 的 Linux 发行版中。要使用的工具是journalctl.
    sudo journalctl --utc -ke
    
    • -ke仅显示内核消息并跳转到日志末尾。 下面的一些日志
    memory: usage 4194304kB, limit 4194304kB, failcnt 1239
    memory+swap: usage 4194304kB, limit 9007199254740988kB, failcnt 0
    kmem: usage 13608kB, limit 9007199254740988kB, failcnt 0
    Memory cgroup stats for /kubepods.slice/kubepods-burstable.slice/kubepods-burst...
    
    • 我们可以在系统视图中找到一些异常的内存使用情况。
  • 检查上述文件夹中的内存 cgroup 统计信息

    • 检查文件夹/sys/fs/cgroup/memory/kubepods.slice/kubepods-burstable.slice下的文件以查找内存分配信息。
  • Pod 的内存转储

    • 我们可以在 pod 的preStop添加一个钩子来转储 pod 的内存,可以根据转储文件进行进一步的调查。这是Java的一个示例
    lifecycle:
    preStop:
    exec:
    command:
    - sh
    - -c
    - "jmap -dump:live,format=b,file=/folder/dump_file 1"
    
  • 继续个人资料

    • 使用继续配置文件工具(如热像仪)监视 Pod 的内存使用情况,并查找泄漏点配置文件数据。

最新更新