从Docker化的应用程序内部获取Docker容器的CPU和内存使用情况

12

我正在Docker容器内运行一个Node.js应用程序,我试图检索该应用程序正在运行的容器的系统使用度量。目前我正在使用https://www.npmjs.com/package/dockerstats,但它始终不显示CPU或内存使用情况。运行docker stats可以显示每个使用情况。

我的代码类似于以下内容:

let dockerId = setUp.getDockerId();
dockerId.then(dockerId => {
    if (dockerId !== null) {
            console.log(`dockerId: ${dockerId}`);
            dockerstats.dockerContainerStats(dockerId, data => {
                console.log(`cpu_percent: ${data.cpu_percent}`);
                console.log(`memPercent: ${data.memPercent}`);
                console.log(`memUsage: ${data.memUsage}`);
            });
        }
    });

setUp类类似以下示例,并使用https://www.npmjs.com/package/docker-container-id

const getId = require('docker-container-id');
module.exports = class setUp {

    getDockerId () {
        return getId().then(id => {
            if (!id) {
                return null;
            }
            return id;
        });
    }
}

1
由于Docker容器通常在您的控制下运行单个进程,并且“容器”除此之外没有太多内容,因此在容器内查看/proc/self/proc/1可能会在相对较少的权限下提供所需的信息。 - David Maze
@DavidMaze 所以说,Docker容器的文件系统中已经有了/proc/self或/proc/1吗?对于我正在开发的解决方案,我打算挂载/proc/stat和在容器cgroup中找到的cpuacct.usage文件,并从这些文件中读取。 - user5186815
2个回答

35

正如你所说,你正在使用 docker-container-id 包来获取容器ID。该包的工作原理是检查 /proc/self/cgroup 文件,因此它只能从容器内部运行(即仅在从容器化的进程执行 getContainerId() 时才能工作)。也就是说,接下来我将假设您正在尝试从容器内获取指标,在应用程序运行的容器中(您没有明确提到这一点)。

问题在于,正如 dockerstats 包的描述中所述,该包使用Docker API,并且根据包源,客户端连接到docker套接字(/var/run/docker.sock),该套接字默认情况下无法在容器内使用。解决此问题的简单(但危险)方法是在启动容器时使用以下选项将主机的/var/run/docker.sock挂载到容器中:

-v /var/run/docker.sock:/var/run/docker.sock
例如。
docker run -v /var/run/docker.sock:/var/run/docker.sock $MY_IMAGE_NAME

然而,这样做强烈不建议,因为它会产生严重的安全风险。在生产环境中永远不要这样做。这样做将允许您的容器控制Docker,这本质上与给容器root访问主机系统的权限相同。

但实际上,您并不需要使用Docker API来访问资源消耗指标。关键是您可以直接从/sys/fs/cgroup读取有关进程的cpuacctmemory控制组的信息(它们分别负责跟踪和限制CPU和内存消耗)。例如,读取/sys/fs/cgroup/memory/memory.usage_in_bytes文件将向您提供容器使用的内存量(以字节为单位):

# cat /sys/fs/cgroup/memory/memory.usage_in_bytes 
164823040

读取/sys/fs/cgroup/cpuacct/cpuacct.usage文件将为您提供容器的总CPU使用情况(以纳秒为单位):

# cat /sys/fs/cgroup/cpuacct/cpuacct.usage
2166331144

因此,您可以从应用程序中读取这些指标并处理它们。同时,您还可以使用procfs中的统计数据,请参阅此讨论了解详细信息。


19

由于我没有足够的声望来发表评论,我想在 @ danila-kiver的答案中补充一个快速检查 内存使用量(以兆字节为单位)的方法:

cat /sys/fs/cgroup/memory/memory.usage_in_bytes | awk '{ byte =$1 /1024/1024; print byte " MB" }'

或者以千兆字节为单位:

cat /sys/fs/cgroup/memory/memory.usage_in_bytes | awk '{ byte =$1 /1024/1024/1024; print byte " GB" }'

适用于任何需要的人。


2
/1024将是Mebibytes而不是Mb。 - volvox

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接