主頁 > 知識庫 > Docker 容器監(jiān)控原理及 cAdvisor的安裝與使用說明

Docker 容器監(jiān)控原理及 cAdvisor的安裝與使用說明

熱門標(biāo)簽:網(wǎng)站建設(shè) 智能手機 硅谷的囚徒呼叫中心 美圖手機 阿里云 使用U盤裝系統(tǒng) 檢查注冊表項 百度競價點擊價格的計算公式

生產(chǎn)環(huán)境中監(jiān)控容器的運行狀況十分重要,通過監(jiān)控我們可以隨時掌握容器的運行狀態(tài),做到線上隱患和問題早發(fā)現(xiàn),早解決。

所以今天我就和你分享關(guān)于容器監(jiān)控的知識(原理及工具 cAdvisor)。

雖然傳統(tǒng)的物理機和虛擬機監(jiān)控已經(jīng)有了比較成熟的監(jiān)控方案,但是容器的監(jiān)控面臨著更大的挑戰(zhàn),因為容器的行為和本質(zhì)與傳統(tǒng)的虛擬機是不一樣的,總的來說,容器具有以下特性:

容器是短期存活的,并且可以動態(tài)調(diào)度

容器的本質(zhì)是進(jìn)程,而不是一個完整操作系統(tǒng)

由于容器非常輕量,容器的創(chuàng)建和銷毀也會比傳統(tǒng)虛擬機更加頻繁

Docker 容器的監(jiān)控方案有很多,除了 Docker 自帶的docker stats命令,還有很多開源的解決方案,例如 sysdig、cAdvisor、Prometheus 等,都是非常優(yōu)秀的監(jiān)控工具。

下面我們首先來看下,不借助任何外部工具,如何用 Docker 自帶的docker stats命令實現(xiàn)容器的監(jiān)控。

使用 docker stats 命令

使用 Docker 自帶的docker stats命令可以很方便地看到主機上所有容器的 CPU、內(nèi)存、網(wǎng)絡(luò) IO、磁盤 IO、PID 等資源的使用情況。下面我們可以具體操作看看。

首先在主機上使用以下命令啟動一個資源限制為 1 核 2G 的 nginx 容器:

$ docker run --cpus=1 -m=2g --name=nginx -d nginx

容器啟動后,可以使用docker stats命令查看容器的資源使用狀態(tài):

$ docker stats nginx

通過docker stats命令可以看到容器的運行狀態(tài)如下:

CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS

f742a467b6d8 0.00% 1.387 MiB / 2 GiB 0.07% 656 B / 656 B 0 B / 9.22 kB 2

從容器的運行狀態(tài)可以看出,docker stats命令確實可以獲取并顯示 Docker 容器運行狀態(tài)。但是它的缺點也很明顯,因為它只能獲取本機數(shù)據(jù),無法查看歷史監(jiān)控數(shù)據(jù),沒有可視化展示面板。

因此,生產(chǎn)環(huán)境中我們通常使用另一種容器監(jiān)控解決方案 cAdvisor。

cAdvisor

cAdvisor 是谷歌開源的一款通用的容器監(jiān)控解決方案。cAdvisor 不僅可以采集機器上所有運行的容器信息,還提供了基礎(chǔ)的查詢界面和 HTTP 接口,更方便與外部系統(tǒng)結(jié)合。所以,cAdvisor很快成了容器指標(biāo)監(jiān)控最常用組件,并且 Kubernetes 也集成了 cAdvisor 作為容器監(jiān)控指標(biāo)的默認(rèn)工具。

cAdvisor 的安裝與使用

下面我們以 cAdvisor 0.37.0 版本為例,演示一下 cAdvisor 的安裝與使用。

cAdvisor 官方提供了 Docker 鏡像,我們只需要拉取鏡像并且啟動鏡像即可。

由于 cAdvisor 鏡像存放在谷歌的 gcr.io 鏡像倉庫中,國內(nèi)無法訪問到。這里我把打好的鏡像放在了 Docker Hub。你可以使用 docker pull lagoudocker/cadvisor:v0.37.0 命令從 Docker Hub 拉取。

首先使用以下命令啟動 cAdvisor:

$ docker run \

 --volume=/:/rootfs:ro \

 --volume=/var/run:/var/run:ro \

 --volume=/sys:/sys:ro \

 --volume=/var/lib/docker/:/var/lib/docker:ro \

 --volume=/dev/disk/:/dev/disk:ro \

 --publish=8080:8080 \

 --detach=true \

 --name=cadvisor \

 --privileged \

 --device=/dev/kmsg \

 lagoudocker/cadvisor:v0.37.0

此時,cAdvisor 已經(jīng)成功啟動,我們可以通過訪問 http://localhost:8080 訪問到 cAdvisor 的 Web 界面。

cAdvisor 不僅可以監(jiān)控容器的資源使用情況,還可以監(jiān)控主機的資源使用情況。下面我們就先看下它是如何查看主機資源使用情況的。

使用 cAdvisor 查看主機監(jiān)控

訪問 http://localhost:8080/containers/ 地址,在首頁可以看到主機的資源使用情況,包含 CPU、內(nèi)存、文件系統(tǒng)、網(wǎng)絡(luò)等資源,如下圖所示。

使用 cAdvisor 查看容器監(jiān)控

如果你想要查看主機上運行的容器資源使用情況,可以訪問 http://localhost:8080/docker/,這個頁面會列出 Docker 的基本信息和運行的容器情況,如下圖所示。

在上圖中的 Subcontainers 下會列出當(dāng)前主機上運行的所有容器,點擊其中一個容器即可查看該容器的詳細(xì)運行狀態(tài),如下圖所示。

總體來說,使用 cAdvisor 監(jiān)控容器具有以下特點:

可以同時采集物理機和容器的狀態(tài)

可以展示監(jiān)控歷史數(shù)據(jù)

了解 Docker 的監(jiān)控工具,你是否想問,這些監(jiān)控數(shù)據(jù)是怎么來的呢?下面我就帶你了解一下容器監(jiān)控的原理。

監(jiān)控原理

我們知道 Docker 是基于 Namespace、Cgroups 和聯(lián)合文件系統(tǒng)實現(xiàn)的。其中 Cgroups 不僅可以用于容器資源的限制,還可以提供容器的資源使用率。無論何種監(jiān)控方案的實現(xiàn),底層數(shù)據(jù)都來源于 Cgroups。

Cgroups 的工作目錄為/sys/fs/cgroup,/sys/fs/cgroup目錄下包含了 Cgroups 的所有內(nèi)容。Cgroups包含很多子系統(tǒng),可以用來對不同的資源進(jìn)行限制。例如對CPU、內(nèi)存、PID、磁盤 IO等資源進(jìn)行限制和監(jiān)控。

為了更詳細(xì)的了解 Cgroups 的子系統(tǒng),我們通過 ls -l 命令查看/sys/fs/cgroup文件夾,可以看到很多目錄:

$ sudo ls -l /sys/fs/cgroup/
total 0
 
dr-xr-xr-x 5 root root 0 Jul 9 19:32 blkio
lrwxrwxrwx 1 root root 11 Jul 9 19:32 cpu -> cpu,cpuacct
dr-xr-xr-x 5 root root 0 Jul 9 19:32 cpu,cpuacct
lrwxrwxrwx 1 root root 11 Jul 9 19:32 cpuacct -> cpu,cpuacct
dr-xr-xr-x 3 root root 0 Jul 9 19:32 cpuset
dr-xr-xr-x 5 root root 0 Jul 9 19:32 devices
dr-xr-xr-x 3 root root 0 Jul 9 19:32 freezer
dr-xr-xr-x 3 root root 0 Jul 9 19:32 hugetlb
dr-xr-xr-x 5 root root 0 Jul 9 19:32 memory
lrwxrwxrwx 1 root root 16 Jul 9 19:32 net_cls -> net_cls,net_prio
dr-xr-xr-x 3 root root 0 Jul 9 19:32 net_cls,net_prio
lrwxrwxrwx 1 root root 16 Jul 9 19:32 net_prio -> net_cls,net_prio
dr-xr-xr-x 3 root root 0 Jul 9 19:32 perf_event
dr-xr-xr-x 5 root root 0 Jul 9 19:32 pids
dr-xr-xr-x 5 root root 0 Jul 9 19:32 systemd

這些目錄代表了 Cgroups 的子系統(tǒng),Docker 會在每一個 Cgroups 子系統(tǒng)下創(chuàng)建 docker 文件夾。這里如果你對 Cgroups 子系統(tǒng)不了解的話,不要著急,這里你只需要明白容器監(jiān)控數(shù)據(jù)來源于 Cgroups 即可。

監(jiān)控系統(tǒng)是如何獲取容器的內(nèi)存限制的?

下面我們以 memory 子系統(tǒng)(memory 子系統(tǒng)是Cgroups 眾多子系統(tǒng)的一個,主要用來限制內(nèi)存使用)為例,講解一下監(jiān)控組件是如何獲取到容器的資源限制和使用狀態(tài)的(即容器的內(nèi)存限制)。

我們首先在主機上使用以下命令啟動一個資源限制為 1 核 2G 的 nginx 容器:

$ docker run --name=nginx --cpus=1 -m=2g --name=nginx -d nginx

## 這里輸出的是容器 ID

51041a74070e9260e82876974762b8c61c5ed0a51832d74fba6711175f89ede1

注意:如果你已經(jīng)創(chuàng)建過名稱為 nginx 的容器,請先使用 docker rm -f nginx 命令刪除已經(jīng)存在的 nginx 容器。

容器啟動后,我們通過命令行的輸出可以得到容器的 ID,同時 Docker 會在/sys/fs/cgroup/memory/docker目錄下以容器 ID 為名稱創(chuàng)建對應(yīng)的文件夾。

下面我們查看一下/sys/fs/cgroup/memory/docker目錄下的文件:

$ sudo ls -l /sys/fs/cgroup/memory/docker
total 0
 
drwxr-xr-x 2 root root 0 Sep 2 15:12 51041a74070e9260e82876974762b8c61c5ed0a51832d74fba6711175f89ede1
-rw-r--r-- 1 root root 0 Sep 2 14:57 cgroup.clone_children
--w--w--w- 1 root root 0 Sep 2 14:57 cgroup.event_control
-rw-r--r-- 1 root root 0 Sep 2 14:57 cgroup.procs
-rw-r--r-- 1 root root 0 Sep 2 14:57 memory.failcnt
--w------- 1 root root 0 Sep 2 14:57 memory.force_empty
-rw-r--r-- 1 root root 0 Sep 2 14:57 memory.kmem.failcnt
-rw-r--r-- 1 root root 0 Sep 2 14:57 memory.kmem.limit_in_bytes
-rw-r--r-- 1 root root 0 Sep 2 14:57 memory.kmem.max_usage_in_bytes
-r--r--r-- 1 root root 0 Sep 2 14:57 memory.kmem.slabinfo
-rw-r--r-- 1 root root 0 Sep 2 14:57 memory.kmem.tcp.failcnt
-rw-r--r-- 1 root root 0 Sep 2 14:57 memory.kmem.tcp.limit_in_bytes
-rw-r--r-- 1 root root 0 Sep 2 14:57 memory.kmem.tcp.max_usage_in_bytes
-r--r--r-- 1 root root 0 Sep 2 14:57 memory.kmem.tcp.usage_in_bytes
-r--r--r-- 1 root root 0 Sep 2 14:57 memory.kmem.usage_in_bytes
-rw-r--r-- 1 root root 0 Sep 2 14:57 memory.limit_in_bytes
-rw-r--r-- 1 root root 0 Sep 2 14:57 memory.max_usage_in_bytes
-rw-r--r-- 1 root root 0 Sep 2 14:57 memory.memsw.failcnt
-rw-r--r-- 1 root root 0 Sep 2 14:57 memory.memsw.limit_in_bytes
-rw-r--r-- 1 root root 0 Sep 2 14:57 memory.memsw.max_usage_in_bytes
-r--r--r-- 1 root root 0 Sep 2 14:57 memory.memsw.usage_in_bytes
-rw-r--r-- 1 root root 0 Sep 2 14:57 memory.move_charge_at_immigrate
-r--r--r-- 1 root root 0 Sep 2 14:57 memory.numa_stat
-rw-r--r-- 1 root root 0 Sep 2 14:57 memory.oom_control
---------- 1 root root 0 Sep 2 14:57 memory.pressure_level
-rw-r--r-- 1 root root 0 Sep 2 14:57 memory.soft_limit_in_bytes
-r--r--r-- 1 root root 0 Sep 2 14:57 memory.stat
-rw-r--r-- 1 root root 0 Sep 2 14:57 memory.swappiness
-r--r--r-- 1 root root 0 Sep 2 14:57 memory.usage_in_bytes
-rw-r--r-- 1 root root 0 Sep 2 14:57 memory.use_hierarchy
-rw-r--r-- 1 root root 0 Sep 2 14:57 notify_on_release
-rw-r--r-- 1 root root 0 Sep 2 14:57 tasks

可以看到 Docker 已經(jīng)創(chuàng)建了以容器 ID 為名稱的目錄,我們再使用 ls 命令查看一下該目錄的內(nèi)容:

$ sudo ls -l /sys/fs/cgroup/memory/docker/51041a74070e9260e82876974762b8c61c5ed0a51832d74fba6711175f89ede1
 
total 0
-rw-r--r-- 1 root root 0 Sep 2 15:21 cgroup.clone_children
--w--w--w- 1 root root 0 Sep 2 15:13 cgroup.event_control
-rw-r--r-- 1 root root 0 Sep 2 15:12 cgroup.procs
-rw-r--r-- 1 root root 0 Sep 2 15:12 memory.failcnt
--w------- 1 root root 0 Sep 2 15:21 memory.force_empty
-rw-r--r-- 1 root root 0 Sep 2 15:21 memory.kmem.failcnt
-rw-r--r-- 1 root root 0 Sep 2 15:12 memory.kmem.limit_in_bytes
-rw-r--r-- 1 root root 0 Sep 2 15:21 memory.kmem.max_usage_in_bytes
-r--r--r-- 1 root root 0 Sep 2 15:21 memory.kmem.slabinfo
-rw-r--r-- 1 root root 0 Sep 2 15:21 memory.kmem.tcp.failcnt
-rw-r--r-- 1 root root 0 Sep 2 15:21 memory.kmem.tcp.limit_in_bytes
-rw-r--r-- 1 root root 0 Sep 2 15:21 memory.kmem.tcp.max_usage_in_bytes
-r--r--r-- 1 root root 0 Sep 2 15:21 memory.kmem.tcp.usage_in_bytes
-r--r--r-- 1 root root 0 Sep 2 15:21 memory.kmem.usage_in_bytes
-rw-r--r-- 1 root root 0 Sep 2 15:12 memory.limit_in_bytes
-rw-r--r-- 1 root root 0 Sep 2 15:12 memory.max_usage_in_bytes
-rw-r--r-- 1 root root 0 Sep 2 15:21 memory.memsw.failcnt
-rw-r--r-- 1 root root 0 Sep 2 15:12 memory.memsw.limit_in_bytes
-rw-r--r-- 1 root root 0 Sep 2 15:21 memory.memsw.max_usage_in_bytes
-r--r--r-- 1 root root 0 Sep 2 15:21 memory.memsw.usage_in_bytes
-rw-r--r-- 1 root root 0 Sep 2 15:21 memory.move_charge_at_immigrate
-r--r--r-- 1 root root 0 Sep 2 15:21 memory.numa_stat
-rw-r--r-- 1 root root 0 Sep 2 15:13 memory.oom_control
---------- 1 root root 0 Sep 2 15:21 memory.pressure_level
-rw-r--r-- 1 root root 0 Sep 2 15:21 memory.soft_limit_in_bytes
-r--r--r-- 1 root root 0 Sep 2 15:21 memory.stat
-rw-r--r-- 1 root root 0 Sep 2 15:21 memory.swappiness
-r--r--r-- 1 root root 0 Sep 2 15:12 memory.usage_in_bytes
-rw-r--r-- 1 root root 0 Sep 2 15:21 memory.use_hierarchy
-rw-r--r-- 1 root root 0 Sep 2 15:21 notify_on_release
-rw-r--r-- 1 root root 0 Sep 2 15:21 tasks

由上可以看到,容器 ID 的目錄下有很多文件,其中 memory.limit_in_bytes 文件代表該容器內(nèi)存限制大小,單位為 byte,我們使用 cat 命令(cat 命令可以查看文件內(nèi)容)查看一下文件內(nèi)容:

$ sudo cat /sys/fs/cgroup/memory/docker/51041a74070e9260e82876974762b8c61c5ed0a51832d74fba6711175f89ede1/memory.limit_in_bytes

2147483648

這里可以看到memory.limit_in_bytes 的值為2147483648,轉(zhuǎn)換單位后正好為 2G,符合我們啟動容器時的內(nèi)存限制 2G。

通過 memory 子系統(tǒng)的例子,我們可以知道監(jiān)控組件通過讀取 memory.limit_in_bytes 文件即可獲取到容器內(nèi)存的限制值。了解完容器的內(nèi)存限制我們來了解一下容器的內(nèi)存使用情況。

$ sudo /sys/fs/cgroup/memory/docker/51041a74070e9260e82876974762b8c61c5ed0a51832d74fba6711175f89ede1/memory.usage_in_bytes

4259840

可以看到當(dāng)前內(nèi)存的使用大小為 4259840 byte,約為 4 M。了解了內(nèi)存的監(jiān)控。

下面我們來了解下網(wǎng)絡(luò)的監(jiān)控數(shù)據(jù)來源

網(wǎng)絡(luò)的監(jiān)控數(shù)據(jù)來源是從 /proc/{PID}/net/dev 目錄下讀取的,其中 PID 為容器在主機上的進(jìn)程 ID。下面我們首先使用 docker inspect 命令查看一下上面啟動的 nginx 容器的 PID,命令如下:

$ docker inspect nginx |grep Pid
 
   "Pid": 27348,
 
   "PidMode": "",
 
   "PidsLimit": 0,

可以看到容器的 PID 為 27348,使用 cat 命令查看一下 /proc/27348/net/dev 的內(nèi)容

$ sudo cat /proc/27348/net/dev
Inter-| Receive            | Transmit
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
 
 lo:  0  0 0 0 0  0   0   0  0  0 0 0 0  0  0   0
 
 eth0:  0  0 0 0 0  0   0   0  0  0 0 0 0  0  0   0

/proc/27348/net/dev 文件記錄了該容器里每一個網(wǎng)卡的流量接收和發(fā)送情況,以及錯誤數(shù)、丟包數(shù)等信息??梢娙萜鞯木W(wǎng)絡(luò)監(jiān)控數(shù)據(jù)都是定時從這里讀取并展示的。

總結(jié)一下,容器的監(jiān)控原理其實就是定時讀取 Linux 主機上相關(guān)的文件并展示給用戶。

結(jié)語

k8s后面使用metrics serve,cAdvisor 是提供底層數(shù)據(jù)的,metrics-server 底層數(shù)據(jù)來源是 cAdvisor

cAdvisor 是提供監(jiān)控數(shù)據(jù)的,Prometheus 是負(fù)責(zé)采集的數(shù)據(jù)的,這兩個作用是不一樣的,生產(chǎn)集群中一般都是 cAdvisor 配合 Prometheus 一起使用。

以上這篇Docker 容器監(jiān)控原理及 cAdvisor的安裝與使用說明就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

標(biāo)簽:賀州 懷化 黃山 山南 湖北 湘潭 通遼 煙臺

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Docker 容器監(jiān)控原理及 cAdvisor的安裝與使用說明》,本文關(guān)鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266