【容器】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 oom

import (
    "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.EventRecorder
    oomStreamer 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 和 oomStreamer
    watcher := &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。并输出相应的log
        for 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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

uniapp的app端软件更新弹框

1&#xff1a;使用html PLUS实现&#xff1a;地址HTML5 API Reference (html5plus.org)&#xff0c;效果图 2&#xff1a;在app.vue的onLaunch生命周期中&#xff0c;代码如下&#xff1a; onLaunch: function() {let a 0let view new plus.nativeObj.View(maskView, {backg…

mib browser读取mib文件的oid(飞塔防火墙为例)

在配置zabbix监控的时候,配置监控项最为麻烦,一般我们都会套用模板,这种方式比较简单,但是有些设备就是没有现成的zabbix模板,怎么办? 今天我们使用MIB Browser来获取设备SNMP的OID,然后加入zabbix 。 1.什么是MIB Browser SNMP客户端工具MIB Browser, 全名iReasonin…

#LLM入门 | langchain | RAG # 4.3_文档分割

上一章讨论了文档标准化加载&#xff0c;现在转向文档的细分&#xff0c;这虽简单却对后续工作有重大影响。 一、为什么要进行文档分割 模型大小和内存限制&#xff1a;大型GPT模型参数众多&#xff0c;需大量计算和内存&#xff0c;而硬件设备如GPU或TPU有内存限制&#xff…

Vscode 实现代码跳转功能

随笔 目录 1. 安装Python 2. 安装Pylance 3. 选择解释器 1. 安装Python 2. 安装Pylance 3. 选择解释器 到此即可实现跳转功能

Pytorch学习笔记——神经网络基本框架

一、神经网络是什么 神经网络在人工智能和深度学习的领域&#xff0c;一般称为人工神经网络&#xff0c;即ANN(Artificial Neural Network)&#xff0c;是一种模仿人脑神经系统工作方式的计算模型。被广泛应用于人工智能、自动控制、机器人、统计学等领域的信息处理中。 二、…

图像处理之PCA(C++)

图像处理之PCA&#xff08;C&#xff09; 文章目录 图像处理之PCA&#xff08;C&#xff09;前言一、PCA原理1.原理思想2.实现步骤 二、代码实现总结 前言 在科研、工程应用中&#xff0c;我们往往所获取的数据都包含着很多冗余的信息&#xff0c;这些冗余的信息会对我们分析数…

CP AUTOSAR之CANXLDriver详细说明(正在更新中)

本文遵循autosar标准&#xff1a;R22-11 1 简介及功能概述 本规范描述了AUTOSAR 基础软件模块CAN XL 驱动程序的功能、API和配置。   本文档的基础是[1,CiA610-1]和[2,CiA611-1]。假设读者熟悉这些规范。本文档不会再次描述CAN XL 功能。   CAN XL 驱动程序是最低层的一部…

【七十六】【算法分析与设计】2435. 矩阵中和能被 K 整除的路径,87. 扰乱字符串,三维动态规划

2435. 矩阵中和能被 K 整除的路径 给你一个下标从 0 开始的 m x n 整数矩阵 grid 和一个整数 k 。你从起点 (0, 0) 出发&#xff0c;每一步只能往 下 或者往 右 &#xff0c;你想要到达终点 (m - 1, n - 1) 。 请你返回路径和能被 k 整除的路径数目&#xff0c;由于答案可能很大…

【Python爬虫实战入门】:全球天气信息爬取

文章目录 一、爬取需求二、所需第三方库2.1 简介 三、实战案例四、完整代码 一、爬取需求 目标网站&#xff1a;http://www.weather.com.cn/textFC/hb.shtml 需求&#xff1a;爬取全国的天气&#xff08;获取城市以及最低气温&#xff09; 目标url&#xff1a;http://www.weath…

数字孪生技术在垃圾焚烧处理中的可视化应用

在迈向智慧城市的进程中&#xff0c;数字孪生技术在垃圾处理领域展现出了巨大潜力。特别是在垃圾焚烧过程的管理和优化上&#xff0c;数字孪生垃圾焚烧可视化技术已成为一项革命性的进步。 通过 HT 构建虚拟的垃圾焚烧模型&#xff0c;实时映射和模拟实际焚烧过程中的各项关键…

QT+网络调试助手+TCP服务器

一、UI界面设计 二、单线程 代码设计 1、 查找合法的本地地址&#xff0c;用于当作服务器的IP地址 #include <QThread> #include <QTcpSocket> #include <QNetworkInterface> #include <QMessageBox>QList<QHostAddress> ipAddressesList QNe…

抖音短视频矩阵系统技术源头/源代码开发部署/SaaS贴牌/源码api代开发

抖音短视频矩阵系统技术源头/源代码开发部署/SaaS贴牌/源码官方平台api授权代开发 一、短视频矩阵系统源码开发步骤 短视频矩阵系统的源头开发步骤通常包括以下几个关键阶段&#xff1a; 1.需求分析&#xff1a;明确系统的目标用户、功能需求、性能要求等。 2.系统设计&…

bite阶段性测试_数据结构

解决问题之前我们要了解什么是度&#xff0c;特别是二叉树中的度&#xff0c;和图论中的度的定义是不同的 什么是度&#xff1a; 在图论中&#xff0c;一个节点&#xff08;或称为顶点&#xff09;的“度”是指与该节点直接相连的边的数量。度是用来衡量一个节点与其他节点连接…

Python:实现b站登录并保存登录信息(baidu Comate插件帮助我逐行分析代码)

&#x1f4da;博客主页&#xff1a;knighthood2001 ✨公众号&#xff1a;认知up吧 &#xff08;目前正在带领大家一起提升认知&#xff0c;感兴趣可以来围观一下&#xff09; &#x1f383;知识星球&#xff1a;【认知up吧|成长|副业】介绍 ❤️感谢大家点赞&#x1f44d;&…

O2OA(翱途)支持高斯_openGauss,瀚高_HighGo,磐维_panweidb等各种国产postgres分支数据库接入

O2OA&#xff08;翱途&#xff09;作为一款企业级应用平台&#xff0c;其支持多种数据库系统是其灵活性和可扩展性的重要体现。从MySQL、Oracle到国产的达梦、神州等数据库&#xff0c;再到对PostgreSQL的原生支持&#xff0c;O2OA展现了其对不同数据库环境的良好适应性。特别地…

LeetCode 难题解析 —— 正则表达式匹配 (动态规划)

10. 正则表达式匹配 思路解析 这道题虽然看起来不难理解&#xff0c;但却存在多种可能&#xff0c;当然这种可能的数量是有限的&#xff0c;且其规律对于每一次判别都使用&#xff0c;所以自然而然就想到用 动态规划 的方法啦 接下来逐步分析可能的情况&#xff1a; &#x…

stm32f103zet6_DAC_2_输出电压

实现效果 DAC输出的电压 同过电压表测量电压 1.DAC配置的步骤 初始化DAC时钟。配置DAC的GPIO端口。设置DAC的工作模式&#xff08;例如&#xff0c;是否使用触发功能&#xff0c;是否启用DAC中断等&#xff09;。启动DAC。 2常用的函数 函数 HAL_DAC_Start() - 开启指定…

企业终端安全管理软件有哪些?终端安全管理软件哪个好?

终端安全的重要性大家众所周知&#xff0c;关系到生死存亡的东西。 各类终端安全管理软件应运而生&#xff0c;为企业提供全方位、多层次的终端防护。 有哪些企业终端安全管理软件&#xff1f; 一、主流企业终端安全管理软件 1. 域智盾 域智盾是一款专为企业打造的全面终端…

淘宝商品搜索API:关键字搜索返回值详解与利用

在当今电子商务蓬勃发展的时代&#xff0c;淘宝作为中国最大的在线购物平台之一&#xff0c;拥有海量的商品信息和用户数据。为了更好地满足商家和开发者的需求&#xff0c;淘宝提供了商品搜索API&#xff0c;允许通过关键字搜索来获取商品信息。本文将详细解析淘宝商品搜索API…

LeetCode 每日一题 Day 144-157

2385. 感染二叉树需要的总时间 给你一棵二叉树的根节点 root &#xff0c;二叉树中节点的值 互不相同 。另给你一个整数 start 。在第 0 分钟&#xff0c;感染 将会从值为 start 的节点开始爆发。 每分钟&#xff0c;如果节点满足以下全部条件&#xff0c;就会被感染&#xf…