前言
我们把应用部署到Docker里面之后,有什么办法查看这个应用占用了多少内存呢?
docker本身提供了一个命令让我们可以直接看到当前时间所有容易占用的情况。
docker stats --no-stream
从上面来看,这几个应用用的内存加起来已经是将近12G了。
但是,这个时候看到机器使用的内存还不到2G。
第一反应就是,docker 这个统计太离谱,太坑人了。
查了一番资料过后,其实是计算的问题,也不能说那个是错的。
注: 这里的 docker 版本是
Docker version 20.10.2, build 2291f61
一般来说应用对内存的占用,这个指标其实是十分重要的,不然内存泄漏都难以发现。
如果我们想要看到应用比较真实的内存要怎么做呢?
处理方案
其实可以分成两个步骤
- 找到应用的真实进程Id(宿主机里面的)
- 从宿主机的
/proc/pid/status
去看VmRSS
的值
找 Pid
docker inspect
命令可以看到当前容器的一些信息,里面也包含了我们要找的这个 Pid。
docker inspect -f '{{.State.Pid}}' 容器ID
这个时候就找到了对应的Pid了。
ps
看了一下这个Pid确实是应用的。
这个时候第一步就完成了。
查 VmRSS
有了 Pid 之后,要查内存就比较容易了。
直接 cat /proc/pid/status
就能看到了。
虽说这样能找到某个应用具体的内存,但是每次都这样去操作一遍也是挺麻烦的。
而且这样操作一次只能查一个应用,想看多个应用还要分多次。
既然有了上面的步骤,那么我们就可以把这个整理成一个脚本,每次执行一下这个脚本就可以了。
# 找出所有运行的容器
idNames=`docker ps --format "{{.ID}}|{{.Names}},"`
# 按,号分隔
OLD_IFS="$IFS"
IFS=","
arr=($idNames)
IFS="$OLD_IFS"
# 输出 Title
printf "%-15s %-30s %-15s
" Id Name Mem
# 遍历所有容器
for item in ${arr[@]}
do
# 容器ID和容器名字 按 | 分隔
OLD_IFS="$IFS"
IFS="|"
array=($item)
IFS="$OLD_IFS"
# 当前容器的Pid
pid=`docker inspect -f '{{.State.Pid}}' ${array[0]}`
# 当前容器的内存
mem=$(cat /proc/$pid/status|grep -e VmRSS| awk '{print $2}')
# 输出结果
printf "%-15s %-30s %-15s
" ${array[0]} ${array[1]} $[$mem / 1024]M
done
执行上面的脚本后,就可以看到当前正在运行的容器的内存占用情况了。
现在看上去,占用大概是1G多,加上其他的内存占用,这个值看上去就和 free
看到的不到2G的使用内存比较接近了。