進入容器中top,雖然看到的PID是容器的,但是%Cpu的統計資訊卻是主控端的。
如圖
原理
程序的cpu使用率是如何計算出來的?
每個程序的狀态是放在檔案裡的,在/proc目錄下,每個程序有自己pid命名的檔案夾,
比如我現在這個jenkins的docker程序,通過inspect查詢到Pid是30134
我們繼續檢視/proc/30134下的檔案。
裡面的檔案比較多,我們現在隻關心stat檔案
[root@paas-m-k8s-node-1 30134]# cat stat30134 (tini) S 30112 30134 30134 0 -1 1077944576 1639 0 0 0 244 934 0 0 20 0 1 0 2352840503 2514944 114 18446744073709551615 94288423874560 94288423890205 140731692225440 140731692224320 139648449412143 0 0 3145728 0 18446744072548467014 0 0 17 12 0 0 0 0 0 94288423901968 94288423904395 94288443621376 140731692228014 140731692228057 140731692228057 140731692228586 0
這個stat檔案是程序的實時狀态資訊,實時輸出了程序的狀态資訊,比如程序的運作态(Running 還是
Sleeping)、父程序 PID、程序優先級、程序使用的記憶體等等總共 50 多項。
這些名額每個空格隔開是一項,現在就看第14項時utime,即程序的使用者态部分占用的cpu時間片。244
第15項是 stime,即程序的核心态部分占用的cpu時間片。934
需要注意的是,utime 和 stime 都是一個累計值,也就是說從程序啟動開始,這兩個值就是一直在累積增長的
然後根據這兩個值來計算程序的cpu使用率。具體的計算公式就不講了。
上面是單個程序的cpu使用計算,那整個系統的cpu資料在哪?
在/proc/stat檔案
明白了
在容器裡top看到的是主控端的cpu的原因就是,top查的是/proc/stat檔案,這個檔案是反應整個主控端的狀态資訊的,不是單個容器的。
有什麼辦法嗎
我們知道每個容器有自己的cpu cgroup控制組,在這個控制組的目錄下有很多檔案
比如我現在的容器cgroup的目錄是
/sys/fs/cgroup/cpuacct/system.slice/docker-1a97854ff7856b7327122bea18c3676f05cd2bf74e9502fe24370c8f011ceb1c.scope
其中有個cpuacct.stat檔案,就有整個容器的cpu資訊
注意,這裡的user和system的資訊也是累計值
是以我們可以每秒擷取一次,通過計算得到實時的cpu使用率。
很多工具如Prometheus,k8s中的資源計算,docker的計算最終都是從這個cgroup檔案來的。
單台節點上容器數量小于1000,計算周期位10s的情況下,計算資源的消耗很小。
是不是還是感覺很麻煩,下一篇分享一個小工具幫我們解決這個問題。