I'm running a node.js application from within a docker container. I'm trying to retrieve system usage metrics of the container the node.js application is running inside of. Right now I'm using https://www.npmjs.com/package/dockerstats but it consistently shows no cpu or memory usage, running docker stats shows usage in each.
My code resembles the following:
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}`);
});
}
});
The setUp class resembles the following and uses 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;
});
}
}
As you said, you are using the docker-container-id
package to obtain the container ID. This package works by inspecting the /proc/self/cgroup
file, thus it should work only from inside the container (i.e. only when getContainerId()
is executed from the containerized process). That said, further I will assume that you are trying to obtain the metrics from inside the container where your application runs (you did not mentioned this fact explicitly).
The problem here is that, as stated in the dockerstats
package description, this package uses Docker API and, as per package source, the client connects to the docker socket (/var/run/docker.sock
), which is is not available inside the container by default. The easy (but dangerous) way to workaround this is to mount host's /var/run/docker.sock
into the container by using the following option when starting the container:
-v /var/run/docker.sock:/var/run/docker.sock
E.g.
docker run -v /var/run/docker.sock:/var/run/docker.sock $MY_IMAGE_NAME
However, this is STRONGLY DISCOURAGED, as it creates a serious security risk. Never do this in production. By doing so, you are allowing your container to control Docker, which is essentially the same as giving the container root access to the host system.
But you actually don't need to use the Docker API to access resource consumption metrics. The point is that you may directly read the information about process' cpuacct
and memory
control groups (which are responsible for tracking and limiting the CPU and the memory consumption respectively) from /sys/fs/cgroup
. For example, reading the /sys/fs/cgroup/memory/memory.usage_in_bytes
file will give you the amount of memory used by your container (in bytes):
# cat /sys/fs/cgroup/memory/memory.usage_in_bytes
164823040
And reading the /sys/fs/cgroup/cpuacct/cpuacct.usage
file will give you a total CPU usage of your container (in nanoseconds):
# cat /sys/fs/cgroup/cpuacct/cpuacct.usage
2166331144
So, you can read these metrics from your application and process them. Also you may use statistics from procfs
, refer to this discussion for details.