1. Docker监控的必要性与挑战
在容器化技术普及的今天,Docker已成为现代应用部署的事实标准。但就像驾驶飞机需要仪表盘一样,运行中的容器也需要全面的监控指标来确保稳定性。我曾亲历过一起生产事故:某个微服务容器因内存泄漏逐渐吞噬主机资源,由于缺乏有效的监控指标,直到整个集群崩溃才发现问题。这种"盲飞"状态在分布式系统中尤为危险。
Docker监控与传统主机监控有本质区别。容器具有瞬时性、高密度和共享内核的特性,常规的CPU、内存指标无法反映真实运行状态。比如,一个容器可能显示CPU使用率很低,但实际上它正在被cgroup限制 throttled(限流)。我曾用docker stats命令调试过这类问题,发现容器表面平静下的暗流涌动。
监控Docker环境需要关注三个维度:
- 容器层面:进程级资源使用、健康状态
- 主机层面:对容器资源的全局分配情况
- 编排层(如Swarm/K8s):调度和分布状态
2. 容器级核心指标详解
2.1 资源使用指标
CPU指标是最容易误读的部分。通过docker stats获取的CPU %实际显示的是相对于单个CPU核心的利用率。当容器被限制CPU份额时(如--cpus=0.5),200%的显示值意味着完全利用了分配的半个核心。更关键的指标是:
# 查看CPU限流情况 cat /sys/fs/cgroup/cpu,cpuacct/cpu.stat输出中的nr_throttled和throttled_time能反映容器是否频繁被限流——这是我们排查性能问题时最先检查的项。
内存指标的复杂性在于多层统计:
docker stats显示的MEM USAGE是RSS(常驻内存)MEM %是相对于内存限制的百分比- 真实内存压力要看
docker inspect中的oom_kill_disable和oom_score_adj
我曾遇到一个Java应用因未设置-XX:+UseContainerSupport导致JVM根据主机内存计算堆大小,最终触发OOM。关键命令:
docker inspect --format='{{.HostConfig.Memory}}' <container>2.2 网络与I/O指标
网络流量指标需要区分方向:
# 查看容器网络接口 docker exec -it <container> cat /proc/net/dev重点关注eth0的bytes和packets计数。在微服务场景下,突然的流量激增可能是循环调用或配置错误的信号。
存储I/O的监控要点:
# 查看块设备IO docker exec -it <container> iostat -dx 1注意await(平均等待时间)和%util(利用率)两个指标。某次MySQL容器性能下降的案例中,正是通过这两个指标发现底层EBS卷达到了IOPS上限。
3. 主机级监控关键点
3.1 全局资源视图
docker system df命令提供存储空间概览:
TYPE TOTAL ACTIVE SIZE RECLAIMABLE Images 5 3 2.3GB 1.1GB (47%) Containers 3 1 450MB 450MB (100%) Local Volumes 2 1 120MB 60MB (50%) Build Cache 12 0 320MB 320MB这个输出能快速发现僵尸容器或悬空镜像——它们曾占用我们生产环境30%的存储空间。
3.2 内核级指标
/proc文件系统中的关键数据:
# 查看容器数量 cat /proc/sys/kernel/pid_max # 查看overlay2挂载点 df -h | grep overlay特别是overlay2存储驱动的inodes使用情况,曾导致我们即使磁盘空间充足也无法创建新容器。
4. 监控工具实战配置
4.1 cAdvisor部署示例
Google的cAdvisor是容器监控的瑞士军刀。最小化部署:
version: '3' services: cadvisor: image: gcr.io/cadvisor/cadvisor:v0.47.0 ports: - "8080:8080" volumes: - /:/rootfs:ro - /var/run:/var/run:rw - /sys:/sys:ro - /var/lib/docker/:/var/lib/docker:ro devices: - /dev/kmsg:/dev/kmsg部署后访问http://localhost:8080/docker/可看到所有容器的实时指标。但要注意其内存消耗——在大型集群中可能达到GB级别。
4.2 Prometheus指标采集
在prometheus.yml中添加cAdvisor抓取配置:
scrape_configs: - job_name: 'cadvisor' static_configs: - targets: ['cadvisor:8080'] metric_relabel_configs: - source_labels: [container_label_com_docker_swarm_service_name] target_label: service通过metric_relabel_configs可以提取Docker标签转为Prometheus标签,这对微服务监控至关重要。
5. 高级监控场景
5.1 健康检查集成
Docker原生支持健康检查:
HEALTHCHECK --interval=30s --timeout=3s \ CMD curl -f http://localhost:8080/health || exit 1结合docker inspect --format='{{.State.Health.Status}}'可以构建自动化恢复流程。我们在生产环境用这个机制实现了web服务的自动重启。
5.2 日志监控策略
虽然不属于指标监控,但日志模式识别也很关键。推荐配置:
{ "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" } }配合Fluentd的日志解析:
<filter docker.**> @type parser key_name log reserve_data true <parse> @type json </parse> </filter>6. 典型问题排查流程
当收到"容器响应变慢"的告警时,我的标准排查路径:
- 检查CPU限流:
cat /sys/fs/cgroup/cpu,cpuacct/cpu.stat - 确认内存压力:
docker stats --no-stream - 查看块设备IO:
iostat -dx 1 - 分析网络状态:
tc -s qdisc show dev eth0 - 检查存储驱动:
docker info | grep Storage
某次线上事故中,正是通过这个流程发现是某PHP容器频繁写日志导致overlay2存储驱动性能下降,最终通过挂载volume解决。
7. 指标告警阈值建议
根据实战经验总结的告警阈值:
| 指标类型 | 警告阈值 | 严重阈值 | 检测方法 |
|---|---|---|---|
| CPU限流率 | >5% | >20% | nr_throttled/nr_periods |
| 内存使用率 | >85% | >95% | docker stats |
| 网络丢包率 | >0.1% | >1% | ifconfig |
| 存储延迟 | >50ms | >200ms | iostat await |
这些阈值需要根据具体应用类型调整。例如,对于批处理作业,CPU限流率可以适当放宽。
8. 监控数据可视化实践
Grafana面板配置建议:
- 容器状态总览:使用Stat面板显示运行/停止容器数量
- 资源热力图:用Heatmap展示各容器CPU使用分布
- 网络拓扑图:通过Flow图表展示容器间流量
- 存储增长预测:基于Prometheus的predict_linear函数
我们团队最常用的面板是"容器生命周期图谱",通过记录docker events数据展示容器的创建、销毁模式,帮助发现异常调度行为。