Docker 监控与日志

Docker 监控与日志

全面掌握Docker容器监控和日志管理,构建可观测的容器化应用环境。

性能监控 日志收集 告警系统 可观测性

Docker 监控与日志概述

Docker监控和日志管理是维护容器化应用健康状态的关键环节。通过有效的监控和日志策略,可以:

  • 实时了解应用性能状态
  • 快速定位和解决问题
  • 优化资源利用率
  • 满足合规性要求
  • 提升系统可靠性

监控和日志管理构成了可观测性的三大支柱:指标(Metrics)、日志(Logs)和追踪(Traces)。

为什么需要监控和日志?
  • 及时发现性能瓶颈
  • 快速故障诊断和恢复
  • 容量规划和资源优化
  • 安全审计和合规要求
  • 用户体验优化
监控 vs 日志
  • 监控 - 实时性能指标和系统状态
  • 日志 - 历史事件记录和调试信息
  • 追踪 - 请求在系统中的流转路径

监控工具分类

指标监控

收集性能指标,如CPU、内存、网络、磁盘使用率等。

Prometheus cAdvisor

日志管理

收集、存储、搜索和分析容器日志。

ELK Stack Fluentd

分布式追踪

跟踪请求在微服务架构中的流转路径。

Jaeger Zipkin

Docker 原生监控命令

Docker 内置监控命令

Docker提供了一系列内置命令用于基本的监控和诊断。

容器状态监控

# 查看容器状态
docker ps
docker ps -a  # 包括停止的容器

# 查看容器资源使用情况
docker stats

# 实时监控特定容器
docker stats container_name

# 查看所有容器资源使用(包括停止的)
docker stats --all

# 格式化输出
docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"
                        
系统信息命令

# 查看Docker系统信息
docker system info

# 查看磁盘使用情况
docker system df

# 详细磁盘使用分析
docker system df -v

# 清理未使用的资源
docker system prune
docker system prune -a  # 清理所有未使用资源
                        
容器内进程监控

# 查看容器内运行的进程
docker top container_name

# 查看容器详细信息
docker inspect container_name

# 查看容器日志
docker logs container_name
docker logs -f container_name  # 实时跟踪
docker logs --tail 100 container_name  # 最后100行
docker logs --since 1h container_name  # 最近1小时的日志
                        

关键监控指标

必须监控的关键指标

CPU 使用率

监控容器CPU使用情况,避免资源竞争。


# 查看容器CPU使用率
docker stats --format "{{.CPUPerc}}" container_name

# 在容器内查看
docker exec container_name top
                                    
内存使用

监控内存使用和限制,防止内存泄漏。


# 查看容器内存使用
docker stats --format "{{.MemUsage}}" container_name

# 查看详细内存信息
docker stats --format "table {{.Name}}\t{{.MemPerc}}\t{{.MemUsage}}"
                                    
网络I/O

监控网络流量,识别网络瓶颈。


# 查看网络流量
docker stats --format "{{.NetIO}}" container_name

# 查看网络详细信息
docker network ls
docker network inspect network_name
                                    
磁盘I/O

监控磁盘读写操作,识别存储性能问题。


# 查看块I/O
docker stats --format "{{.BlockIO}}" container_name

# 查看数据卷使用情况
docker system df -v
                                    

cAdvisor - 容器监控工具

Prometheus + Grafana 监控栈

Prometheus + Grafana - 企业级监控

使用Docker Compose部署

version: '3.8'

services:
  prometheus:
    image: prom/prometheus:latest
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus_data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.console.libraries=/etc/prometheus/console_libraries'
      - '--web.console.templates=/etc/prometheus/consoles'
      - '--storage.tsdb.retention.time=200h'
      - '--web.enable-lifecycle'
    networks:
      - monitoring

  grafana:
    image: grafana/grafana:latest
    ports:
      - "3000:3000"
    volumes:
      - grafana_data:/var/lib/grafana
      - ./grafana/dashboards:/var/lib/grafana/dashboards
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
    networks:
      - monitoring
    depends_on:
      - prometheus

  node-exporter:
    image: prom/node-exporter:latest
    ports:
      - "9100:9100"
    networks:
      - monitoring

volumes:
  prometheus_data:
  grafana_data:

networks:
  monitoring:
    driver: bridge
                        
Prometheus 配置

# prometheus.yml
global:
  scrape_interval: 15s
  evaluation_interval: 15s

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  - job_name: 'node-exporter'
    static_configs:
      - targets: ['node-exporter:9100']

  - job_name: 'cadvisor'
    static_configs:
      - targets: ['cadvisor:8080']
    metrics_path: /metrics

  - job_name: 'docker'
    static_configs:
      - targets: ['docker-engine:9323']
                        

Docker 日志管理

容器日志驱动和配置

Docker 日志驱动

# 查看当前日志驱动
docker info --format '{{.LoggingDriver}}'

# 运行容器时指定日志驱动
docker run --log-driver=json-file --log-opt max-size=10m nginx

# 配置全局日志驱动
# 在 /etc/docker/daemon.json 中配置
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}
                        
常用日志驱动
  • json-file - 默认驱动,日志以JSON格式存储在文件中
  • journald - 日志发送到systemd journal
  • syslog - 日志发送到syslog服务器
  • fluentd - 日志发送到Fluentd收集器
  • awslogs - 日志发送到AWS CloudWatch Logs
  • gelf - 日志发送到Graylog或其他GELF兼容服务
日志查询和分析

# 查看容器日志
docker logs container_name

# 实时跟踪日志
docker logs -f container_name

# 查看特定时间段的日志
docker logs --since 2023-01-01T00:00:00 container_name
docker logs --since 1h container_name

# 查看最后N行日志
docker logs --tail 100 container_name

# 结合grep过滤日志
docker logs container_name | grep "ERROR"

# 格式化日志输出
docker logs --timestamps container_name
                        

ELK Stack 日志管理

ELK Stack - 企业级日志解决方案

ELK Stack (Elasticsearch, Logstash, Kibana) 是流行的日志收集、存储和分析解决方案。

使用Docker Compose部署ELK

version: '3.8'

services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.5.0
    environment:
      - discovery.type=single-node
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
      - xpack.security.enabled=false
    volumes:
      - elasticsearch_data:/usr/share/elasticsearch/data
    ports:
      - "9200:9200"
    networks:
      - elk

  logstash:
    image: docker.elastic.co/logstash/logstash:8.5.0
    volumes:
      - ./logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml
      - ./logstash/pipeline:/usr/share/logstash/pipeline
    ports:
      - "5000:5000"
    environment:
      - LS_JAVA_OPTS=-Xmx256m -Xms256m
    networks:
      - elk
    depends_on:
      - elasticsearch

  kibana:
    image: docker.elastic.co/kibana/kibana:8.5.0
    environment:
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
    ports:
      - "5601:5601"
    networks:
      - elk
    depends_on:
      - elasticsearch

  filebeat:
    image: docker.elastic.co/beats/filebeat:8.5.0
    volumes:
      - /var/lib/docker/containers:/var/lib/docker/containers:ro
      - /var/run/docker.sock:/var/run/docker.sock
      - ./filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml
    networks:
      - elk
    depends_on:
      - logstash

volumes:
  elasticsearch_data:

networks:
  elk:
    driver: bridge
                        
Filebeat 配置

# filebeat.yml
filebeat.inputs:
- type: container
  paths:
    - '/var/lib/docker/containers/*/*.log'
  processors:
    - add_docker_metadata:
        host: "unix:///var/run/docker.sock"

output.logstash:
  hosts: ["logstash:5000"]
                        

监控架构示意图

完整的监控与日志架构

Docker
容器
cAdvisor
指标收集
Prometheus
时序数据库
Grafana
可视化
Alertmanager
告警管理
容器
日志
Fluentd
日志收集
Elasticsearch
日志存储
Kibana
日志分析

告警配置

监控告警配置

Prometheus Alertmanager 配置

# alertmanager.yml
global:
  smtp_smarthost: 'smtp.example.com:587'
  smtp_from: 'alertmanager@example.com'
  smtp_auth_username: 'username'
  smtp_auth_password: 'password'

route:
  group_by: ['alertname']
  group_wait: 10s
  group_interval: 10s
  repeat_interval: 1h
  receiver: 'email-notifications'

receivers:
- name: 'email-notifications'
  email_configs:
  - to: 'admin@example.com'
    send_resolved: true
                        
Prometheus 告警规则

# alerts.yml
groups:
- name: container_alerts
  rules:
  - alert: HighCPUUsage
    expr: rate(container_cpu_usage_seconds_total[5m]) * 100 > 80
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "High CPU usage detected"
      description: "Container {{ $labels.container_name }} has high CPU usage (current value: {{ $value }}%)"

  - alert: HighMemoryUsage
    expr: container_memory_usage_bytes / container_spec_memory_limit_bytes * 100 > 85
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "High memory usage detected"
      description: "Container {{ $labels.container_name }} has high memory usage (current value: {{ $value }}%)"

  - alert: ContainerRestarted
    expr: time() - container_start_time_seconds > 60
    for: 0m
    labels:
      severity: info
    annotations:
      summary: "Container restarted"
      description: "Container {{ $labels.container_name }} has restarted"
                        

仪表板配置

Grafana 仪表板配置

关键监控面板
  • 容器资源使用率 - CPU、内存、磁盘、网络
  • 应用性能指标 - 请求数、响应时间、错误率
  • 业务指标 - 用户活跃度、交易量等
  • 基础设施状态 - 节点健康状态、服务发现
  • 日志分析 - 错误日志统计、关键事件
  • 告警概览 - 当前告警状态、历史告警
  • 容量规划 - 资源使用趋势、预测
  • 安全监控 - 异常访问、安全事件
Grafana 查询示例

# 容器CPU使用率
rate(container_cpu_usage_seconds_total{container_name="myapp"}[5m]) * 100

# 容器内存使用率
container_memory_usage_bytes{container_name="myapp"} /
container_spec_memory_limit_bytes{container_name="myapp"} * 100

# 网络接收流量
rate(container_network_receive_bytes_total{container_name="myapp"}[5m])

# 网络发送流量
rate(container_network_transmit_bytes_total{container_name="myapp"}[5m])
                        

监控工具对比

工具 类型 部署复杂度 功能特性 适用场景
cAdvisor 指标收集 简单 容器资源监控、Web界面 开发测试、小型部署
Prometheus 时序数据库 中等 多维数据模型、强大查询语言 云原生、微服务架构
Grafana 数据可视化 简单 丰富图表、告警、多数据源 所有规模的监控展示
ELK Stack 日志管理 复杂 日志收集、存储、分析、可视化 企业级日志管理
Fluentd 日志收集 中等 统一日志层、插件丰富 大规模日志收集
Jaeger 分布式追踪 中等 请求链路追踪、性能分析 微服务性能诊断

最佳实践

定义清晰的监控目标

明确监控的目的和指标,避免过度监控或监控不足。关注业务关键指标和用户体验指标。

实施分层监控策略

从基础设施层、应用层到业务层实施全面的监控,确保每个层级都有相应的监控覆盖。

配置合理的告警阈值

避免告警风暴,设置合理的阈值和告警间隔。区分警告级别和紧急级别。

标准化日志格式

使用结构化的日志格式(如JSON),包含统一的字段(时间戳、级别、服务名、请求ID等)。


{
  "timestamp": "2023-01-01T12:00:00Z",
  "level": "INFO",
  "service": "user-service",
  "request_id": "abc-123",
  "message": "User login successful",
  "user_id": "user-123",
  "ip": "192.168.1.1"
}
                        
定期审查和优化

定期审查监控配置和告警规则,根据业务变化和监控效果进行优化调整。

常见问题与解决方案

问题描述: 监控数据和日志文件快速增长,占用大量磁盘空间。

解决方案:

  • 配置数据保留策略
  • 使用数据压缩
  • 实施日志轮转
  • 只收集必要的指标和日志
  • 使用分层存储策略

# Prometheus 数据保留配置
--storage.tsdb.retention.time=15d
--storage.tsdb.retention.size=100GB

# Docker 日志轮转配置
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}
                                    

问题描述: 监控数据收集和处理消耗过多系统资源,影响应用性能。

解决方案:

  • 调整数据采集频率
  • 使用抽样策略减少数据量
  • 分离监控网络和应用网络
  • 优化查询和聚合操作
  • 使用专用的监控节点

# 降低数据采集频率
scrape_interval: 30s
evaluation_interval: 30s

# 配置资源限制
resources:
  limits:
    memory: 512Mi
    cpu: 500m
  requests:
    memory: 256Mi
    cpu: 250m
                                    

问题描述: 日志数量庞大,难以快速定位问题和进行分析。

解决方案:

  • 实施结构化日志
  • 建立统一的日志索引策略
  • 配置日志过滤和聚合
  • 使用日志分析工具
  • 建立日志分类和标签体系

// 结构化日志示例
{
  "timestamp": "2023-01-01T12:00:00Z",
  "level": "ERROR",
  "logger": "com.example.UserService",
  "message": "Failed to create user",
  "error": "Duplicate email address",
  "user_email": "user@example.com",
  "trace_id": "trace-123",
  "span_id": "span-456"
}
                                    
监控与日志掌握!

恭喜!您已经掌握了Docker监控与日志的核心知识。现在可以构建可观测的容器化应用环境,及时发现和解决问题。