Docker 完全指南 / 14 - 监控方案
14 - 监控方案
使用 cAdvisor、Prometheus、Grafana 构建完整的容器监控体系。
14.1 容器监控概述
监控指标分类
| 类别 | 指标 | 说明 |
|---|---|---|
| 资源指标 | CPU、内存、磁盘 I/O、网络 I/O | 容器资源使用情况 |
| 容器指标 | 运行状态、重启次数、健康检查 | 容器生命周期 |
| 应用指标 | 请求延迟、错误率、吞吐量 | 应用性能 |
| 宿主机指标 | 内核版本、磁盘空间、系统负载 | 底层基础设施 |
常用监控工具
| 工具 | 定位 | 特点 |
|---|---|---|
docker stats | 基础 CLI | 实时查看,无历史数据 |
| cAdvisor | 容器指标采集 | Google 开源,自动发现容器 |
| Prometheus | 指标存储与时序数据库 | 拉取模型,强大的查询语言 |
| Grafana | 可视化面板 | 丰富的仪表板,多数据源 |
| Datadog | SaaS 监控平台 | 商业方案,功能全面 |
| Zabbix | 传统监控 | 企业级,学习曲线较陡 |
14.2 Docker 原生监控
docker stats
# 实时查看所有容器资源使用
docker stats
# 输出示例:
# CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
# web 0.15% 15MiB / 256MiB 5.86% 1.2kB / 0B 0B / 0B 2
# db 1.25% 120MiB / 512MiB 23.4% 5.6kB / 2.1kB 12MB / 0B 8
# 仅查看一次(不持续更新)
docker stats --no-stream
# 指定输出格式
docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}"
# JSON 格式输出
docker stats --no-stream --format '{"name":"{{.Name}}","cpu":"{{.CPUPerc}}","mem":"{{.MemUsage}}"}'
docker inspect
# 获取容器详细资源信息
docker inspect my-container | jq '.[0].HostConfig'
# 查看容器网络统计
docker exec my-container cat /proc/net/dev
# 查看容器 CPU 使用
docker exec my-container cat /proc/stat
# 查看容器内存使用
docker exec my-container cat /proc/meminfo
14.3 cAdvisor
cAdvisor (Container Advisor) 是 Google 开源的容器资源监控工具,自动采集容器的 CPU、内存、网络和磁盘使用数据。
部署 cAdvisor
# 快速部署
docker run -d \
--name cadvisor \
--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 \
--privileged \
--device /dev/kmsg \
gcr.io/cadvisor/cadvisor:v0.47.0
Docker Compose 部署
services:
cadvisor:
image: gcr.io/cadvisor/cadvisor:v0.47.0
container_name: cadvisor
ports:
- "8080:8080"
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
- /dev/disk/:/dev/disk:ro
devices:
- /dev/kmsg:/dev/kmsg
privileged: true
restart: unless-stopped
cAdvisor 界面
访问 http://localhost:8080
界面功能:
├── Subcontainers: 所有容器列表
├── Docker Containers: Docker 容器详情
├── 单容器页面:
│ ├── CPU 使用率曲线
│ ├── 内存使用曲线
│ ├── 网络 I/O 曲线
│ ├── 文件系统使用
│ └── 进程列表
└── Prometheus 指标端点: /metrics
14.4 Prometheus
Prometheus 架构
监控数据流:
┌──────────┐ pull ┌────────────┐ PromQL ┌──────────┐
│ cAdvisor │ ────────> │ Prometheus │ ─────────> │ Grafana │
└──────────┘ └────────────┘ └──────────┘
┌──────────┐ pull │
│ 应用程序 │ ────────> │
└──────────┘ │
┌──────────┐ push ┌────┴───────┐
│ 短期任务 │ ────────> │ Pushgateway│
└──────────┘ └────────────┘
prometheus.yml 配置
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
# Prometheus 自身监控
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
# cAdvisor 容器监控
- job_name: 'cadvisor'
static_configs:
- targets: ['cadvisor:8080']
metrics_path: /metrics
# Docker Engine 指标
- job_name: 'docker'
static_configs:
- targets: ['host.docker.internal:9323']
Docker Compose 完整监控栈
services:
# ---- cAdvisor ----
cadvisor:
image: gcr.io/cadvisor/cadvisor:v0.47.0
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
- /dev/disk/:/dev/disk:ro
devices:
- /dev/kmsg:/dev/kmsg
privileged: true
restart: unless-stopped
# ---- Prometheus ----
prometheus:
image: prom/prometheus:v2.49.0
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prometheus-data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.retention.time=30d'
- '--storage.tsdb.path=/prometheus'
restart: unless-stopped
# ---- Grafana ----
grafana:
image: grafana/grafana:10.2.0
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=admin123
- GF_INSTALL_PLUGINS=
volumes:
- grafana-data:/var/lib/grafana
- ./grafana/provisioning:/etc/grafana/provisioning
restart: unless-stopped
volumes:
prometheus-data:
grafana-data:
启用 Docker Engine 指标
// /etc/docker/daemon.json
{
"metrics-addr": "0.0.0.0:9323",
"experimental": true
}
# 重启 Docker
sudo systemctl restart docker
# 验证指标端点
curl http://localhost:9323/metrics
14.5 Grafana 配置
添加数据源
1. 访问 http://localhost:3000
2. 登录: admin / admin123
3. Configuration → Data Sources → Add data source
4. 选择 Prometheus
5. URL: http://prometheus:9090
6. Save & Test
推荐仪表板
| Dashboard ID | 名称 | 说明 |
|---|---|---|
| 893 | Docker & System Monitoring | Docker 容器和系统监控 |
| 193 | Docker container monitoring | 容器详细监控 |
| 1860 | Node Exporter Full | 宿主机监控 |
| 14282 | Cadvisor Exporter | cAdvisor 专用 |
导入仪表板:
1. Grafana → + → Import
2. 输入 Dashboard ID (如 893)
3. 选择 Prometheus 数据源
4. Import
Grafana 自动配置数据源
# grafana/provisioning/datasources/datasource.yml
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
editable: true
14.6 Prometheus 常用查询
容器 CPU 使用率
# 容器 CPU 使用率百分比
rate(container_cpu_usage_seconds_total{name=~".+"}[5m]) * 100
# 按容器名称查看
rate(container_cpu_usage_seconds_total{name="web"}[5m]) * 100
# 所有容器 CPU 使用排行
topk(5, rate(container_cpu_usage_seconds_total{name=~".+"}[5m]) * 100)
容器内存使用
# 容器内存使用量 (MB)
container_memory_usage_bytes{name=~".+"} / 1024 / 1024
# 容器内存使用百分比
container_memory_usage_bytes{name=~".+"} / container_spec_memory_limit_bytes{name=~".+"} * 100
# 内存使用排行
topk(5, container_memory_usage_bytes{name=~".+"} / 1024 / 1024)
容器网络 I/O
# 网络接收速率 (bytes/sec)
rate(container_network_receive_bytes_total{name=~".+"}[5m])
# 网络发送速率
rate(container_network_transmit_bytes_total{name=~".+"}[5m])
容器重启次数
# 容器重启次数
container_restart_count{name=~".+"}
14.7 告警配置
Prometheus 告警规则
# alert_rules.yml
groups:
- name: container_alerts
rules:
# 容器 CPU 使用率过高
- alert: ContainerHighCPU
expr: rate(container_cpu_usage_seconds_total{name=~".+"}[5m]) * 100 > 80
for: 5m
labels:
severity: warning
annotations:
summary: "容器 {{ $labels.name }} CPU 使用率过高"
description: "CPU 使用率已超过 80%,当前值: {{ $value }}%"
# 容器内存使用率过高
- alert: ContainerHighMemory
expr: container_memory_usage_bytes{name=~".+"} / container_spec_memory_limit_bytes{name=~".+"} * 100 > 85
for: 5m
labels:
severity: warning
annotations:
summary: "容器 {{ $labels.name }} 内存使用率过高"
# 容器频繁重启
- alert: ContainerRestartLoop
expr: increase(container_restart_count{name=~".+"}[1h]) > 3
labels:
severity: critical
annotations:
summary: "容器 {{ $labels.name }} 在过去 1 小时内重启超过 3 次"
# 容器停止运行
- alert: ContainerDown
expr: absent(container_last_seen{name=~".+"})
for: 1m
labels:
severity: critical
annotations:
summary: "容器 {{ $labels.name }} 已停止"
Alertmanager 配置
# alertmanager.yml
global:
smtp_smarthost: 'smtp.gmail.com:587'
smtp_from: '[email protected]'
route:
group_by: ['alertname', 'severity']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
receiver: 'web.hook'
receivers:
- name: 'web.hook'
webhook_configs:
- url: 'http://alertmanager-webhook:5001/'
email_configs:
- to: '[email protected]'
subject: 'Docker 告警: {{ .GroupLabels.alertname }}'
body: '{{ range .Alerts }}{{ .Annotations.summary }}{{ end }}'
14.8 生产环境监控栈
# 完整的监控栈
services:
# 容器指标采集
cadvisor:
image: gcr.io/cadvisor/cadvisor:v0.47.0
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
devices:
- /dev/kmsg:/dev/kmsg
privileged: true
# 宿主机指标
node-exporter:
image: prom/node-exporter:v1.7.0
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
- '--path.rootfs=/rootfs'
# 指标存储
prometheus:
image: prom/prometheus:v2.49.0
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus-data:/prometheus
# 告警管理
alertmanager:
image: prom/alertmanager:v0.27.0
volumes:
- ./alertmanager.yml:/etc/alertmanager/alertmanager.yml
ports:
- "9093:9093"
# 可视化
grafana:
image: grafana/grafana:10.2.0
ports:
- "3000:3000"
volumes:
- grafana-data:/var/lib/grafana
volumes:
prometheus-data:
grafana-data:
要点回顾
| 要点 | 核心内容 |
|---|---|
| 监控体系 | cAdvisor (采集) + Prometheus (存储) + Grafana (可视化) |
| 关键指标 | CPU、内存、网络 I/O、磁盘 I/O、容器重启 |
| 告警 | Prometheus Alertmanager 配置告警规则和通知 |
| 预配置 | 使用 Grafana 导入现成仪表板快速上手 |
| 生产建议 | 添加 Node Exporter 监控宿主机指标 |
注意事项
资源占用: cAdvisor + Prometheus + Grafana 约需 1-2GB 内存。资源有限的环境考虑使用轻量方案。
数据保留: Prometheus 默认保留 15 天数据。根据需求调整
--storage.tsdb.retention.time。
安全: 生产环境务必修改 Grafana 默认密码,并配置认证和 HTTPS。
下一步
→ 15 - 镜像仓库:学习 Harbor 私有仓库与镜像签名。