系统监控工具指南 / 第11章:Docker容器监控
第11章:Docker容器监控
11.1 概述
为什么需要容器监控
- 资源隔离 - 容器资源独立,需要单独监控
- 动态性 - 容器频繁创建销毁,传统工具难以覆盖
- 密度 - 单机运行多个容器,资源竞争
- 微服务 - 服务分散在多个容器中
容器监控的挑战
| 挑战 | 说明 |
|---|---|
| 动态性 | 容器生命周期短,IP变化 |
| 密度 | 单机数百容器,监控开销大 |
| 隔离性 | 容器内外视角不同 |
| 编排 | Kubernetes等编排系统的复杂性 |
容器监控工具
| 工具 | 类型 | 特点 |
|---|---|---|
| docker stats | Docker内置 | 基础、实时 |
| cAdvisor | Google开源 | 容器专用、Web界面 |
| Prometheus + Grafana | 监控栈 | 企业级、可视化 |
| Datadog | SaaS服务 | 全托管、功能丰富 |
| Sysdig | 安全+监控 | 深度洞察 |
11.2 Docker内置监控
11.2.1 docker stats
基本用法:
# 查看所有容器资源使用
docker stats
# 查看指定容器
docker stats container_name
# 查看多个容器
docker stats container1 container2
# 单次输出(不持续刷新)
docker stats --no-stream
# 自定义格式
docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"
输出解读:
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
a1b2c3d4e5f6 nginx 0.50% 65.43MiB / 16GiB 0.40% 1.23MB / 456KB 12.3MB / 0B 7
f6e5d4c3b2a1 mysql 3.20% 234.5MiB / 16GiB 1.43% 45.6MB / 12.3MB 56.7MB / 8.9MB 45
字段说明:
| 字段 | 含义 |
|---|---|
| CPU % | CPU使用率 |
| MEM USAGE / LIMIT | 内存使用 / 内存限制 |
| MEM % | 内存使用率 |
| NET I/O | 网络输入/输出 |
| BLOCK I/O | 块设备输入/输出 |
| PIDS | 进程数 |
11.2.2 docker stats格式化
自定义输出格式:
# 简化输出
docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"
# JSON格式
docker stats --format '{"name":"{{.Name}}","cpu":"{{.CPUPerc}}","mem":"{{.MemUsage}}"}'
# 只显示特定容器
docker stats --format "{{.Name}}: {{.CPUPerc}}" container1 container2
可用变量:
| 变量 | 说明 |
|---|---|
| .Container | 容器ID |
| .Name | 容器名称 |
| .ID | 容器ID |
| .CPUPerc | CPU使用率 |
| .MemUsage | 内存使用 |
| .MemPerc | 内存使用率 |
| .NetIO | 网络IO |
| .BlockIO | 块IO |
| .PIDs | 进程数 |
11.2.3 docker top
# 查看容器进程
docker top container_name
# 自定义ps选项
docker top container_name -o pid,user,%cpu,%mem,command
# 查看所有线程
docker top container_name -eLf
11.2.4 docker inspect
# 查看容器详细信息
docker inspect container_name
# 获取特定信息
docker inspect --format='{{.State.Pid}}' container_name
docker inspect --format='{{.HostConfig.Memory}}' container_name
docker inspect --format='{{.HostConfig.CpuShares}}' container_name
# 查看资源限制
docker inspect --format='{{json .HostConfig}}' container_name | jq
11.2.5 docker system df
# 查看Docker磁盘使用
docker system df
# 输出示例
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 10 5 2.5GB 1.2GB (48%)
Containers 8 3 500MB 300MB (60%)
Local Volumes 15 10 1GB 500MB (50%)
Build Cache 0 0 0B 0B
# 详细信息
docker system df -v
11.2.6 docker events
# 实时监控Docker事件
docker events
# 过滤事件
docker events --filter type=container
docker events --filter event=start
docker events --filter container=nginx
# JSON格式
docker events --format '{{json .}}'
# 监控指定时间段
docker events --since 2026-05-10T14:00:00
docker events --until 2026-05-10T16:00:00
11.3 cAdvisor详解
11.3.1 什么是cAdvisor
cAdvisor(Container Advisor)是Google开源的容器监控工具,提供:
- 容器资源使用统计
- 性能数据分析
- Web界面展示
- API接口
11.3.2 安装部署
Docker方式部署:
# 基本部署
docker run \
--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 \
--detach=true \
--privileged \
--device=/dev/kmsg \
gcr.io/cadvisor/cadvisor:latest
# 指定版本
docker run \
--name=cadvisor \
--volume=/:/rootfs:ro \
--volume=/var/run:/var/run:ro \
--volume=/sys:/sys:ro \
--volume=/var/lib/docker/:/var/lib/docker:ro \
--publish=8080:8080 \
--detach=true \
gcr.io/cadvisor/cadvisor:v0.47.0
docker-compose方式:
# docker-compose.yml
version: '3.8'
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
- /dev/disk/:/dev/disk:ro
privileged: true
devices:
- /dev/kmsg:/dev/kmsg
# 启动
docker-compose up -d
# 查看状态
docker-compose ps
11.3.3 Web界面
访问cAdvisor:
# 本地访问
http://localhost:8080
# 远程访问
http://server_ip:8080
界面功能:
| 页面 | 功能 |
|---|---|
| / | 主页,系统概览 |
| /docker/ | Docker容器列表 |
| /containers/ | 所有容器 |
| /system/ | 系统信息 |
容器详情页面:
- CPU使用率图表
- 内存使用图表
- 网络IO图表
- 磁盘IO图表
- 进程列表
11.3.4 API接口
获取容器信息:
# 获取所有容器
curl http://localhost:8080/api/v1.0/containers
# 获取指定容器
curl http://localhost:8080/api/v1.0/containers/<container_name>
# 获取Docker容器
curl http://localhost:8080/api/v1.0/docker/<container_id>
API响应示例:
{
"name": "/docker/nginx",
"aliases": ["nginx", "a1b2c3d4e5f6"],
"namespace": "docker",
"spec": {
"container_name": "nginx",
"image": "nginx:latest"
},
"stats": [
{
"timestamp": "2026-05-10T14:32:15Z",
"cpu": {
"usage": {
"total": 123456789,
"per_cpu_usage": [12345678, 23456789, ...]
}
},
"memory": {
"usage": 67108864,
"cache": 12345678,
"rss": 54321098
},
"network": {
"interfaces": [
{
"name": "eth0",
"rx_bytes": 1234567,
"tx_bytes": 2345678
}
]
}
}
]
}
API查询参数:
# 指定时间范围
curl "http://localhost:8080/api/v1.0/containers/nginx?start=2026-05-10T14:00:00Z&end=2026-05-10T15:00:00Z"
# 指定采样数
curl "http://localhost:8080/api/v1.0/containers/nginx?num_stats=60"
11.3.5 监控脚本
Python示例:
import requests
import json
class CadvisorClient:
def __init__(self, host='localhost', port=8080):
self.base_url = f"http://{host}:{port}/api/v1.0"
def get_containers(self):
"""获取所有容器"""
resp = requests.get(f"{self.base_url}/containers")
return resp.json()
def get_container_stats(self, container_name):
"""获取容器统计"""
resp = requests.get(f"{self.base_url}/containers/{container_name}")
data = resp.json()
if data.get('stats'):
latest = data['stats'][-1]
return {
'cpu_usage': latest['cpu']['usage']['total'],
'memory_usage': latest['memory']['usage'],
'network_rx': latest['network']['interfaces'][0]['rx_bytes'],
'network_tx': latest['network']['interfaces'][0]['tx_bytes']
}
return None
# 使用示例
client = CadvisorClient()
containers = client.get_containers()
for name in containers:
stats = client.get_container_stats(name)
if stats:
print(f"{name}: CPU={stats['cpu_usage']}, MEM={stats['memory_usage']}")
Shell脚本示例:
#!/bin/bash
# cadvisor_monitor.sh
CADVISOR_URL="http://localhost:8080"
# 获取容器列表
get_containers() {
curl -s $CADVISOR_URL/api/v1.0/containers | jq -r 'keys[]'
}
# 获取容器CPU使用率
get_cpu_usage() {
local container=$1
curl -s $CADVISOR_URL/api/v1.0/containers/$container | \
jq '.stats[-1].cpu.usage.total'
}
# 获取容器内存使用
get_memory_usage() {
local container=$1
curl -s $CADVISOR_URL/api/v1.0/containers/$container | \
jq '.stats[-1].memory.usage'
}
# 监控所有容器
for container in $(get_containers); do
cpu=$(get_cpu_usage $container)
mem=$(get_memory_usage $container)
echo "$container: CPU=$cpu, MEM=$mem"
done
11.4 Prometheus + Grafana
11.4.1 架构概述
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Docker │───>│ cAdvisor │───>│ Prometheus │
│ Containers │ │ (Metrics) │ │ (Storage) │
└─────────────┘ └─────────────┘ └─────────────┘
│
▼
┌─────────────┐
│ Grafana │
│ (Dashboard) │
└─────────────┘
11.4.2 Docker Compose部署
# docker-compose-monitoring.yml
version: '3.8'
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
privileged: true
devices:
- /dev/kmsg:/dev/kmsg
prometheus:
image: prom/prometheus:latest
container_name: prometheus
restart: unless-stopped
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--storage.tsdb.retention.time=30d'
grafana:
image: grafana/grafana:latest
container_name: grafana
restart: unless-stopped
ports:
- "3000:3000"
volumes:
- grafana_data:/var/lib/grafana
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
volumes:
prometheus_data:
grafana_data:
Prometheus配置:
# prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'cadvisor'
static_configs:
- targets: ['cadvisor:8080']
启动服务:
# 启动所有服务
docker-compose -f docker-compose-monitoring.yml up -d
# 查看状态
docker-compose -f docker-compose-monitoring.yml ps
# 查看日志
docker-compose -f docker-compose-monitoring.yml logs -f
11.4.3 Grafana配置
添加数据源:
- 访问 http://localhost:3000
- 登录(admin/admin)
- Configuration → Data Sources → Add data source
- 选择Prometheus
- URL: http://prometheus:9090
- Save & Test
导入Dashboard:
- Dashboards → Import
- 输入Dashboard ID(如 11600 - Docker and system monitoring)
- Load
- 选择Prometheus数据源
- Import
推荐Dashboard:
| Dashboard ID | 名称 | 说明 |
|---|---|---|
| 11600 | Docker and system monitoring | Docker和系统监控 |
| 893 | Docker containers | Docker容器监控 |
| 10619 | Docker container & host metrics | 容器和主机指标 |
| 14282 | cAdvisor Exporter | cAdvisor监控 |
11.4.4 常用PromQL查询
CPU使用率:
# 容器CPU使用率
rate(container_cpu_usage_seconds_total{image!=""}[5m]) * 100
# 按容器分组
sum(rate(container_cpu_usage_seconds_total{image!=""}[5m])) by (name) * 100
内存使用:
# 容器内存使用
container_memory_usage_bytes{image!=""}
# 内存使用率
container_memory_usage_bytes{image!=""} / container_spec_memory_limit_bytes{image!=""} * 100
网络流量:
# 接收速率
rate(container_network_receive_bytes_total{image!=""}[5m])
# 发送速率
rate(container_network_transmit_bytes_total{image!=""}[5m])
磁盘IO:
# 读取速率
rate(container_fs_reads_bytes_total{image!=""}[5m])
# 写入速率
rate(container_fs_writes_bytes_total{image!=""}[5m])
11.5 容器资源管理
11.5.1 资源限制
CPU限制:
# 限制CPU使用率为50%
docker run --cpus=0.5 nginx
# 限制CPU份额(相对权重)
docker run --cpu-shares=512 nginx
# 绑定到特定CPU核心
docker run --cpuset-cpus="0,1" nginx
内存限制:
# 限制内存为512MB
docker run --memory=512m nginx
# 限制内存和Swap
docker run --memory=512m --memory-swap=1g nginx
# 内存软限制
docker run --memory=512m --memory-reservation=256m nginx
IO限制:
# 限制块IO
docker run --device-read-bps=/dev/sda:1mb nginx
docker run --device-write-bps=/dev/sda:1mb nginx
# 限制IOPS
docker run --device-read-iops=/dev/sda:1000 nginx
docker run --device-write-iops=/dev/sda:1000 nginx
11.5.2 资源监控
查看资源限制:
# 查看容器资源限制
docker inspect --format='{{.HostConfig.Memory}}' container_name
docker inspect --format='{{.HostConfig.CpuShares}}' container_name
# 查看资源使用
docker stats container_name
动态调整资源:
# 动态调整CPU份额
docker update --cpu-shares=1024 container_name
# 动态调整内存限制
docker update --memory=1g container_name
# 批量更新
docker update --cpu-shares=512 container1 container2
11.5.3 资源告警
Prometheus告警规则:
# alerts.yml
groups:
- name: container_alerts
rules:
- alert: ContainerHighCPU
expr: rate(container_cpu_usage_seconds_total{image!=""}[5m]) * 100 > 80
for: 5m
labels:
severity: warning
annotations:
summary: "容器CPU使用率过高"
description: "容器 {{ $labels.name }} CPU使用率超过80%"
- alert: ContainerHighMemory
expr: container_memory_usage_bytes{image!=""} / container_spec_memory_limit_bytes{image!=""} * 100 > 80
for: 5m
labels:
severity: warning
annotations:
summary: "容器内存使用率过高"
description: "容器 {{ $labels.name }} 内存使用率超过80%"
- alert: ContainerRestarting
expr: increase(container_restart_count[1h]) > 3
labels:
severity: critical
annotations:
summary: "容器频繁重启"
description: "容器 {{ $labels.name }} 在过去1小时内重启超过3次"
11.6 Kubernetes监控
11.6.1 Metrics Server
安装Metrics Server:
# 安装
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
# 验证
kubectl get pods -n kube-system | grep metrics-server
使用kubectl top:
# 查看节点资源使用
kubectl top nodes
# 查看Pod资源使用
kubectl top pods
# 查看指定命名空间
kubectl top pods -n kube-system
# 查看Pod中容器资源使用
kubectl top pods --containers
11.6.2 Prometheus Operator
安装:
# 使用Helm安装
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--create-namespace
组件:
| 组件 | 功能 |
|---|---|
| Prometheus Operator | 管理Prometheus实例 |
| Prometheus | 时序数据库 |
| Alertmanager | 告警管理 |
| Grafana | 可视化 |
| kube-state-metrics | Kubernetes指标 |
11.6.3 常用监控指标
Pod指标:
# Pod CPU使用率
sum(rate(container_cpu_usage_seconds_total{namespace="default"}[5m])) by (pod) * 100
# Pod内存使用
sum(container_memory_usage_bytes{namespace="default"}) by (pod)
# Pod重启次数
sum(kube_pod_container_status_restarts_total{namespace="default"}) by (pod)
节点指标:
# 节点CPU使用率
(1 - avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance)) * 100
# 节点内存使用率
(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100
# 节点磁盘使用率
(1 - node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100
11.7 日志监控
11.7.1 Docker日志
查看容器日志:
# 查看日志
docker logs container_name
# 实时跟踪
docker logs -f container_name
# 最近100行
docker logs --tail 100 container_name
# 指定时间范围
docker logs --since 2026-05-10T14:00:00 container_name
docker logs --until 2026-05-10T15:00:00 container_name
# 带时间戳
docker logs -t container_name
日志驱动配置:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
11.7.2 ELK Stack
Docker Compose部署:
# docker-compose-elk.yml
version: '3.8'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.7.0
container_name: elasticsearch
environment:
- discovery.type=single-node
- xpack.security.enabled=false
ports:
- "9200:9200"
volumes:
- elasticsearch_data:/usr/share/elasticsearch/data
logstash:
image: docker.elastic.co/logstash/logstash:8.7.0
container_name: logstash
volumes:
- ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf
depends_on:
- elasticsearch
kibana:
image: docker.elastic.co/kibana/kibana:8.7.0
container_name: kibana
ports:
- "5601:5601"
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
depends_on:
- elasticsearch
volumes:
elasticsearch_data:
11.8 实战场景
场景1:容器资源监控
需求:监控所有容器的资源使用
# 实时监控
docker stats
# 导出到文件
docker stats --no-stream > /tmp/docker_stats_$(date +%Y%m%d_%H%M%S).txt
# 使用cAdvisor
docker run -d --name cadvisor \
-p 8080:8080 \
-v /:/rootfs:ro \
-v /var/run:/var/run:ro \
-v /sys:/sys:ro \
-v /var/lib/docker/:/var/lib/docker:ro \
gcr.io/cadvisor/cadvisor:latest
场景2:容器性能问题排查
问题:容器响应缓慢
# 1. 检查容器资源使用
docker stats container_name
# 2. 检查容器进程
docker top container_name
# 3. 检查容器日志
docker logs --tail 100 container_name
# 4. 进入容器排查
docker exec -it container_name bash
# 5. 检查资源限制
docker inspect --format='{{json .HostConfig}}' container_name | jq
场景3:容器密度优化
需求:优化单机容器密度
# 1. 查看当前资源使用
docker stats --no-stream
# 2. 分析资源分配
docker inspect --format='{{.Name}}: CPU={{.HostConfig.CpuShares}}, MEM={{.HostConfig.Memory}}' $(docker ps -q)
# 3. 调整资源限制
docker update --cpu-shares=256 --memory=256m container_name
# 4. 监控调整效果
docker stats
场景4:容器网络监控
需求:监控容器网络流量
# 1. 使用docker stats
docker stats --format "table {{.Name}}\t{{.NetIO}}"
# 2. 使用cAdvisor
curl http://localhost:8080/api/v1.0/containers/nginx | jq '.stats[-1].network'
# 3. 使用iftop(需要进入容器)
docker exec -it container_name iftop
场景5:容器存储监控
需求:监控容器存储使用
# 1. 查看容器文件系统
docker exec -it container_name df -h
# 2. 查看容器层大小
docker system df
# 3. 查看卷使用
docker volume ls
docker system df -v
# 4. 清理未使用资源
docker system prune
11.9 最佳实践
11.9.1 监控策略
| 层次 | 监控内容 | 工具 |
|---|---|---|
| 容器层 | CPU、内存、网络、IO | docker stats, cAdvisor |
| 应用层 | 响应时间、错误率 | Prometheus + 应用指标 |
| 编排层 | Pod状态、节点健康 | Kubernetes Metrics |
| 日志层 | 应用日志、错误日志 | ELK Stack |
11.9.2 告警设置
关键告警:
| 指标 | 阈值 | 级别 |
|---|---|---|
| CPU使用率 | >80% | Warning |
| 内存使用率 | >85% | Warning |
| 容器重启 | >3次/小时 | Critical |
| 磁盘使用率 | >90% | Critical |
| 网络错误 | >0 | Warning |
11.9.3 容量规划
监控数据收集:
# 每天收集资源使用
docker stats --no-stream > /tmp/stats_$(date +%Y%m%d).txt
# 分析趋势
# CPU平均使用率
# 内存峰值使用率
# 网络流量趋势
11.10 故障排查
问题1:cAdvisor无法启动
# 检查日志
docker logs cadvisor
# 检查挂载
ls -la /var/run/docker.sock
# 权限问题
docker run --privileged ...
问题2:Prometheus无法抓取数据
# 检查cAdvisor是否运行
docker ps | grep cadvisor
# 检查Prometheus配置
cat prometheus.yml
# 手动测试
curl http://cadvisor:8080/metrics
问题3:容器资源监控不准
# 检查cgroup版本
cat /proc/self/cgroup
# 检查Docker版本
docker version
# 更新cAdvisor
docker pull gcr.io/cadvisor/cadvisor:latest
11.11 扩展阅读
11.12 快速参考
Docker监控命令
# 基本监控
docker stats # 所有容器
docker stats container_name # 指定容器
docker stats --no-stream # 单次输出
# 进程监控
docker top container_name # 容器进程
# 事件监控
docker events # 实时事件
# 资源使用
docker system df # 磁盘使用
cAdvisor命令
# 启动cAdvisor
docker run -d --name cadvisor \
-p 8080:8080 \
-v /:/rootfs:ro \
-v /var/run:/var/run:ro \
-v /sys:/sys:ro \
-v /var/lib/docker/:/var/lib/docker:ro \
gcr.io/cadvisor/cadvisor:latest
# API调用
curl http://localhost:8080/api/v1.0/containers
curl http://localhost:8080/api/v1.0/containers/nginx
资源限制命令
# CPU限制
docker run --cpus=0.5 nginx
docker run --cpu-shares=512 nginx
# 内存限制
docker run --memory=512m nginx
docker run --memory=512m --memory-swap=1g nginx
# 动态调整
docker update --cpu-shares=1024 container_name
docker update --memory=1g container_name
11.13 本章小结
本章详细介绍了Docker容器监控:
Docker内置监控:
- docker stats:实时资源监控
- docker top:进程监控
- docker inspect:详细信息
- docker events:事件监控
cAdvisor:
- 容器专用监控工具
- Web界面和API
- 与Prometheus集成
Prometheus + Grafana:
- 企业级监控方案
- 丰富的Dashboard
- 告警功能
Kubernetes监控:
- Metrics Server
- Prometheus Operator
- kubectl top
最佳实践:
- 分层监控策略
- 合理设置告警
- 容量规划
容器监控需要结合多种工具,从不同层次全面掌握容器运行状态。
上一章: 第10章:dstat与nmon 下一章: 第12章:监控最佳实践