Docker容器化应用监控与日志管理:Prometheus+Grafana+ELK Stack完整集成方案

 
更多

Docker容器化应用监控与日志管理:Prometheus+Grafana+ELK Stack完整集成方案

在现代云原生架构中,Docker容器化技术已成为构建、部署和运行应用的标准方式。然而,随着微服务架构的普及和容器数量的快速增长,如何有效监控容器性能、收集应用日志并进行可视化分析,成为运维团队面临的重大挑战。

本文将详细介绍一套完整的Docker容器化环境监控与日志管理解决方案,整合 Prometheus(指标监控)、Grafana(可视化展示)和 ELK Stack(Elasticsearch、Logstash、Kibana,用于日志分析)三大核心技术,提供从部署、配置到最佳实践的全流程指南,适用于生产环境。


一、方案架构概览

本方案采用分层架构,实现对Docker容器环境的全方位可观测性:

  • 指标采集层:Prometheus 通过 Pull 模式从容器、节点及服务暴露的 /metrics 接口定期拉取监控数据。
  • 日志采集层:Filebeat 或 Fluentd 从容器日志文件或标准输出中收集日志,发送至 Logstash 进行处理,最终写入 Elasticsearch。
  • 存储层
    • Prometheus 存储时间序列指标数据
    • Elasticsearch 存储结构化日志数据
  • 可视化层
    • Grafana 用于展示 Prometheus 指标,支持自定义仪表盘
    • Kibana 提供日志搜索、分析与可视化能力
  • 告警层:Prometheus 配置 Alertmanager 实现基于指标的告警通知(邮件、Slack、Webhook等)

该架构具备高可用、可扩展、松耦合的特点,适用于中小型企业及中大型生产环境。


二、环境准备与基础组件部署

1. 前置条件

确保以下环境已准备就绪:

  • Docker Engine 20.10+
  • Docker Compose 2.0+
  • 至少 4GB 内存,8GB 推荐
  • 开放端口:9090(Prometheus)、3000(Grafana)、5601(Kibana)、9200(Elasticsearch)

2. 使用 Docker Compose 统一部署

我们使用 docker-compose.yml 文件统一管理所有组件。创建项目目录:

mkdir docker-monitoring && cd docker-monitoring

创建 docker-compose.yml 文件:

version: '3.8'

services:
  # Prometheus 服务
  prometheus:
    image: prom/prometheus:v2.50.0
    container_name: prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus/:/etc/prometheus/
      - 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=15d'
    restart: unless-stopped

  # Alertmanager(可选)
  alertmanager:
    image: prom/alertmanager:v0.27.0
    container_name: alertmanager
    ports:
      - "9093:9093"
    volumes:
      - ./alertmanager/:/etc/alertmanager/
    command:
      - '--config.file=/etc/alertmanager/alertmanager.yml'
      - '--storage.path=/alertmanager'
    restart: unless-stopped

  # Grafana 可视化
  grafana:
    image: grafana/grafana:10.3.3
    container_name: grafana
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=securepass123
      - GF_INSTALL_PLUGINS=grafana-polystat-panel
    volumes:
      - grafana_data:/var/lib/grafana
      - ./grafana/provisioning/:/etc/grafana/provisioning/
    restart: unless-stopped

  # Elasticsearch(日志存储)
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.11.3
    container_name: elasticsearch
    environment:
      - discovery.type=single-node
      - ES_JAVA_OPTS=-Xms2g -Xmx2g
      - xpack.security.enabled=false
      - xpack.monitoring.collection.enabled=true
    ports:
      - "9200:9200"
      - "9300:9300"
    volumes:
      - elasticsearch_data:/usr/share/elasticsearch/data
    restart: unless-stopped
    ulimits:
      memlock:
        soft: -1
        hard: -1
    networks:
      - monitoring

  # Logstash(日志处理)
  logstash:
    image: docker.elastic.co/logstash/logstash:8.11.3
    container_name: logstash
    volumes:
      - ./logstash/pipeline/:/usr/share/logstash/pipeline/
      - ./logstash/config/:/usr/share/logstash/config/
    ports:
      - "5044:5044"  # Beats 输入
    environment:
      - xpack.monitoring.enabled=false
    depends_on:
      - elasticsearch
    restart: unless-stopped
    networks:
      - monitoring

  # Kibana(日志可视化)
  kibana:
    image: docker.elastic.co/kibana/kibana:8.11.3
    container_name: kibana
    ports:
      - "5601:5601"
    environment:
      - ELASTICSEARCH_HOSTS=["http://elasticsearch:9200"]
    depends_on:
      - elasticsearch
    restart: unless-stopped
    networks:
      - monitoring

  # Filebeat(日志采集,可运行在宿主机或Sidecar)
  filebeat:
    image: docker.elastic.co/beats/filebeat:8.11.3
    user: root
    volumes:
      - ./filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml
      - /var/lib/docker/containers:/var/lib/docker/containers:ro
      - /var/log:/var/log:ro
    command: ["filebeat", "-e", "-strict.perms=false"]
    restart: unless-stopped
    networks:
      - monitoring

volumes:
  prometheus_data:
  grafana_data:
  elasticsearch_data:

networks:
  monitoring:
    driver: bridge

⚠️ 注意:生产环境中建议禁用单节点模式,启用安全认证(TLS、用户名密码),并配置 JVM 堆大小。


三、Prometheus 指标监控配置

1. 配置文件 prometheus/prometheus.yml

global:
  scrape_interval: 15s
  evaluation_interval: 15s

rule_files:
  - "alerts.yml"

alerting:
  alertmanagers:
    - static_configs:
        - targets: ['alertmanager:9093']

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

  # 采集 Docker 宿主机节点指标(需运行 node-exporter)
  - job_name: 'node'
    static_configs:
      - targets: ['host.docker.internal:9100']  # macOS/Windows
        # 或使用宿主机 IP:172.17.0.1

  # 采集容器内应用指标(如 Spring Boot Actuator)
  - job_name: 'spring-boot-app'
    metrics_path: '/actuator/prometheus'
    static_configs:
      - targets: ['app-container:8080']

  # 使用 cAdvisor 采集容器资源使用情况
  - job_name: 'cadvisor'
    static_configs:
      - targets: ['cadvisor:8080']

2. 部署 node-exporter 和 cAdvisor

为监控宿主机和容器资源,需额外部署:

# 在 docker-compose.yml 中添加
  node-exporter:
    image: prom/node-exporter:v1.7.0
    container_name: node-exporter
    ports:
      - "9100:9100"
    volumes:
      - "/proc:/host/proc:ro"
      - "/sys:/host/sys:ro"
      - "/:/rootfs:ro"
    command:
      - '--path.procfs=/host/proc'
      - '--path.sysfs=/host/sys'
      - '--collector.filesystem.ignored-mount-points=^/(sys|proc|dev|host|etc)($$|/)'
    restart: unless-stopped

  cadvisor:
    image: gcr.io/cadvisor/cadvisor:v0.47.1
    container_name: cadvisor
    ports:
      - "8080:8080"
    volumes:
      - "/:/rootfs:ro"
      - "/var/run:/var/run:rw"
      - "/sys:/sys:ro"
      - "/var/lib/docker/:/var/lib/docker:ro"
    restart: unless-stopped

3. 告警规则示例 prometheus/alerts.yml

groups:
  - name: container_alerts
    rules:
      - alert: HighContainerCPUUsage
        expr: rate(container_cpu_usage_seconds_total{name="app-container"}[5m]) > 0.8
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: "High CPU usage on container {{ $labels.name }}"
          description: "CPU usage is above 80% for more than 2 minutes."

      - alert: ContainerMemoryHigh
        expr: container_memory_usage_bytes{name="app-container"} / container_spec_memory_limit_bytes{name="app-container"} > 0.85
        for: 3m
        labels:
          severity: warning
        annotations:
          summary: "High memory usage on container {{ $labels.name }}"
          description: "Memory usage is above 85% of limit."

      - alert: TargetDown
        expr: up == 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "Target {{ $labels.job }} is down"
          description: "Prometheus target {{ $labels.instance }} in job {{ $labels.job }} has been down for more than 1 minute."

4. Alertmanager 配置 alertmanager/alertmanager.yml

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

receivers:
  - name: 'email-notifications'
    email_configs:
      - to: 'ops@example.com'
        from: 'alertmanager@example.com'
        smarthost: 'smtp.gmail.com:587'
        auth_username: 'alertmanager@example.com'
        auth_identity: 'alertmanager@example.com'
        auth_password: 'your-app-password'
        require_tls: true

四、Grafana 可视化配置

1. 数据源配置(自动注入)

./grafana/provisioning/datasources/prometheus.yml 中添加:

apiVersion: 1
datasources:
  - name: Prometheus
    type: prometheus
    url: http://prometheus:9090
    access: proxy
    isDefault: true

2. 仪表盘自动加载

创建 ./grafana/provisioning/dashboards/dashboard.yml

apiVersion: 1
providers:
  - name: 'Docker Monitoring'
    orgId: 1
    folder: ''
    type: file
    disableDeletion: false
    editable: true
    options:
      path: /etc/grafana/provisioning/dashboards

导入一个预定义的 Docker 监控仪表盘(如 ID: 193),保存为 docker-overview.json 并放入 ./grafana/provisioning/dashboards/

3. 常用 Prometheus 查询示例

指标 查询语句
容器 CPU 使用率 rate(container_cpu_usage_seconds_total[5m])
容器内存使用 container_memory_usage_bytes
容器网络流入 rate(container_network_receive_bytes_total[5m])
节点 CPU 使用率 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
节点内存使用率 (node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100

五、ELK Stack 日志管理

1. Filebeat 配置 filebeat/filebeat.yml

filebeat.inputs:
  - type: container
    paths:
      - /var/lib/docker/containers/*/*.log
    processors:
      - add_docker_metadata: ~
    json.keys_under_root: true
    json.add_error_key: true

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

2. Logstash 配置

创建 logstash/pipeline/logstash.conf

input {
  beats {
    port => 5044
  }
}

filter {
  # 解析 JSON 日志(如 Spring Boot)
  if [message] =~ /^\{.*\}$/ {
    json {
      source => "message"
      remove_field => ["message"]
    }
  }

  # 添加时间戳字段
  date {
    match => ["timestamp", "ISO8601"]
    target => "@timestamp"
  }

  # 分类日志来源
  if [docker][container][name] =~ "app-" {
    mutate {
      add_field => { "service" => "backend-api" }
    }
  }
}

output {
  elasticsearch {
    hosts => ["http://elasticsearch:9200"]
    index => "logs-%{+YYYY.MM.dd}"
  }
}

3. Kibana 使用技巧

  • 访问 http://localhost:5601
  • 进入 Stack Management > Index Patterns,创建 logs-* 索引模式
  • 使用 Discover 功能搜索日志
  • 创建 VisualizationsDashboards 分析错误趋势、响应时间等

六、应用集成示例:Spring Boot + Micrometer

1. 添加依赖

<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

2. 配置 application.yml

management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus
  metrics:
    tags:
      application: ${spring.application.name}

3. Dockerfile 示例

FROM openjdk:17-jdk-slim
COPY target/myapp.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app.jar"]

构建并运行:

docker build -t my-spring-app .
docker run -d -p 8080:8080 --name app-container my-spring-app

Prometheus 将自动从 http://app-container:8080/actuator/prometheus 采集指标。


七、最佳实践与生产建议

1. 安全性

  • 启用 Elasticsearch 安全功能(TLS、RBAC)
  • 为 Grafana 配置 LDAP/OAuth 认证
  • Prometheus 和 Alertmanager 前置 Nginx 实现 HTTPS 和 Basic Auth
  • 使用 Docker secrets 管理敏感配置

2. 性能优化

  • Prometheus:合理设置 scrape_intervalretention.time(建议 15-30 天)
  • Elasticsearch:配置索引生命周期管理(ILM),自动归档或删除旧日志
  • Filebeat:启用 multiline 处理堆栈跟踪日志

3. 高可用部署(生产环境)

  • Prometheus:部署 Thanos 或 Cortex 实现多副本和长期存储
  • Elasticsearch:配置集群模式(3 节点以上),分片与副本
  • Grafana:使用外部数据库(PostgreSQL)存储仪表盘
  • 使用 Kubernetes Operator(如 Prometheus Operator、ECK)简化管理

4. 日志规范建议

  • 应用日志使用 JSON 格式输出
  • 包含关键字段:timestamp, level, service, trace_id, message
  • 避免敏感信息(密码、token)写入日志

八、故障排查常见问题

问题 可能原因 解决方案
Prometheus 无法抓取目标 目标未暴露 /metrics 或网络不通 检查容器端口映射,使用 curl 测试
Filebeat 无数据 权限不足或路径错误 使用 user: root,确认日志路径正确
Elasticsearch 启动失败 内存不足或 vm.max_map_count 未设置 执行 sysctl -w vm.max_map_count=262144
Kibana 无法连接 ES 网络隔离或认证失败 检查 elasticsearch.hosts 配置
Grafana 无数据 数据源 URL 错误 使用容器名而非 localhost

九、总结

本文详细介绍了基于 Prometheus + Grafana + ELK Stack 的 Docker 容器化应用监控与日志管理完整方案。通过统一的 Docker Compose 部署,实现了:

  • 实时采集容器、节点、应用的性能指标
  • 可视化展示关键监控数据
  • 集中式日志收集、分析与告警
  • 灵活的扩展性和生产级稳定性

该方案已在多个生产环境中验证,具备良好的可维护性和可观测性。结合微服务架构,可进一步实现服务依赖分析、链路追踪(集成 Jaeger)等高级功能。

建议在实际部署中根据业务规模逐步演进,从单机部署过渡到高可用集群,并持续优化采集策略与存储成本。


标签:Docker, 监控, Prometheus, Grafana, ELK Stack

打赏

本文固定链接: https://www.cxy163.net/archives/8230 | 绝缘体

该日志由 绝缘体.. 于 2020年04月16日 发表在 未分类 分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。
原创文章转载请注明: Docker容器化应用监控与日志管理:Prometheus+Grafana+ELK Stack完整集成方案 | 绝缘体
关键字: , , , ,

Docker容器化应用监控与日志管理:Prometheus+Grafana+ELK Stack完整集成方案:等您坐沙发呢!

发表评论


快捷键:Ctrl+Enter