容器变多后
docker stats看不过来?一条docker run启动 cAdvisor,在 Web 页面查看宿主机和每个容器的 CPU、内存、磁盘 I/O 与网络占用,定位资源异常的容器。
容器只有两三个的时候,docker stats 临时看一眼基本够用;可一旦数量上到十几个,机器突然变慢再去逐个猜是哪个容器在吃 CPU、内存为什么持续涨、磁盘又被谁写满,就变得很盲目。常见的选择是先跑一个 cAdvisor(Container Advisor),把宿主机和每个容器当前的 CPU、内存、文件系统和网络指标搬到 Web 页面上来,先把资源状态变成可见的,再决定要不要继续接 Prometheus、Grafana 这种更完整的监控栈 [1][5]。
cAdvisor 由 Google 开源,会自动发现本机所有容器,通过 Linux 的 cgroups、procfs、sysfs 等机制读取内核暴露的资源统计信息 [3][4],再通过内置 Web 页面(容器内默认 8080 端口)和 HTTP 接口把数据展示出来。它不能自动修复故障,也不自带长期历史和告警——这些是后面接 InfluxDB、Prometheus 才有的事。先把”现在谁吃了多少资源”看清楚,是它最直接的价值 [1][5]。
一条 docker run 把 cAdvisor 跑起来
起步就是一条 docker run,把 cAdvisor 跑成容器,再把宿主机 8087 映射到容器内 8080。下面的命令按官方文档的写法 [6],版本用写这篇时的最新版 v0.60.6 [7]:
docker run -d --name=cadvisor \
--privileged \
--volume=/:/rootfs:ro \
--volume=/var/run:/var/run:rw \
--volume=/sys:/sys:ro \
--volume=/var/lib/docker/:/var/lib/docker:ro \
--publish=8087:8080 \
ghcr.io/google/cadvisor:v0.60.6
外面访问用的是宿主机 8087,cAdvisor 容器内仍是它自身的默认 8080 [1];所以 8087 只是这次 Docker 映射出来的主机端口,不要直接当成 cAdvisor 的固定默认端口。
注意镜像地址:从 v0.53.0 起官方镜像发布在 ghcr.io/google/cadvisor,gcr.io/cadvisor/cadvisor 只有更早的版本 [6]。不少教程里的 gcr.io/cadvisor/cadvisor:v0.47.0 是 2023 年的版本,能用,但不是最新。网上还流传 lagoudocker/cadvisor:v0.37.0 这类社区重新打包的镜像,那是 2020 年的版本,对 cgroup v2 的支持远不如新版,来源也无从核实,不建议用;ghcr.io 拉不下来时,优先用可信的镜像加速,或自己把官方镜像同步到私有仓库。
cAdvisor 本身没有配置文件,所有配置都在命令行参数里;要停止或重建,先 docker stop cadvisor && docker rm cadvisor,再跑更新后的 docker run。
--privileged 和四个挂载到底是干嘛的
这条命令里最容易被略过的部分是 --privileged 和四个 --volume 挂载,但它们决定了 cAdvisor 能不能正常读到这台机器上的资源数据。
cAdvisor 读取容器和宿主机资源数据的底层来源是 cgroups、procfs 和 sysfs [3][4]。Linux 把这些信息暴露在 /sys/fs/cgroup(cgroups 各子系统)、/proc/<PID>/(进程级统计,例如网络数据来自 /proc/<PID>/net/dev)以及 /sys/(sysfs)等目录里 [4]。这意味着 cAdvisor 容器必须能”看到”宿主机的对应目录,并且不能停留在自己 PID namespace 内的同名路径——所以这里加了 --privileged,配合 --volume=/:/rootfs:ro、--volume=/sys:/sys:ro 把宿主机的根目录和 sysfs 以只读方式挂进容器 [1][3];/var/run 里有 Docker 的 socket,cAdvisor 要通过它和 Docker 通信,官方文档的写法是 rw [6]。/var/lib/docker/:/var/lib/docker:ro 这一项则是为了让 cAdvisor 能拿到 Docker 的容器元数据和层信息,没它通常只能看到宿主机自身,看不到完整的容器列表 [1][3]。
官方文档的基础命令里没有 --privileged,但在 CentOS、RHEL 这类对容器限制更严的系统上,以及采集进程级指标时,文档要求加上它 [6]。实际部署中,不加时 /docker 下看不到容器的情况也不少见,所以本文的命令直接带上。只要加了它,cAdvisor 就不是一个低权限的普通 Web 容器。它更适合放在自己控制的主机上,不建议直接暴露到公网;如果需要远程访问,按官方文档和自选的内网穿透方案自行加认证 [1]。
页面怎么看:从整机 → /docker → 单容器
启动完成后浏览器打开 http://<宿主机IP>:8087 就会进入 cAdvisor 主页 [1][5]。常见的排查路径分三层,逐层往下钻。
第一层是主机资源页。打开主页直接看到的是宿主机级别的 CPU、内存、文件系统、网络汇总——这一步回答的是”机器整体压力有多大” [1]。
第二层是容器列表。点击页面上方的 /docker 路径会进入容器列表,每个正在运行的容器都会列出来并显示资源占用概览 [1][2]。这一步回答的是”如果整体压力大,是哪些容器在贡献”。
第三层是单容器详情。继续点开某个具体容器或它的 Subcontainers,就可以看到更细的 CPU、内存、文件系统、网络以及 cgroup 配额等指标 [1][2]。页面里的配额来自 cgroup。例如 docker run --cpus=1 -m=2G 起出来的容器,在 cgroup v1 下内存上限写在 memory.limit_in_bytes 里 [4];现在多数发行版(Ubuntu 22.04、Debian 12、RHEL 9 及之后的版本)默认用 cgroup v2,对应的文件是 memory.max,目录结构也不一样。不确定自己的机器是哪种,可以执行 stat -fc %T /sys/fs/cgroup/:输出 cgroup2fs 是 v2,tmpfs 是 v1。
排查”机器突然变卡”这类问题时,常见做法就是按这三层从粗到细往下走:先看整机指标判断是不是真到了瓶颈,再在容器列表里挑出 Top 占用,最后点进单容器看具体进程或子容器。这种顺序比一开始就挨个 docker stats 盲看要直接得多 [2][5]。
启动失败时的两种典型报错
第一种是镜像拉不下来。先确认地址写对了:新版本在 ghcr.io/google/cadvisor,在 gcr.io 上找新版本 tag 本来就找不到 [6]。地址没错但网络不通时,用可信的镜像加速或私有仓库中转,不要换成来源不明的旧版重打包镜像。
第二种是容器启动后立刻退出,日志里出现类似 Failed to create a Container Manager: mountpoint for cpu not found 的错误 [3]。这条错误说明 cAdvisor 没找到它预期的 cgroup 挂载点。最常见的情况是宿主机用的是 cgroup v2,而镜像是对 v2 支持不完整的旧版本。先用上面的 stat -fc %T /sys/fs/cgroup/ 确认 cgroup 版本,是 v2 就换成近期的版本;cAdvisor 从 2021 年的 v0.40 起陆续修了一批 cgroup v2 的问题 [7]。还要检查 /sys 等目录是否按上面的命令挂进去了。在 CentOS、RHEL 的一些版本上,cgroup 挂在 /cgroup 下,官方文档建议额外加 --volume=/cgroup:/cgroup:ro [6]。有的教程还会加挂 /dev/disk、加 --device=/dev/kmsg [3],在官方文档里这是采集磁盘信息和 perf 事件时的写法 [6],不是这条报错的通用解法。
cAdvisor 能做什么、不能做什么
如果只是第一次给 Docker 加监控,cAdvisor 的优势在于先把容器资源变成可见,再决定要不要继续往上接 Prometheus、Grafana 这种更完整的栈 [1][5]。它的能力边界大致是这样:
它能做的:自动发现本机容器(基于 Docker、containerd 等运行时)[5];实时采集 CPU 使用率、内存使用量、磁盘 I/O、网络带宽等指标 [3][5];内置 Web 页面直接展示 [1][5];同时暴露 HTTP 接口,方便上层采集系统拉取 [4]。Kubernetes 也把 cAdvisor 作为默认容器监控组件集成进去 [4]。
它做不了或者默认不做:默认不持久化历史,关掉或重启后当前指标就清零 [3][4][5];不带告警规则;不带高级可视化看板;也不带跨主机的统一视图——这些能力都要靠把数据导出到 InfluxDB、Prometheus 等后端,再视情况配合 Grafana 完成 [3][4][5]。
所以这篇把它定位成”先把容器资源看见”的入口。CPU、内存、磁盘和网络这几项指标在 cAdvisor 页面里都看得到,但有跨主机或长期排查需求时,需要再往上搭一层 [1][2]。
FAQ
Q1:cAdvisor 自带 Web 页面的指标数据能保留多久?
默认不持久化历史。容器重启或宿主机重启之后,页面上的指标就从当前时刻重新累计,之前的数据不会被保留 [3][4][5]。如果需要长期历史或告警,要按官方文档的指导把数据接到 Prometheus 或 InfluxDB,再视情况配合 Grafana 做可视化 [3][4][5]。
Q2:页面里的”网络”指标看着很小,是不是漏了什么?
cAdvisor 读取的是 cgroup 与 procfs 视角下的网络数据,底层来源是 /proc/<PID>/net/dev 这类文件 [4],统计的是容器持有的网卡收发。如果关注的是跨主机网络、桥接流量或某个特定接口的统计,单看 cAdvisor 页面里的网络一项是不够的,需要从宿主机侧用 ss、iftop、ip -s link 等工具,或上层网络监控进一步确认,不能只依赖 cAdvisor 的一个数字判断。
Q3:cAdvisor 的版本怎么选?
直接用 GitHub Releases 页面上的最新版 [7],写这篇时是 v0.60.6,镜像地址是 ghcr.io/google/cadvisor。教程里常见的 v0.47.0 是 2023 年的版本,v0.37.0 更是 2020 年的;在默认 cgroup v2 的新系统上,版本越旧越容易出现指标缺失或起不来。
参考来源
[1] 别只会docker stats了:cAdvisor把CPU、内存、磁盘和网络监控搬进Web页面 – CSDN技术社区
[2] Docker 容器谁在吃 CPU?用 cAdvisor 把资源占用直接看清楚 – CSDN技术社区
[3] docker服务监控之cAdvisor – huangSir-devops(博客园)
[4] 容器监控:容器监控原理及cAdvisor的安装与使用 – 羊脂玉净瓶(博客园)
[5] 服务器突然变卡?先别重启,看看是不是某个容器在偷吃资源 – CSDN技术社区


暂无评论内容