K8S/Docker中对于容器内存的监控 (www.ipcpu.com)

标签: jianshu | 发表时间:2022-12-11 00:00 | 作者:
出处:https://itindex.net/relian

一、概述

在使用Docker或者Kubernetes时,我们经常需要监控容器或者Pod的内存,同时我们也经常收到反馈内存不准确的情况,这不仅是因为存在Buffer、Cache的影响,不同的算法指标也会得出不同的结果。
接下来我们先回顾下我们最古老的计算方法,然后分别取分析docker stats 和 kubectl top 中的内存计算方法。

二、最原始的计算内存方法

我翻阅了以前的一些工作资料,发现从Docker 1.5 开始才提供了Docker stats接口,这个接口有API和命令行两种方式,并且API是stream方式,会不间断的发送数据,当时我们也不清楚如何和这样的API接口对接,所以我们选择了直接对cgroup文件下手。
我们读取了以下两个文件:

   # 容器当前已使用的内存Bytes
/cgroup/memory/docker/$DOCKERID/memory.usage_in_bytes
# 容器最大限制内存Bytes
/cgroup/memory/docker/$DOCKERID/memory.limit_in_bytes

这两个数据相除就得到了内存使用率,当时并没有考虑Buffer、Cache等数据,也没有详细深究/cgroup/memory/docker/$DOCKERID/memory.stat文件内容,所以与docker stats略有偏差。

接下来我们看下Docker stats 中的实现方法

三、Docker stats中的内存计算方法

由于低版本的docker源码已经看不了了,在Docker V19和之前的版本中,

   mem.Usage - mem.Stats["cache"]

看起来与我们上面实现的方式类似,减掉了Cache部分,具体源码如下:

   // calculateMemUsageUnixNoCache calculate memory usage of the container.
// Page cache is intentionally excluded to avoid misinterpretation of the output.
func calculateMemUsageUnixNoCache(mem types.MemoryStats) float64 {
    return float64(mem.Usage - mem.Stats["cache"])
}

从Docker V20版本开始这部分有修改,计算方法为

   mem.Usage - inactive_file

详细代码如下

   // calculateMemUsageUnixNoCache calculate memory usage of the container.
// Cache is intentionally excluded to avoid misinterpretation of the output.
//
// On cgroup v1 host, the result is `mem.Usage - mem.Stats["total_inactive_file"]` .
// On cgroup v2 host, the result is `mem.Usage - mem.Stats["inactive_file"] `.
//
// This definition is consistent with cadvisor and containerd/CRI.
// * https://github.com/google/cadvisor/commit/307d1b1cb320fef66fab02db749f07a459245451
// * https://github.com/containerd/cri/commit/6b8846cdf8b8c98c1d965313d66bc8489166059a
//
// On Docker 19.03 and older, the result was `mem.Usage - mem.Stats["cache"]`.
// See https://github.com/moby/moby/issues/40727 for the background.
func calculateMemUsageUnixNoCache(mem types.MemoryStats) float64 {
    // cgroup v1
    if v, isCgroup1 := mem.Stats["total_inactive_file"]; isCgroup1 && v < mem.Usage {
        return float64(mem.Usage - v)
    }
    // cgroup v2
    if v := mem.Stats["inactive_file"]; v < mem.Usage {
        return float64(mem.Usage - v)
    }
    return float64(mem.Usage)
}

四、Kubernetes/cadvisor中的内存计算方法

kubectl top 的内存数据用working_set参数,底层数据是从kubelet中内置的cadvisor来读取的,但是cadvisor的旧代码我们也无迹可寻了,我们找了v0.30.0 9 Mar 2018 ,计算方式为:

   workingSet := ret.Memory.Usage
    if v, ok := s.MemoryStats.Stats["total_inactive_file"]; ok {
        if workingSet < v {
            workingSet = 0
        } else {
            workingSet -= v
        }
    }
    ret.Memory.WorkingSet = workingSet

简单的说,就是:

   Memory.Usage - MemoryStats.Stats["total_inactive_file"]

这个方法和Docker V20以后是一致的,也就是说一直到Docker 20.10.0时间是2020-12-08,docker stats 和 kubectl top 内存数据才达成一致,之前都是不统一的。

五、统一的内存计算方法

所以,Docker 20.10.0(2020-12-08) 之后,docker stats 和 kubectl top都会使用下面方法计算内存使用:

   memory_working_set  = Memory.Usage - Memeory.inactive_file

参考资料

https://qingwave.github.io/container-memory/
https://segmentfault.com/a/1190000021493607
https://blog.csdn.net/Ivan_Wz/article/details/119457692
https://kubesphere.com.cn/forum/d/1517-docker-stats-mem-top-res
https://github.com/docker/cli/blob/v19.03.15/cli/command/container/stats_helpers.go

转载请注明: IPCPU-网络之路» K8S/Docker中对于容器内存的监控

相关 [k8s docker 容器] 推荐:

K8S/Docker中对于容器内存的监控 (www.ipcpu.com)

- - IT瘾-jianshu
在使用Docker或者Kubernetes时,我们经常需要监控容器或者Pod的内存,同时我们也经常收到反馈内存不准确的情况,这不仅是因为存在Buffer、Cache的影响,不同的算法指标也会得出不同的结果. 接下来我们先回顾下我们最古老的计算方法,然后分别取分析docker stats 和 kubectl top 中的内存计算方法.

容器平台选型的十大模式:Docker、DC/OS、K8S 谁与当先?(上)-社区博客-网易云

- -
无论是在社区,还是在同客户交流的过程中,总会被问到到底什么时候该用 Docker. 如果使用容器,应该使用哪个容器平台. 显而易见,我不会直接给大家一个答案,而是希望从技术角度进行分析具体的场景. 例如客户是大公司还是小公司,将部署小集群还是大集群,倾向于私有云还是公有云,已经采购了 IaaS 还是没有 IaaS,IT 运维能力强还是弱,是否需要物理机、虚拟机、容器的混合部署,是一般的并发系统还是高并发,这里面所应该做的技术选型都不一样.

k8s docker集群搭建 - CSDN博客

- -
一、Kubernetes系列之介绍篇.     - 一次构建,到处运行. 2.什么是kubernetes.   首先,他是一个全新的基于容器技术的分布式架构领先方案. Kubernetes(k8s)是Google开源的容器集群管理系统(谷歌内部:Borg). 在Docker技术的基础上,为容器化的应用提供部署运行、资源调度、服务发现和动态伸缩等一系列完整功能,提高了大规模容器集群管理的便捷性.

关于docker容器的监控

- - CSDN博客推荐文章
1 docker inspect [容器ID | 镜像ID]. 查看容器创建时间、容器的IP、映射的端口、挂载的目录等信息. 此命令同样也能用来查看镜像的详细信息. 2 docker stats 容器ID. 用来查看容器的资源使用情况,如:CPU、内存、网络、I/O. 另外,在docker的配置文件中添加如下的参数之后,可以采用curl来调用stats API接口.

Docker容器安全性分析

- - FreeBuf互联网安全新媒体平台
Docker是目前最具代表性的容器技术之一,对云计算及虚拟化技术产生了颠覆性的影响. 本文对Docker容器在应用中可能面临的安全问题和风险进行了研究,并将Docker容器应用环境中的安全机制与相关解决方案分为容器虚拟化安全、容器安全管理、容器网络安全三部分进行分析. 一、从虚拟化安全到容器安全 .

调试 Docker 容器内部进程

- - 掘金后端
摘要:本文以 Nebula Graph 进程为例,讲解如何不破坏原有容器的内容,也不用在其中安装任何的工具包前提下,像在本地一样来调试进程. 在开发或者测试过程中,我们经常会用到. vesoft-inc/nebula-docker-compose 这个 repo 下的部署方式,因为当初为了尽可能的压缩每个.

K8S的SDN容器网络解决方案及其价值

- - SegmentFault 最新的文章
编者按:关于容器网络的解决方案业界已经有较多的讨论,笔者无意继续赘述. K8S及其网络模型体现了鲜明的解耦设计思想,采用SDN技术实现K8S容器网络,并与相应的生态组件形成SDN监管控一体化解决方案,可以更好地提高整个系统的运营水平,更有效地提升企业的核心竞争力. 本文拟抛砖引玉,从K8S的网络实现入手,重点阐述SDN在容器网络中的应用价值.

图解 K8S(03):从 Pause 容器理解 Pod 的本质

- - 明哥教程
在 K8S 中,Pod 是最核心、最基础的资源对象,它是 Kubernetes 中调度最小单元,学习 K8S 很多时候,我们都是在跟 Pod 打交道,它的内容是最多的,需要分好多的章节才能将它讲透. 本篇作为 Pod 的首篇,打算先从咱们熟悉的 Docker 容器入手,介绍 Pod 的组成及其工作原理.

如何收集K8S容器化部署的服务的日志?

- - 掘金 后端
做开发的同学都知道日志的重要性,日志的种类一般有接口日志、错误日志、关键步骤日志、用户操作日志等. 本文主要详细讲解使用kubernetes容器化部署的服务该如何记录和收集日志. 将想要记录的日志内容输出到stdout或stderr即可(DockerEngine本身具有LogDriver 功能,可通过配置不同的LogDriver将容器的stdout通过DockerEngine写入到日志系统),由DockerEngine将日志写入到日志系统.

减少使用Java应用服务器,迎接Docker容器

- - ITeye资讯频道
【编者的话】随着Docker的发展,越来越多的应用开发者开始使用Docker. James Strachan写了一篇有关Java开发者如何使用Docker进行轻量级快速开发的文章. 他告诉我们,使用Docker和服务发现的机制,可以有效减轻Java运维人员的负担,进行项目的快速启动和持续迭代. 多年来,Java生态系统一直在使用应用服务器.