1. 程式人生 > >Prometheus+grafana監控:cAdvisor輸出的容器CPU相關的指標的解讀

Prometheus+grafana監控:cAdvisor輸出的容器CPU相關的指標的解讀

概述

對容器中的服務進行監控,常見方案是採用Prometheus+grafana。其中對容器服務的CPU的監控有一組指標,本文對它們進行了一些分析和解讀,並做了一些試驗。

檢視cAdvisor輸出的容器CPU監控指標

我們使用kubernetes進行管理,自帶了容器監控cAdvisor exporter,可以直接通過頁面檢視監控指標,例如直接訪問一臺IP為172.18.12.188的node節點:

直接在頁面中搜索以 container_cpu 開頭的指標,如下表所示:

名稱 型別 單位 說明
container_cpu_usage_seconds_total counter

秒數

該容器服務針對每個CPU累計消耗的CPU時間。如果有多個CPU,則總的CPU時間需要把各個CPU耗費的時間相加

container_cpu_user_seconds_total counter

秒數

該容器服務累計消耗的使用者(user)CPU時間

container_cpu_system_seconds_total counter

秒數

該容器服務累計消耗的系統(system)CPU時間

container_cpu_cfs_throttled_seconds_total counter

秒數

cfs 是完全公平排程器(Completely Fair Scheduler)的縮寫,是Linux的一種控制CPU資源佔用的機制,可以按指定比例分配排程CPU 的使用時間。這個指標指的是該容器服務被限制使用的CPU時間

container_cpu_cfs_throttled_periods_total counter

個數

文件註釋是:“Number of throttled period intervals.”,解釋為被限制/節流的CPU時間週期數。

container_cpu_cfs_periods_total counter

個數 

文件註釋是:“Number of elapsed enforcement period intervals。”,應該解釋為已經執行的CPU時間週期數。

container_cpu_load_average_10s gauge 文件註釋是:“Value of container cpu load average over the last 10 seconds.”應該解釋為過去10秒內的CPU負載的平均值。

用Grafana檢視容器CPU指標

以我們部署在容器中的某自己開發的服務 cloud-bdp-interface為例,在grafana的dashborad中配置如下查詢:

因為CPU指標是計數器(counter)型別,所以grafana 的metrics的配置用到 rate函式:

rate(container_cpu_usage_seconds_total{name=~"k8s_cloud-bdp-interface.*"}[5m])

rate(container_cpu_user_seconds_total{name=~"k8s_cloud-bdp-interface.*"}[5m])

grafana查到的原始資料是:

container_cpu_usage_seconds_total

{beta_kubernetes_io_arch="amd64",beta_kubernetes_io_os="linux",container_name="cloud-bdp-interface",cpu="cpu00",id="/kubepods/burstable/pod84ab880d-bc9f-11e8-abe2-fa163e6f3f6b/93069e41ed1ac7181fa69732736f927ebe8764b560ba281c9d392a5333c30020",image="reg.docker.tb/huawei/[email protected]:975ac36a806f39d75ea992967b63ded54bd7b9798e2f5109511953681cc1fe53",instance="k8s-node-1",job="kubernetes-cadvisor",kubernetes_io_hostname="k8s-node-1",name="k8s_cloud-bdp-interface_cloud-bdp-interface-5b9bbc567f-xkvpj_docker-new40_84ab880d-bc9f-11e8-abe2-fa163e6f3f6b_0",namespace="docker-new40",pod_name="cloud-bdp-interface-5b9bbc567f-xkvpj"}

同一個節點上的同一個服務,不同cpu的佔用時間都有計量和統計,如下:

由此可見,要得到該容器服務的CPU使用的總的情況,需要對所有CPU求和,即:

sum(rate(container_cpu_usage_seconds_total{name=~"k8s_cloud-bdp-interface.*"}[5m]))

container_cpu_user_seconds_total 

{beta_kubernetes_io_arch="amd64",beta_kubernetes_io_os="linux",container_name="cloud-bdp-interface",id="/kubepods/burstable/pod84ab880d-bc9f-11e8-abe2-fa163e6f3f6b/93069e41ed1ac7181fa69732736f927ebe8764b560ba281c9d392a5333c30020",image="reg.docker.tb/huawei/[email protected]:975ac36a806f39d75ea992967b63ded54bd7b9798e2f5109511953681cc1fe53",instance="k8s-node-1",job="kubernetes-cadvisor",kubernetes_io_hostname="k8s-node-1",name="k8s_cloud-bdp-interface_cloud-bdp-interface-5b9bbc567f-xkvpj_docker-new40_84ab880d-bc9f-11e8-abe2-fa163e6f3f6b_0",namespace="docker-new40",pod_name="cloud-bdp-interface-5b9bbc567f-xkvpj"}
 

從返回的資料看, container_cpu_user_seconds_total 不再區分不同的CPU,已經針對所有CPU進行了合併,是個總的user CPU時間。直接用 rate 就可以得到不同容器服務的CPU的user時間。

一些試驗

我們用了一個自己開發的測試容器服務 cloud-bdp-interface。雖然虛機節點的CPU是8核,但我們用k8s限制其使用為2核。我們可以用實驗測試一下,在實際執行時,這個2核的限制是否有效。具體方法如下:

在命令列輸入如下命令,模擬一個無限迴圈的程序,把所有能用的CPU佔滿:

echo 'while True: pass'|python &

用top命令,可以看到CPU佔用為99.9%,可以理解為佔用了CPU的1核

進一步加大壓力,同時執行三個無限迴圈的程序:

echo 'while True: pass'|python &
echo 'while True: pass'|python &
echo 'while True: pass'|python &

用top命令看CPU佔用情況如下: 

可以看到每個程序佔用66.6%,三個程序加起來佔用約200%,應該就是CPU的2核。

進一步檢視grafna監控的指標,metrcs設定是:

sum(rate(container_cpu_usage_seconds_total{name=~"k8s_cloud-bdp-interface.*"}[5m]))
rate(container_cpu_user_seconds_total{name=~"k8s_cloud-bdp-interface.*"}[5m])
rate(container_cpu_system_seconds_total{name=~"k8s_cloud-bdp-interface.*"}[5m])
rate(container_cpu_cfs_throttled_seconds_total{name=~"k8s_cloud-bdp-interface.*"}[5m])

 監控結果如下:

可以看到,該容器服務的CPU佔用,usage指標和user指標都約等於2.0, 也就是佔用了2個CPU核心

小結

一般要對指定的容器服務進行監控,看一下 container_cpu_usage_seconds_total 指標就可以了。指標的格式如下:

sum(rate(container_cpu_usage_seconds_total{name=~"xxxxxxxxxxxxxxx.*"}[5m]))

要深入分析,可以再單獨看 user CPU時間, system CPU時間等等,用如下指標格式:

rate(container_cpu_user_seconds_total{name=~"xxxxxxxxxxxxxxx.*"}[5m])

rate(container_cpu_system_seconds_total{name=~"xxxxxxxxxxxxxxx.*"}[5m])

附:CPU相關指標的原始註釋

# HELP container_cpu_usage_seconds_total Cumulative cpu time consumed per cpu in seconds.
# TYPE container_cpu_usage_seconds_total counter
# HELP container_cpu_user_seconds_total Cumulative user cpu time consumed in seconds.
# TYPE container_cpu_user_seconds_total counter
# HELP container_cpu_cfs_periods_total Number of elapsed enforcement period intervals.
# TYPE container_cpu_cfs_periods_total counter
# HELP container_cpu_cfs_throttled_periods_total Number of throttled period intervals.
# TYPE container_cpu_cfs_throttled_periods_total counter
# HELP container_cpu_cfs_throttled_seconds_total Total time duration the container has been throttled.
# TYPE container_cpu_cfs_throttled_seconds_total counter
# HELP container_cpu_load_average_10s Value of container cpu load average over the last 10 seconds.
# TYPE container_cpu_load_average_10s gauge
# HELP container_cpu_system_seconds_total Cumulative system cpu time consumed in seconds.
# TYPE container_cpu_system_seconds_total counter