首页 > 系统相关 >记一次go应用在k8s pod已用内存告警不准确分析

记一次go应用在k8s pod已用内存告警不准确分析

时间:2024-01-17 09:14:50浏览次数:28  
标签:active 内存 file memory go 日志 k8s pod

版权说明: 本文章版权归本人及博客园共同所有,转载请在文章前标明原文出处( https://www.cnblogs.com/mikevictor07/p/17968696.html ),以下内容为个人理解,仅供参考。

 

一、背景

起因:自监控应用凌晨告警:Pod 内存使用率大于80%(规格为1c1G)。内存缓慢增长,持续到早上内存使用率停止在81%左右。

疑点:此模块是一个轻任务模块(基于go开发),请求量很低并且数据量非常少,平常内存占用一直以来都在100MB左右,出现内存不足的概率极小,而且运行了几个月无故障。

初步定位:登录平常查看指标,确实有一个节点内存异常,但另一个节点正常(这模块有个特性是主备模式,同一时间只有一个节点工作,通过日志确定异常的节点正是工作节点)。

 

 

 

二、初步分析过程

登录k8s查看内存情况,通过 kubectl top pod 查看内存占用果然已经有800MB+,但理论上这模块不应该占用这么多内存(截图时间点不一样,有部分回收)。

 

 继续登录pod内,通过 cat /sys/fs/cgroup/memory/ 查看内存统计 (注意,在pod中使用 free -m 等类似的命令只能统计到宿主机的内存信息,固无用)

# cd  /sys/fs/cgroup/memory/
# cat memory.usage_in_bytes
显示输出 962097152(即约917MB,即将超过1GB限额,超过则会激活OOM Kill)

# cat memory.stat 后输出如下图

 

 其中的 rss 标识当前应用进程实际使用内存量,55017472 = 约52MB,此数据证实了一般的设定:这个应用一般占用都在100MB以内。

 

三、怀疑监控指标不准确?

通过了解到,激活自监控告警的指标是通过k8s的 container_memory_working_set_bytes 指标超过80%告警。

通过查阅k8s源码 promethus.go 的 Memory.WorkingSet 相关引用发现,此参数是通过计算 Memory.Usage - total_inactive_file 得出(即本案例是 962097152 - 111620096 = 811MB)

 (其中的 Memory.Usage 即为memory.usage_in_bytes文件中的值:962097152 

 

 

 

按照此情况看,数据取值确实没问题,同时,关注到一个指标  total_active_file (795275264 = 75.8MB),此参数加上rss刚好与已用内存接近,源码中未找到此指标的相关信息,通过查阅官方资料发现,此参数认为是一个不能被计算为可用内存的值。

也就是说 k8s 作者们认为 此active_file内存不认定为可用内存(官方地址为:https://kubernetes.io/docs/concepts/scheduling-eviction/node-pressure-eviction/#active-file-memory-is-not-considered-as-available-memory )

 

此参数作为文件缓存是否要被计算进已用内存中,github上的讨论已经有了6年之久仍然是Open状态 (地址为:  https://github.com/kubernetes/kubernetes/issues/43916)。

 

四、应用分析

此应用只有日志才用到写文件的操作,是否是日志文件导致的file cache呢? 进入到日志文件目录 ,通过 > xxx.log 清理文件后,再次 cat memory.stat

 

其中的 total_active_file 立即缩小,在通过之前的命令查看内存占用,立即恢复正常,也就是 日志文件导致的 total_active_file 增长从而导致Pod内存使用量增大

 

五、回溯代码 & 修复措施

此应用使用了 zap日志框架,通过配置 MaxSize 设定日志轮转文件大小为1G,在故障时日志文件大小已经达到了 889M。

 

日志一直要达到1G才会激活轮转,此前系统将此cache住,但是k8s认为此内存无法被利用,就导致了内存一直在增长,直到产生告警。

解决方案:为保证Pod 不被 OOM Kill,通过修改MaxSize 修改文件大小进行轮转(比如改为200-300M),file cache即可在日志轮转后释放。

 

标签:active,内存,file,memory,go,日志,k8s,pod
From: https://www.cnblogs.com/mikevictor07/p/17968696

相关文章

  • go--数组
    数组的定义数组是用来存储相同唯一类型的,一组已编号且长度固定的序列数组的特点固定长度:这意味着数组不可增长、不可缩减。想要扩展数组,只能创建新数组,将原数组的元素复制到新数组。内存连续:这意味可以在缓存中保留的时间更长,搜索速度更快,是一种非常高效的数据结构,同时还意味......
  • client-go异常场景分析
    场景1:同步时连不上kube-apiserverWaitForCacheSync一直阻塞,直到成功或者控制器停止。W011513:01:55.32988118339reflector.go:535]pkg/mod/k8s.io/[email protected]/tools/cache/reflector.go:229:failedtolist*v1.Node:Get"https://192.168.0.105:6443/api/v1/no......
  • Go组合与继承
    转载:原文链接Golang是不支持继承的,因此我们在使用的时候往往使用组合。那么,组合与继承有什么区别呢?组合和继承都是面向对象编程中重要的概念。继承让一个类获得另一个类的属性和方法,形成层级关系,子类可以重用父类的功能。而组合则是将一个类的对象作为另一个类的成员变量,实现代码......
  • Google自研芯片首次交给台厂生产 | 百能云芯
    Google半导体战略有了新的走向,首次将其自家设计的手机系统单晶片(SoC)"Tensor"的测试订单委托给了台湾的京元电。这一举动打破了以往三星包揽晶圆代工与封测的模式,同时也为未来Google可能释出更多自家设计的人工智能(AI)芯片测试订单留下伏笔,象征着台湾在全球AI芯片供应链中的地位不断......
  • K8S单机版部署
    安装etcd、kubernetesKubernetes中几乎所有的资源对象(Node、Pod、ReplicationController、Service等)都能通过kubectl工具执行增删改查操作并保存在etcd中持久化存储。因此Kubernetes和etcd密不可分。可在root权限下,输入如下指令安装etcd和kubernetesyuminstall-yetcdkuber......
  • argo-rollout使用--金丝雀结合ingress-nginx
    1.金丝雀发布流程,安装比例发布,又名灰度发布举例:共10pod第一批发布30%V1:10个PodV2:3个Pod第二批发布60%V1:10个PodV2:6个Pod第三批发布100%V1:10个PodV2:10个Pod第四批发布V2:10个Pod(active)V1:0个Pod 2.资源文件准备文......
  • 以 Golang 为例详解 AST 抽象语法树
    前言各位同行有没有想过一件事,一个程序文件,比如hello.go是如何被编译器理解的,平常在编写程序时,IDE又是如何提供代码提示的。在这奥妙无穷的背后,AST(AbstractSyntaxTree)抽象语法树功不可没,他站在每一行程序的身后,默默无闻的工作,为繁荣的互联网世界立下了汗马功劳。AST抽象......
  • Django 使用swagger自定义自动生成类
    完整代码:https://gitee.com/mom925/django-system之前写的Django配置swagger(https://www.cnblogs.com/moon3496694/p/17657283.html)其实更多还是自己手动的写代码去书写接口文档,我希望它能更加的自动化生成出接口文档,所以我需要自己重写一些函数。安装所需的包,注册app,注册路由参考......
  • 关于命令行修改K8s内Prometheus配置文件参数
    #登录master节点操作1、进入prometheus介质目录:[root@k8s-master01]$cd/yang/operator/operator-0.7/manifests/prometheus2、备份prometheus配置文件[root@k8s-master01]$cpprometheus-prometheus.yamlprometheus-prometheus.yaml.202312153、编辑prometheus配置文件修......
  • Gorm常见映射关系查询实例
    一、概述本小节主要罗列一下常见的查询以及相应的代码示例1.假设你有一个轮播图表,请查询出轮播图中的所有记录2.获取后台管理用户列表,并把用户的角色信息也查询出来3.查询用户订单信息,要求:查询某用户买了某商品的订单信息。本例是查询用户购买的视频的详细的......