docker容器學習筆記-資源監控
前言:
最近在看linux監控相關的各種命令,公司的服務部署在docker鏡像上,在鏡像上測試top命令的時候,發現了一個奇怪的現象:我們運維平臺上對某個docker鏡像的描述是4核 * 4g,在容器中執行top命令,按1可以查看每個核的信息,結果按完一下出來了20多個cpu的信息。
之前看網上說docker是通過namespace 和cgroups來實現資源隔離的,現在就很奇怪,到底隔離了哪些資源?怎麼隔離的?為什麼隔離了top命令還是顯示這麼多核?
轉載:
DOCKER基礎技術:LINUX NAMESPACE(上)
DOCKER基礎技術:LINUX CGROUP
正文:
很幸運的找到了上邊的幾個帖子,很清晰的把這個問題描述清楚了:
namespace負責環境的隔離
,包括PID(進程空間)、MOUNT(文件系統)、USER(用戶許可權)、NET(網路埠)。
cgroups負責資源的隔離
,具體就是在/sys/fs/cgroup這個目錄下配置了每個宿主機進程可以使用的各種資源(包括內存,cpu,磁碟io等等)的最大使用率。
從文章的描述看,cgroups只是設置了宿主機進程可以使用cpu的最大值,並不能從20多個核中選出4個單獨給某個進程使用,相似的也不是從操作系統申請某塊內存專門給某個鏡像使用。所以猜測同一個宿主機上的多個鏡像,執行top指令看見的內容應該是相同的,都是宿主機的指標,因為cgroups根本就沒有真正的隔離資源,所以也沒辦法在鏡像中查看獨立的監控。
下面就做個小實驗測試一下:
1.在宿主機上啟動兩個鏡像dcm1和dcm2
docker run -d --name dcm1 centos /bin/bash -c while true;do echo hello world ; sleep 1000;done > /dev/null
docker run -d --name dcm2 centos /bin/bash -c while true;do echo hello world ; sleep 1000;done > /dev/null
2.在dcm1中編寫測試用例,把cpu跑滿
//deadloop.c
int main(void)
{
int i = 0;
for(;;) i++;
return 0;
}
#編譯
gcc deadloop.c -o deadloop
#執行
nohup ./deadloop&
3.在dcm2中編寫測試用例,喫掉500m內存
// malloc_mb.c
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#define UNIT (1024*1024)
int main(int argc, char *argv[])
{
long long i = 0;
int size = 0;
if (argc != 2) {
printf(" === argc must 2
");
return 1;
}
size = strtoull(argv[1], NULL, 10);
if (size == 0) {
printf(" argv[1]=%s not good
", argv[1]);
return 1;
}
char *buff = (char *) malloc(size * UNIT);
if (buff)
printf(" we malloced %d Mb
", size);
buff[0] = 1;
for (i = 1; i < (size * UNIT); i++) {
if (i%1024 == 0)
buff[i] = buff[i-1]/8;
else
buff[i] = i/2;
}
pause();
}
#編譯
gcc malloc_mb.c -o mallocMb
#執行
nohup ./mallocMb 500&
4.分別在兩個鏡像中執行top,觀察結果:
5.宿主機中執行docker stats 查看鏡像資源:
觀察結果,發現確實跟之前的猜測一致。直接在鏡像裡邊執行top指令,顯示的cpu、內存信息都是宿主機的信息,如果希望查看具體哪一個鏡像出了問題,需要在宿主機上執行docker stats命令。
總結:
最近看的東西太多太雜,很難發現什麼可以總結的東西,就當是熱熱身吧,後續系統的學習一下linux,希望能有所突破吧。新的目標「Linux內核學習四庫全書(壓力山大~~~)
附錄:
覺得很有意思,改天研究一下:Docker:網路模式詳解
最後,讓我們保持獨立思考,不卑不亢。長成自己想要的樣子!
(引用自 我非常喜歡的B站up主 」獨立菌兒「的口頭禪嗶哩嗶哩 ( ゜- ゜)つロ 乾杯~ Bilibili)推薦閱讀: