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

这篇具有很好参考价值的文章主要介绍了记一次go应用在k8s pod已用内存告警不准确分析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、背景

起因:

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

疑点:

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

初步定位:

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

记一次go应用在k8s pod已用内存告警不准确分析,kubernetes,golang,容器

二、初步分析过程

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

记一次go应用在k8s pod已用内存告警不准确分析,kubernetes,golang,容器

 继续登录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  后输出如下图

记一次go应用在k8s pod已用内存告警不准确分析,kubernetes,golang,容器

 其中的 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 

记一次go应用在k8s pod已用内存告警不准确分析,kubernetes,golang,容器

按照此情况看,数据取值确实没问题,同时,关注到一个指标  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 )

记一次go应用在k8s pod已用内存告警不准确分析,kubernetes,golang,容器

记一次go应用在k8s pod已用内存告警不准确分析,kubernetes,golang,容器

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

四、应用分析

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

记一次go应用在k8s pod已用内存告警不准确分析,kubernetes,golang,容器

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

五、回溯代码 & 修复措施

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

记一次go应用在k8s pod已用内存告警不准确分析,kubernetes,golang,容器

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

解决方案:

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

文章转载自:mikevictor

原文链接:https://www.cnblogs.com/mikevictor07/p/17968696

体验地址:引迈 - JNPF快速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流引擎_软件架构文章来源地址https://www.toymoban.com/news/detail-800427.html

到了这里,关于记一次go应用在k8s pod已用内存告警不准确分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • kubernetes(k8s)为容器和 Pod 分配内存资源

    展示如何将内存请求(request)和内存限制(limit)分配给一个容器。 我们保障容器拥有它请求数量的内存,但不允许使用超过限制数量的内存。 创建新的命名空间 编辑yaml文件 配置文件的 args 部分提供了容器启动时的参数。 “–vm-bytes”, “150M” 参数告知容器尝试分配 15

    2024年02月15日
    浏览(54)
  • 记一次Redisson连接k8s环境Redis报UnknownHostException-域名解析错误问题解决

    一直听说Redisson分布式锁好用,终于在项目上使用了!在本地测试完毕,一上测试环境,运维就反馈服务没起来,拉日志一看,是以下报错 主要报错信息是 于是乎,上github看了一下,发现这还是一个比较热门dns解析失败的问题,好多人都遇到了同样的问题。想着开源项目,这

    2024年02月04日
    浏览(45)
  • k8s故障排查个案:当Pod内存持续增长,OOM问题如何解决?

    pod 运行一段时间后,内存持续增长,甚至 oom 的情况. 容器化过程中,我们经常会发现 kubernetes 集群内 pod 的内存使用率会不停持续增长,加多少内存吃多少内存,如果对 cgroup 内存的构成不是很清楚的情况下,单纯看监控看不出什么问题。 经过一番查阅,目前总结出大致有

    2024年02月22日
    浏览(56)
  • K8S 1.27 新特性 Pod 无需重启调整CPU内存资源

    如果您已经部署了指定 CPU 或 Memory 资源的 Kubernetes pod,可能已经注意到更改资源值涉及重新启动 pod。直到现在,这一直是运行工作负载的破坏性操作。 在 Kubernetes v1.27 中,添加了一个新的 alpha 功能,允许用户在不重启容器的情况下调整分配给 Pod 的 CPU 或 memory 资源的大小。

    2024年02月11日
    浏览(35)
  • k8s自定义Endpoint实现内部pod访问外部应用

    endpoint除了可以暴露pod的IP和端口还可以代理到外部的ip和端口 使用场景 公司业务还还没有完成上云, 一部分云原生的,一部分是实体的 业务上云期间逐步实现上云,保证各个模块之间的解耦性 比如使用云数据库或者实体数据库服务器啥的,因为像数据库实现容器化的话在

    2024年01月25日
    浏览(50)
  • k8s企业级应用系列(二):对象管理及Pod原理

    本节介绍对象的相关概念和管理机制。只有了解了这些机制,我们才能轻松的对k8s资源进行编排。 1 对象 Object k8s对象 即是对应用程序、工作负载、存储、网络等资源的抽象表示,如 image、pod、node、volume、service 等。集群中每个对象都有一个 名称 来标识其在 同类资源中 的

    2024年04月14日
    浏览(45)
  • 【Kubernetes 系列】一文带你吃透 K8S 应用pod结点

    作者:半身风雪 上一节:创建K8s集群项目 简介:上一节我们一起学习了,如何去部署一个K8S 的应用程序,这一节,我们主要讲解一下,K8S 应用的框架结构。 本节我将和大家一起学习Kubernetes 应用中的pod结点 了解 Kubernetes Pod。 了解 Kubernetes 工作节点。 对已部署的应用故障排

    2023年04月08日
    浏览(106)
  • k8s进阶之路-pod探针:容器内的监控机制,检测应用是否存活

    配合Pod重启策略:  RestartPolicy 应用程序是否启动完成: 3.startupProbe启动探针1.16:排他性          如果三个都配置了,会优先启动,会禁用前两个反馈成功后,才会启动以下两个 应用启动成功后: 1.LivenessProbe存活探针--故障自动恢复:         如果容器挂掉了,会检测是

    2024年02月19日
    浏览(54)
  • 【Go】K8s 管理系统项目[Jenkins Pipeline K8s环境–应用部署]

    考虑到实际工作中前后端可能是不同的同学完成,一般Api部分完成后改动会比较小,web部分改动会比较频繁.于是将api和web分了2个pipeline实现 docker目录存放镜像构建相关文件 k8s-plantform-api 存放api部分代码 Jenkinsfile用作pipeline配置 yaml用作生成k8s下k8s-plantform-api相关资源 1.1.1 docker目

    2023年04月08日
    浏览(55)
  • 【云原生 | Kubernetes 系列】K8s 实战 如何给应用注入数据 II 将pod数据传递给容器

    在上一篇文章中,我们学习了针对容器设置启动时要执行的命令和参数、定义相互依赖的环境变量、为容器设置环境变量,三种设置方式,本篇文章,我们将继续学习数据的传递。 有两种方式可以将 Pod 和 Container 字段传递给运行中的容器: 环境变量 卷文件 这两种呈现 Pod

    2024年01月25日
    浏览(124)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包