Skip to content

容器监控

容器监控要同时看宿主机、Docker daemon、容器资源和应用自身。只确认容器是 running 远远不够——CPU 打满、内存接近上限、磁盘涨满、容器频繁重启、OOM 和健康检查失败,都要能被发现。

监控的四个层次

层次关注点
宿主机CPU、内存、磁盘、inode、网络、内核日志
Docker daemon服务状态、事件、镜像和容器数量
容器CPU、内存、网络、块 IO、重启次数、健康状态
应用QPS、错误率、延迟、业务日志

容器监控是宿主机监控的补充,不是替代。容器跑在宿主机上,磁盘满、conntrack 满、Docker daemon 异常——根因最终仍然在宿主机层面。

docker stats——临时查看

bash
docker stats                  # 实时看所有运行容器的资源
docker stats --no-stream      # 只看一次,不持续刷新
字段说明
CPU %容器 CPU 使用率
MEM USAGE / LIMIT已用内存和限制值
MEM %内存使用比例
NET I/O网络收发字节
BLOCK I/O磁盘读写字节
PIDS进程数

docker stats 适合现场排查,不适合长期留存和趋势分析。长期趋势要接 Prometheus、Zabbix 或其他监控系统。

cAdvisor——容器资源指标采集

cAdvisor 采集容器 CPU、内存、网络、文件系统等指标,暴露 Prometheus 格式的 /metrics 接口:

bash
docker run -d \
  --name cadvisor \
  --restart unless-stopped \
  -p 127.0.0.1:8088:8080 \
  --volume=/:/rootfs:ro \
  --volume=/var/run:/var/run:ro \
  --volume=/sys:/sys:ro \
  --volume=/var/lib/docker/:/var/lib/docker:ro \
  gcr.io/cadvisor/cadvisor:v0.49.1

挂载说明:

挂载用途
/:/rootfs:ro读取宿主机文件系统信息
/var/run:/var/run:ro读取运行时 socket 和进程信息
/sys:/sys:ro读取 cgroups、设备、内核信息
/var/lib/docker:/var/lib/docker:ro读取 Docker 容器文件系统信息

cAdvisor 只绑定 127.0.0.1:8088。指标接口包含了宿主机和容器的详细信息,不适合直接暴露给公网或业务网络。如果 Prometheus 在另一台机器上,需要把 cAdvisor 暴露在监控网段,或通过反向代理限制访问来源。

Prometheus 抓取和常用指标

yaml
scrape_configs:
  - job_name: "cadvisor"
    static_configs:
      - targets:
          - "192.168.10.11:8088"

cAdvisor 指标很多,日常先关注这些:

指标含义
container_cpu_usage_seconds_total容器 CPU 累计使用时间
container_memory_working_set_bytes容器工作集内存(最接近 OOM 判断依据)
container_network_receive_bytes_total容器网络接收字节
container_network_transmit_bytes_total容器网络发送字节
container_fs_usage_bytes容器文件系统使用量
container_fs_reads_bytes_total容器读 IO
container_fs_writes_bytes_total容器写 IO

PromQL 示例:

promql
# 按容器看最近 5 分钟 CPU 使用速率
rate(container_cpu_usage_seconds_total{name!=""}[5m])

# 按容器看当前内存使用
container_memory_working_set_bytes{name!=""}

容器指标的标签在不同环境(Docker、K8s、containerd)里不完全一样——容器名、镜像名、实例、namespace 的标签名可能有差异。写告警规则前要先看实际标签,不要直接照搬别的环境的 PromQL。

Docker daemon 指标

Docker daemon 自身也可以暴露 Prometheus metrics。/etc/docker/daemon.json

json
{
  "metrics-addr": "127.0.0.1:9323",
  "experimental": true
}

experimental 在不同 Docker 版本里的要求不同,以当前版本官方文档和 dockerd --help 为准。

bash
sudo systemctl restart docker
curl http://127.0.0.1:9323/metrics | head

daemon metrics 偏向 Docker 自身状态(守护进程的 goroutine、API 请求延迟、镜像操作计数等),不替代 cAdvisor 的容器资源指标。这个端口也通常只绑定本机或监控网段。

日志和事件

监控不只是指标,还包括日志和事件:

bash
docker events --since 1h    # 最近 1 小时内的容器创建、停止、OOM 等事件
docker logs --since 30m app # 最近 30 分钟日志

生产环境里日志通常接到 Loki、ELK、Fluent Bit、Filebeat 或云日志服务。容器标准输出天然适合采集,但应用日志格式要稳定——日志结构不统一,查询和告警规则就很难维护。

告警方向

告警说明
宿主机磁盘使用率高/var/lib/docker、日志、volume 都会受影响
容器内存接近限制提前发现 OOM 风险,不要等 kill 了再查
容器频繁重启应用崩溃、配置错误、依赖不可用
健康检查失败服务进程还在但已不可用——比进程退出更难发现
镜像拉取失败仓库、网络、证书、权限问题
Docker daemon down单机所有容器的管理能力异常

容器频繁重启要配合应用日志一起看。只报"容器重启了 10 次"信息量不够,告警最好能同时带上退出码、OOMKilled 状态、最近日志摘要和镜像版本。

现场排查顺序

bash
# 第一步:容器层面
docker ps -a
docker inspect app --format '{{.State.Status}} {{.State.ExitCode}} {{.State.OOMKilled}}'
docker logs --tail 100 app
docker stats --no-stream app
journalctl -u docker -n 100 --no-pager

# 第二步:宿主机层面
df -h
df -ih
free -h
dmesg -T | tail -n 50
ss -lntp

容器监控的价值在于把"容器状态、资源曲线、宿主机状态、应用日志"四条线串起来。只看其中一条,Docker 问题、宿主机问题和应用问题很容易混在一起——排查效率取决于能不能快速定界到其中一层。