【容器】k8s获取的节点oom事件并输出到node事件

在debug k8s node不可用过程中,有可能会看到:

System OOM encountered, victim process: xx

为了搞清楚oom事件是什么,以及如何产生的,我们做了一定探索,并输出了下面的信息。(本文关注oom事件是如何生成&传输的,具体cadvisor如何判定oom不在本片的讨论范围)

解析

主要代码文件:

1)pkg.kubelet.oom.oom_watcher_linux.go

oom_watcher主要描述了kubelet是如何接受并log系统产生的oom事件的

2)oom_watcher_linux.go:

NewWatcher方法会返回一个Watcher类型的对象,该对象包含recorder和oomStreamer。recorder用于记录,oomStreamer是一个OomParser(Cadvisor)类型的对象, 用于将OomInstance类型的对象写入outStream管道(channel)

package oomimport ("fmt"v1 "k8s.io/api/core/v1""k8s.io/apimachinery/pkg/util/runtime""k8s.io/client-go/tools/record""k8s.io/klog/v2""github.com/google/cadvisor/utils/oomparser"
)// streamer 接口定义了一个 StreamOoms 函数,
// 它接收一个 oomparser.OomInstance 类型的 channel,存储OomInstance类型数据
type streamer interface {StreamOoms(chan<- *oomparser.OomInstance)
}var _ streamer = &oomparser.OomParser{}type realWatcher struct {recorder    record.EventRecorderoomStreamer streamer
}var _ Watcher = &realWatcher{}// NewWatcher creates and initializes a OOMWatcher backed by Cadvisor as
// the oom streamer.
// 启动一个新的OOM watcher, 参数是一个 EventRecorder
// EventRecorder 是一个能够存储event并记录到一个queue里的Interface
// 函数声明中前面的括号里面是函数形参列表;后面的括号里面是函数返回值列表。
func NewWatcher(recorder record.EventRecorder) (Watcher, error) {
// 生成一个oomStreamer,由cadvisor的oomparser创建oomStreamer, err := oomparser.New()if err != nil {return nil, err}
// 生成一个watcher,包含上面的两个对象: recorder 和 oomStreamerwatcher := &realWatcher{recorder:    recorder,oomStreamer: oomStreamer,}return watcher, nil
}// Start watches for system oom's and records an event for every system oom encountered.
func (ow *realWatcher) Start(ref *v1.ObjectReference) error {
// 这段代码用来创建一个outStream channel,它是一个由 oomparser.OomInstance 
// 类型指针元素的channel,并可以向channel中传输10个元素。接着就启动了一个goroutine,
// 该goroutine调用ow.oomStreamer.StreamOoms方法并将outStream作为参数传入。该方法会往outStream channel中不断地写数据(即oom instance对象)outStream := make(chan *oomparser.OomInstance, 10)go ow.oomStreamer.StreamOoms(outStream)go func() {defer runtime.HandleCrash()
// 从outStream 读取event,并根据判断条件做是否oom。并输出相应的logfor event := range outStream {if event.VictimContainerName == recordEventContainerName {klog.V(1).InfoS("Got sys oom event", "event", event)eventMsg := "System OOM encountered"if event.ProcessName != "" && event.Pid != 0 {eventMsg = fmt.Sprintf("%s, victim process: %s, pid: %d", eventMsg, event.ProcessName, event.Pid)}ow.recorder.Eventf(ref, v1.EventTypeWarning, systemOOMEvent, eventMsg)}}klog.ErrorS(nil, "Unexpectedly stopped receiving OOM notifications")}()return nil
}

再来看下kubelet.go中如何应用
kubelet.go:
创建oomWatcher

# 通过上面的NewWathcher方法创建一个新的oomWatcher
oomWatcher, err := oomwatcher.NewWatcher(kubeDeps.Recorder)
# 如果创建新的oomWatcher报错,则查看原因
if err != nil {if libcontaineruserns.RunningInUserNS() {if utilfeature.DefaultFeatureGate.Enabled(features.KubeletInUserNamespace) {// oomwatcher.NewWatcher returns "open /dev/kmsg: operation not permitted" error,// when running in a user namespace with sysctl value `kernel.dmesg_restrict=1`.klog.V(2).InfoS("Failed to create an oomWatcher (running in UserNS, ignoring)", "err", err)oomWatcher = nil} else {klog.ErrorS(err, "Failed to create an oomWatcher (running in UserNS, Hint: enable KubeletInUserNamespace feature flag to ignore the error)")return nil, err}} else {return nil, err}
}

启动oomWatcher

    // Start out of memory watcher.if kl.oomWatcher != nil {if err := kl.oomWatcher.Start(kl.nodeRef); err != nil {return fmt.Errorf("failed to start OOM watcher: %w", err)}}

图示

在这里插入图片描述

上面的代码体现的就是如下流程,下图较完整描述了oom事件是如何被cAdvisor读取最终输出到node的事件的。

图片参考:启动oomWatcher

参考

1)https://www.jianshu.com/p/ef524b0b0119

2)启动oomWatcher

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3015040.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

电脑显示丢失mfc140u.dll怎么修复,总共有7个方法

mfc140u.dll 是一个动态链接库&#xff08;Dynamic Link Library&#xff09;文件&#xff0c;它是Microsoft Foundation Class (MFC)库的一部分&#xff0c;专为使用C编程语言开发Windows应用程序而设计。MFC库由微软提供&#xff0c;作为一个高级的应用程序框架&#xff0c;旨…

c++匿名比较函数参数顺序逻辑

在使用lower_bound和upper_bound时&#xff0c;想自定义比较函数&#xff0c;在这个过程中出现了参数定义顺序导致的错误问题&#xff0c;于是查找学习了下自定义比较函数需要符合的规则。 目录 1 lower_bound和upper_bound函数 1.1 lower_bound 1.2 upper_bound 2 问题产…

Java Streams和Collectors的使用技巧

文章目录 引言I 对list集合进行数据分组筛选1.1 按字段1进行分组并选择每组中时间最新的元素1.2 对list集合按照对象属性进行分组引言 应用场景: 对某一个字段进行分组,按照特定规则进行去重对某一个字段进行分组 //查询不显示城市QueryWrapper<JavaType> queryWrappe…

wangEditor 富文本详解

前言&#xff1a;wangEditor 官网 。本文档讲解 wangEditor 在 vue3 中的使用。 一&#xff1a;快速开始 1. 安装 需要安装 wangeditor/editor、wangeditor/editor-for-vuenext 两个依赖 # 安装 editor npm install wangeditor/editor # or yarn add wangeditor/editor # o…

一键静音,iPhone勿扰模式助你远离干扰

在现代社会的快节奏生活中&#xff0c;我们时常被各种各样的通知、铃声和提示音所打扰&#xff0c;无法专注地工作或享受宁静的时光。而iPhone的勿扰模式功能&#xff0c;就像是一位贴心的助手&#xff0c;能够一键帮你屏蔽这些干扰&#xff0c;让你在需要的时候拥有一个清静的…

sqlserver中替换空格和换行

sqlserver 中换行符&#xff0c;如下&#xff1a; sql语句如下&#xff1a; //替换换行-使用char(10) select REPLACE(F_CNKITitle ,char(10),) title from tzkj_CNKIContent tc where --F_CnkiContentID ffdc7412-41e1-4d42-8693-cc79d0cf2dd3and len(REPLACE(F_CNKITitle ,…

使用Three.js开发一个3D案例Demo

使用Three.js开发一个3D案例 最近在找工作&#xff0c;发现好多招聘要求都需要会Three.js&#xff0c;以前接触比较多的是2D开发&#xff0c;也就是平面开发&#xff0c;用到的做多的技术就是d3.js&#xff0c;现在3D开发已经成为了大势所趋&#xff0c;所以就学习下Three.js。…

第二届生成式AI应用创新大赛

&#x1f525; 第二届生成式AI应用创新大赛 &#x1f331; 初赛正如火如荼地进行中&#xff0c;报名截止时间是5月15日&#xff01; ⏰ ⭐ 最激动人心的总决赛将于5月30日在亚马逊上海峰会上举行&#xff0c;届时会有权威评委现场点评&#xff01; &#x1f3a4; &#x1f3…

【微积分】微分方程的求解(必看)

文章目录 微分方程1.一阶微分方程1.1 可分离变量型微分方程1.2 一阶齐次微分方程1.3 一阶线性微分方程 2. 高阶微分方程2.1 可降阶的高阶微分方程求解&#xff08;以二阶为例&#xff09;2.2 二阶常系数线性微分方程2.2.1 二阶常系数齐次微分方程2.2.2 二阶常系数非齐次微分方程…

tkinter/python:第一个GUI程序——制作一个数据录入界面

下图是在网上搜寻的一个案例图样&#xff0c;经过了调整修改&#xff0c;登录时界面图如下&#xff1a; 登录后点击百货店铺按钮&#xff0c;界面如下 一、创建root窗口&#xff1a; geometry接收一个字符串&#xff0c;也就是需要建立的窗口尺寸和位置&#xff0c;geometry(…

字符设备驱动流程

字符设备驱动&#xff1a; linux系统驱动程序分为三大类&#xff0c;字符设备驱动&#xff0c;块设备驱动和网络设备驱动。其中字符设备驱动是使用最多的一种&#xff0c;从点灯到llC&#xff0c;SPI&#xff0c;音频设备等的驱动都是字符设备驱动。块设备和网络设备驱动要比字…

使用fitten code插件(vscode),替换通义千问,识别需求中的输入输出

今天我们介绍一个工具,具体介绍可以参考我的这篇文章的介绍,支持vs code 插件,Fitten Code是一款由非十科技开发的AI代码助手,旨在通过大模型驱动来提升编程效率和体验-免费神器-CSDN博客https://blog.csdn.net/lijigang100/article/details/137833223?spm=1001.2014.3001…

超越传统游戏:生成式人工智能对游戏的变革性影响

人工智能&#xff08;AI&#xff09;在游戏中的应用 游戏产业是一个充满活力、不断发展的领域&#xff0c;人工智能&#xff08;AI&#xff09;的融入对其产生了重大影响。这一技术进步彻底改变了游戏的开发、玩法和体验方式。本文分析的重点是传统人工智能和生成式人工智能在游…

【Java笔记】多线程:中断

线程中断的作用 线程中断可以使一个线程从等待状态变成就绪状态 使用线程中断&#xff0c;并不是要把线程给终止或是杀死&#xff0c;而是让线程不再继续等待&#xff0c;而是让线程不再继续等待&#xff0c;线程可以继续往下执行代码&#xff0c;线程发生中断后&#xff0c;会…

Linux网络编程(二) socket编程及其仿真

本节内容介绍Linux下进行网络编程所必须得socket接口的一些知识 一、socket地址函数 1.1、主机字节序和网络字节序 现代PC大多采用小端字节序&#xff0c;因此小端字节序又被称为主机字节序。 为了避免由于字节序导致的错误&#xff0c;发送端总是将字节序转换为大端字节序…

暖心又实用!母亲节教会妈妈这4招才是最贴心的礼物

母亲节就要到了&#xff0c;这个特殊的日子&#xff0c;我们总是想要为妈妈送上最真挚的祝福和关怀。在这个数字化时代&#xff0c;一部智能手机就能成为我们表达爱意的桥梁。今天&#xff0c;就让我们一起来看看华为手机的四个功能&#xff0c;让妈妈的手机使用体验更加便捷、…

C语言中的关键字static和extern

Hello,亲爱的小伙伴们&#xff0c;我又来了&#xff0c;上一期作者菌讲解了C语言中函数的知识点&#xff0c;得到了很好的反馈&#xff0c;这里作者菌感谢每一个至此我的小伙伴&#xff01;&#xff01;今天作者菌又来补充一些很有用的知识&#xff0c;感兴趣的uu们不要吝啬手中…

Jmeter 命令行压测 生成 HTML 测试报告,你真的会?

通常 Jmeter 的 GUI 模式仅用于调试&#xff0c;在实际的压测项目中&#xff0c;为了让压测机有更好的性能&#xff0c;多用 Jmeter 命令行来进行压测。 同时&#xff0c;JMeter 也支持生成 HTML 测试报告&#xff0c; 以便从测试计划中获得图表和统计信息。 以上定义的文件路…

Elementui的el-footer标签使用报错

Elementui的el-footer标签使用报错 其余标签的使用没有报错信息 el-footer的报错信息 原因: ​ 警告信息表示 Vue 不识别 <el-footer> 解决方式: 在组件中进行引入和暴露