Appearance
容器监控
容器监控要同时看宿主机、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 | headdaemon 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 问题、宿主机问题和应用问题很容易混在一起——排查效率取决于能不能快速定界到其中一层。