Docker-日志与监控:集中采集与性能分析实战

Docker-日志与监控:集中采集与性能分析实战

文章目录

  • Docker-日志与监控:集中采集与性能分析实战
    • 摘要
    • [一、Docker 日志基础:理解默认行为](#一、Docker 日志基础:理解默认行为)
      • [1.1 默认日志驱动:json-file](#1.1 默认日志驱动:json-file)
      • [1.2 日志轮转(Log Rotation)防磁盘爆满](#1.2 日志轮转(Log Rotation)防磁盘爆满)
    • [二、进阶:集中式日志采集(EFK 架构)](#二、进阶:集中式日志采集(EFK 架构))
      • [2.1 为什么选 EFK 而非 ELK?](#2.1 为什么选 EFK 而非 ELK?)
      • [2.2 架构图解](#2.2 架构图解)
      • [2.3 使用 Compose 部署 EFK 栈](#2.3 使用 Compose 部署 EFK 栈)
      • [2.4 启动并验证](#2.4 启动并验证)
    • [三、容器性能监控:Prometheus + cAdvisor + Grafana](#三、容器性能监控:Prometheus + cAdvisor + Grafana)
      • [3.1 核心组件介绍](#3.1 核心组件介绍)
      • [3.2 监控架构](#3.2 监控架构)
      • [3.3 Compose 部署监控栈](#3.3 Compose 部署监控栈)
      • [3.4 验证与使用](#3.4 验证与使用)
    • 四、最佳实践与避坑指南
      • [4.1 应用日志必须输出到 stdout/stderr](#4.1 应用日志必须输出到 stdout/stderr)
      • [4.2 结构化日志(JSON)更利于分析](#4.2 结构化日志(JSON)更利于分析)
      • [4.3 避免过度采集](#4.3 避免过度采集)
      • [4.4 生产环境注意事项](#4.4 生产环境注意事项)
    • 五、总结:构建你的可观测性金字塔
    • 结语

关键字: Docker 日志EFKPrometheus 监控cAdvisorGrafana容器监控集中日志可观测性

摘要

"没有日志的系统如同盲人开车------你不知道哪里出了问题,直到撞上墙。"

在容器化世界,日志和监控不再是"可选项",而是保障服务稳定性的基础设施。

你是否遇到过这些场景?

  • 容器突然退出,docker logs 却只看到最后一行 "Killed";
  • 多个微服务日志分散在不同终端,排查链路耗时半小时;
  • CPU 使用率飙升,却无法定位是哪个容器在"挖矿";
  • 用户反馈慢,但你连请求在哪一层卡住都不知道......

这些问题的根源,往往不是代码缺陷,而是缺乏有效的可观测性(Observability)体系

本文将带你从零构建一套适用于中小团队的 Docker 日志与监控方案,涵盖:

✅ 容器日志的输出与管理

✅ 使用 Filebeat + Elasticsearch + Kibana(EFK)实现日志集中查询

✅ 通过 Prometheus + cAdvisor + Grafana 实现容器性能监控

✅ 借助 Docker Compose 一键部署整套系统

准备好了吗?让我们把"黑盒"变成"透明玻璃房"。


一、Docker 日志基础:理解默认行为

1.1 默认日志驱动:json-file

当你运行 docker run nginx,Docker 默认使用 json-file 驱动,将 stdout/stderr 写入 JSON 文件:

bash 复制代码
# 查看日志位置
docker inspect nginx | grep LogPath
# 输出:/var/lib/docker/containers/<id>/<id>-json.log

每条日志格式如下:

json 复制代码
{
  "log": "172.18.0.1 - - [05/Nov/2025:08:30:00 +0000] \"GET / HTTP/1.1\" 200\n",
  "stream": "stdout",
  "time": "2025-11-05T08:30:00.123456789Z"
}

1.2 日志轮转(Log Rotation)防磁盘爆满

默认情况下,日志文件会无限增长!必须配置轮转:

/etc/docker/daemon.json 中添加:

json 复制代码
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m",
    "max-file": "3"
  }
}

然后重启 Docker:

bash 复制代码
sudo systemctl restart docker

✅ 效果:每个容器最多保留 3 个日志文件,单个不超过 100MB,总计 300MB。


二、进阶:集中式日志采集(EFK 架构)

对于多容器应用,分散的日志毫无意义。我们需要一个统一入口进行搜索、过滤、告警。

2.1 为什么选 EFK 而非 ELK?

  • Elasticsearch:存储与索引日志;
  • Filebeat:轻量级日志采集器(替代 Logstash,资源占用更低);
  • Kibana:可视化查询界面。

相比传统 ELK(Logstash 重),EFK 更适合容器环境


2.2 架构图解

stdout stdout stdout Flask App Docker json-file Nginx MySQL Filebeat Elasticsearch Kibana 运维人员

🔑 关键点:所有应用只需正常输出到 stdout,Filebeat 自动采集宿主机上的日志文件。


2.3 使用 Compose 部署 EFK 栈

项目结构:

text 复制代码
logging-stack/
├── docker-compose.yml
├── filebeat/
│   └── filebeat.yml
└── elasticsearch/
    └── elasticsearch.yml
docker-compose.yml
yaml 复制代码
version: '3.8'

services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.12.0
    environment:
      - discovery.type=single-node
      - xpack.security.enabled=false  # 开发环境关闭安全
    volumes:
      - es_data:/usr/share/elasticsearch/data
    ports:
      - "9200:9200"
    networks:
      - monitoring

  kibana:
    image: docker.elastic.co/kibana/kibana:8.12.0
    depends_on:
      - elasticsearch
    ports:
      - "5601:5601"
    networks:
      - monitoring

  filebeat:
    image: docker.elastic.co/beats/filebeat:8.12.0
    user: root
    volumes:
      - ./filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml:ro
      - /var/lib/docker/containers:/var/lib/docker/containers:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
    command: ["--strict.perms=false"]
    depends_on:
      - elasticsearch
    networks:
      - monitoring

volumes:
  es_data:

networks:
  monitoring:
    driver: bridge
filebeat/filebeat.yml
yaml 复制代码
filebeat.inputs:
- type: container
  paths:
    - /var/lib/docker/containers/*/*.log
  processors:
    - add_docker_metadata: ~

output.elasticsearch:
  hosts: ["elasticsearch:9200"]

📌 注意:Filebeat 需要读取宿主机的 Docker 日志目录,因此挂载了两个关键路径。


2.4 启动并验证

bash 复制代码
# 启动日志栈
docker compose up -d

# 部署一个测试应用
docker run -d --name test-app alpine sh -c 'while true; do echo "$(date): Hello from test-app"; sleep 5; done'

# 访问 Kibana:http://localhost:5601
# 首次使用需创建 index pattern(如 filebeat-*)

在 Kibana 中搜索 test-app,即可看到实时日志流!


三、容器性能监控:Prometheus + cAdvisor + Grafana

日志解决"发生了什么",监控回答"系统状态如何"。

3.1 核心组件介绍

  • cAdvisor(Container Advisor):Google 开源,自动采集容器 CPU、内存、网络、磁盘指标;
  • Prometheus:时序数据库,拉取并存储指标;
  • Grafana:可视化面板,展示资源使用趋势。

3.2 监控架构

暴露指标 查询数据 cAdvisor Prometheus Grafana 运维大屏

cAdvisor 会自动发现本机所有容器,并暴露 /metrics 接口(格式为 Prometheus 标准)。


3.3 Compose 部署监控栈

yaml 复制代码
# monitoring-stack/docker-compose.yml
version: '3.8'

services:
  cadvisor:
    image: gcr.io/cadvisor/cadvisor:v0.47.2
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:rw
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro
    ports:
      - "8080:8080"
    privileged: true  # 需要访问宿主机信息

  prometheus:
    image: prom/prometheus:v2.47.1
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
    ports:
      - "9090:9090"
    depends_on:
      - cadvisor

  grafana:
    image: grafana/grafana:10.1.5
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
    volumes:
      - grafana_data:/var/lib/grafana

volumes:
  grafana_data:
prometheus/prometheus.yml
yaml 复制代码
scrape_configs:
  - job_name: 'cadvisor'
    static_configs:
      - targets: ['cadvisor:8080']

3.4 验证与使用

  1. 启动监控栈:docker compose up -d
  2. 访问 cAdvisor:http://localhost:8080 → 查看容器实时资源
  3. 访问 Prometheus:http://localhost:9090 → 搜索 container_cpu_usage_seconds_total
  4. 访问 Grafana:
    • 登录(admin/admin)
    • 添加 Prometheus 数据源(URL: http://prometheus:9090
    • 导入官方 Dashboard ID:193(Docker and Host Metrics)

四、最佳实践与避坑指南

4.1 应用日志必须输出到 stdout/stderr

❌ 不要写日志到文件(如 /app/app.log),除非配合日志驱动或 sidecar 采集。

✅ 正确做法(Python 示例):

python 复制代码
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

@app.route('/')
def home():
    logger.info("User accessed homepage")
    return "OK"

这样日志会自动进入 Docker 日志管道。


4.2 结构化日志(JSON)更利于分析

将日志格式化为 JSON,Kibana 可自动解析字段:

python 复制代码
import json
import sys

def log_event(event, user_id=None):
    record = {
        "level": "info",
        "event": event,
        "user_id": user_id,
        "timestamp": time.time()
    }
    print(json.dumps(record), flush=True)

输出示例:

json 复制代码
{"level":"info","event":"login_success","user_id":"123"}

在 Kibana 中可直接按 user_id 过滤,无需正则解析。


4.3 避免过度采集

  • Filebeat 不要采集所有容器,可通过标签过滤:

    yaml 复制代码
    processors:
      - drop_event.when.not.equals.docker.container.labels.monitoring: "true"
  • Prometheus 抓取间隔建议 15~30 秒,避免高频拉取压垮系统。


4.4 生产环境注意事项

组件 生产建议
Elasticsearch 启用 TLS、认证、快照备份
Prometheus 使用远程存储(如 Thanos)防数据丢失
Grafana 配置 LDAP/OAuth 登录,关闭匿名访问
Filebeat 使用 Kubernetes DaemonSet 部署(非 Compose)

五、总结:构建你的可观测性金字塔

层级 工具 作用
日志(Logs) EFK 回溯事件、调试错误
指标(Metrics) Prometheus + Grafana 监控性能、设置告警
链路追踪(Tracing) Jaeger / Zipkin 分析微服务调用链(后续专题)

🌟 终极目标:当用户说"网站变慢了",你能在 1 分钟内定位到是 Redis 缓存击穿,还是某个容器 CPU 被占满。


结语

日志与监控不是"锦上添花",而是"雪中送炭"。在容器快速启停、IP 动态变化的环境下,传统的 SSH 登录查日志方式早已失效。

通过本文的 EFK + Prometheus 方案,你已具备构建现代化可观测体系的能力。无论是排查 Bug、优化性能,还是应对故障复盘,都将游刃有余。

记住:最好的运维,是让问题在用户发现前就被预警。


系列预告

下一篇 → 《Docker 与 CI/CD:集成 GitHub Actions 实现自动化构建与部署》

我们将把 Docker 融入 DevOps 流水线,实现"代码提交 → 自动测试 → 镜像构建 → 发布上线"全自动化!


参考资料


相关推荐
Just_Do_IT_OK4 小时前
Docker--Spark
docker·容器·spark
1***81534 小时前
Docker视频
docker·容器·音视频
sleP4o4 小时前
Windows用Docker Desktop部署Redis
redis·docker·容器
Andy6 小时前
Docker 初识
java·docker·容器
BG8EQB6 小时前
Docker 极简入门:从零到实践的全攻略
运维·docker·容器
1***s6327 小时前
Docker虚拟现实开发
docker·容器·vr
Just_Do_IT_OK8 小时前
Docker--Apache/hadoop
hadoop·docker·apache
Thexhy8 小时前
CentOS快速安装DockerCE指南
linux·docker
二流子学程序15 小时前
Windows创建一个Docker镜像
docker·容器