前言
我們把應用部署到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\n" 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\n" ${array[0]} ${array[1]} $[$mem / 1024]M
done
執行上面的腳本后,就可以看到當前正在運行的容器的內存占用情況了。
現在看上去,占用大概是1G多,加上其他的內存占用,這個值看上去就和 free
看到的不到2G的使用內存比較接近了。