容器化环境里,想看清每个容器的真实资源消耗,cAdvisor 是最轻量的原生方案之一。它由 Google 开源,直接读取 cgroup 与文件系统,能把 CPU、内存、网络 IO、文件系统用量翻译成 Prometheus 格式指标。相比在业务里埋点,cAdvisor 对应用零侵入,部署后立刻能看到宿主机上所有容器的实时状态。

使用 Docker 快速启动 cAdvisor 的基础方法
最普遍的部署方式是通过官方镜像启动一个常驻容器。cAdvisor 需要访问宿主机的系统目录才能采集数据,因此必须把 /var/run/docker.sock、/sys、/proc 和 /var/lib/docker 等路径挂载进去。如果漏掉 /sys/fs/cgroup,在 cgroup v2 的机器上会无法识别限制值,页面上内存上限显示成 0。
下面是一段可直接运行的启动命令,其中 --privileged 是为了让 cAdvisor 读取部分受保护的内核统计,生产环境可改为更细的 capability 授权。端口映射把容器内的 8080 转到宿主 8080,访问网页即可看到机器与容器列表。
docker run --volume=/:/rootfs:ro --volume=/var/run:/var/run:ro --volume=/sys:/sys:ro --volume=/var/lib/docker/:/var/lib/docker/:ro --volume=/var/lib/containers:/var/lib/containers:ro --publish=8080:8080 --privileged --name=cadvisor --detach=true gcr.io/cadvisor/cadvisor:latest
启动后用浏览器打开 http://宿主机IP:8080 能看到原生 UI,而 /metrics 路径则输出 Prometheus 文本。需要注意,默认情况下 cAdvisor 只保留两分钟内的历史,久于此时长的数据会被丢弃,因此若要做趋势图,必须接外部存储或拉取器。
在资源受限的边缘节点,可以追加 --docker_only 减少非 Docker 容器的扫描开销,或用 --max_housekeeping_interval=30s 降低采集频率。这些参数能显著减少 cAdvisor 自身占用的内存,避免监控组件反过来拖垮业务容器。
通过 docker compose 与 systemd 管理长期运行
单机命令行适合验证,真正上线最好用编排文件固化参数。docker compose 能把挂载、重启策略与资源限制写在一起,避免每次手工敲错路径。下面的 compose.yaml 片段展示了带自动重启与只读挂载的写法,并显式禁用了 Swap 监控以兼容部分老旧内核。
version: "3"
services:
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
container_name: cadvisor
restart: unless-stopped
ports:
- "8080:8080"
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker:/var/lib/docker:ro
command:
- --disable_metrics=percpu,sched,disk,wifi
如果不想依赖 Docker 守护进程,也可用二进制加 systemd 托管。从发布页取下对应架构的 cadvisor 可执行文件,放进 /usr/local/bin,再写个 unit 文件指定 --port=8080 即可。这种形态在 Containerd 或 K3s 环境更干净,少了两层容器开销,但也要求你手动处理 cgroup 挂载点差异。
两种方案对比看,compose 改参数最直观,适合频繁调整采集项;systemd 二进制则启动更快、占用更低,适合监控 Agent 标准化的集群。无论哪种,都要设置 Restart=always 或 restart: unless-stopped,因为 cAdvisor 遇到 Docker 断连有时会退出而非重试。
对接 Prometheus 与常见排错场景
单独跑 cAdvisor 只能看近实时数据,接 Prometheus 才能留存与告警。在 Prometheus 的 scrape_configs 里加一个 job,目标指向 cAdvisor 的 /metrics,抓取间隔设 15 秒较为平衡。下面的配置片段演示了如何只拉取容器相关指标,减少无效序列。
scrape_configs:
- job_name: cadvisor
static_configs:
- targets: ["192.168.0.1:8080"]
metric_relabel_configs:
- source_labels: [__name__]
regex: container_(cpu|memory|network)_.*
action: keep
部署中常碰到的坑之一是 cgroup v2 主机上权限不足,日志报 failed to find cgroup。此时要确认挂载了 /sys/fs/cgroup 且为只读或可读写,并给容器加 --device=/dev/kmsg 在某些发行版才可访问内核日志。另一类是 SELinux 开启时拒绝访问 /var/run/docker.sock,需用 chcon 打标签或临时设 setenforce 0 验证。
还有一类隐蔽问题是端口冲突,当宿主机本身跑了 Node Exporter 占 8080 时,cAdvisor 会启动失败但不报明显错误。改 --port=9091 并同步 Prometheus 目标即可。网络策略层面,若跨主机抓取,记得放通防火墙,否则指标断点会造成 Grafana 面板大面积无数据。
理清了部署形态、长期管理与外部对接,cAdvisor 的落地就不再是黑盒。它虽不替代完整 APM,但作为资源水位底座,配合 PromQL 很快能写出“按命名空间汇总内存”的实用看板,为容量评估提供硬依据。