
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 日志、 EFK、 Prometheus 监控、 cAdvisor、 Grafana、 容器监控、 集中日志、 可观测性
摘要
"没有日志的系统如同盲人开车------你不知道哪里出了问题,直到撞上墙。"
在容器化世界,日志和监控不再是"可选项",而是保障服务稳定性的基础设施。
你是否遇到过这些场景?
- 容器突然退出,
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 验证与使用
- 启动监控栈:
docker compose up -d - 访问 cAdvisor:
http://localhost:8080→ 查看容器实时资源 - 访问 Prometheus:
http://localhost:9090→ 搜索container_cpu_usage_seconds_total - 访问 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 不要采集所有容器,可通过标签过滤:
yamlprocessors: - 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 流水线,实现"代码提交 → 自动测试 → 镜像构建 → 发布上线"全自动化!
参考资料:
- Docker Logging Overview: https://docs.docker.com/config/containers/logging/
- Elastic EFK Guide: https://www.elastic.co/guide/en/beats/filebeat/current/running-on-docker.html
- Prometheus Docker Monitoring: https://prometheus.io/docs/guides/cadvisor/
- Grafana Docker Dashboard: https://grafana.com/grafana/dashboards/193
