2. Docker 日志管理:驱动、轮转与集中式收集
在 Docker 企业环境中,日志是故障排查和系统监控的第一手资料。本章深入解析 Docker 日志驱动机制、日志轮转配置以及企业级集中式日志收集方案(ELK / Loki),帮助运维人员构建可观测的日志体系。
2.1 Docker 日志驱动(Logging Driver)
Docker 通过 logging driver 将容器的 stdout/stderr 输出转发到不同的后端。默认驱动为 json-file,企业环境常切换为 journald 或 syslog 以适配现有基础设施。
| 驱动名称 | 输出目标 | 适用场景 | 主要限制 |
|---|---|---|---|
| json-file | 宿主机文件系统(/var/lib/docker/containers/<id>/<id>-json.log) | 单机调试、开发环境 | 无轮转时易占满磁盘;默认不压缩 |
| journald | systemd journal(journalctl 查询) | 已使用 systemd 的 Linux 服务器 | 日志量过大时影响系统 journal 性能 |
| syslog | 本地 syslog 守护进程或远程 syslog 服务器 | 已有集中式 syslog 基础设施的企业 | 结构化日志需额外解析;UDP 可能丢日志 |
| gelf | Graylog Extended Log Format(UDP/TCP) | 直接对接 Graylog 集群 | 需 Graylog 接收端;配置较复杂 |
| fluentd | Fluentd 数据收集器 | 统一日志转发管道 | 需额外部署 Fluentd agent |
| awslogs | Amazon CloudWatch Logs | AWS 原生环境 | 绑定 AWS 生态;非 AWS 环境不可用 |
最佳实践: 生产环境建议使用
journald 或 syslog 作为第一跳驱动,再通过 agent 转发到集中式平台。避免在每台宿主机上直接使用 json-file 且不配置轮转。
2.1.1 配置日志驱动
全局配置(/etc/docker/daemon.json):
{
"log-driver": "journald",
"log-opts": {
"tag": "{{.Name}}/{{.ID}}"
}
}
容器级别覆盖(docker run):
docker run --log-driver syslog --log-opt syslog-address=tcp://192.168.1.100:514 \
--log-opt tag="nginx-prod" nginx:latest
2.2 日志轮转配置
无论使用哪种驱动,日志轮转都是防止磁盘写满的关键措施。对于 json-file 驱动,Docker 原生支持轮转参数。
| 参数 | 说明 | 推荐值 |
|---|---|---|
max-size |
单个日志文件最大大小 | 10m 或 50m |
max-file |
保留的日志文件数量 | 3 ~ 5 |
compress |
是否压缩轮转后的旧日志 | true |
配置示例(daemon.json):
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3",
"compress": "true"
}
}
注意: 修改 daemon.json 后需执行
systemctl restart docker 生效。已运行的容器不会自动应用新配置,需重建容器。
2.3 集中式日志收集集成方案
企业级环境需要将分散在数百台宿主机上的容器日志统一收集、存储和检索。主流方案为 ELK(Elasticsearch + Logstash + Kibana) 和 Loki(Grafana Loki + Promtail)。
2.3.1 ELK 集成方案
典型架构:容器日志 → Filebeat(轻量采集器)→ Logstash(解析/过滤)→ Elasticsearch(存储/索引)→ Kibana(可视化)。
Filebeat 配置示例(filebeat.yml):
filebeat.inputs:
- type: container
paths:
- '/var/lib/docker/containers/*/*.log'
json.keys_under_root: true
json.add_error_key: true
output.logstash:
hosts: ["logstash.example.com:5044"]
2.3.2 Loki 集成方案
Loki 是 Grafana 推出的轻量级日志系统,不建立全文索引,仅对日志元数据(标签)建立索引,存储成本更低。典型架构:容器日志 → Promtail(采集器)→ Loki(存储/查询)→ Grafana(可视化)。
Promtail 配置示例(promtail.yml):
scrape_configs:
- job_name: docker
docker_sd_configs:
- host: unix:///var/run/docker.sock
refresh_interval: 15s
relabel_configs:
- source_labels: ['__meta_docker_container_name']
target_label: 'container'
- source_labels: ['__meta_docker_container_log_stream']
target_label: 'log_stream'
2.4 方案对比与选型建议
| 维度 | ELK(Elastic Stack) | Loki + Grafana |
|---|---|---|
| 索引机制 | 全文索引,支持复杂搜索 | 仅索引标签,日志内容不索引 |
| 存储成本 | 较高(需大量磁盘和内存) | 较低(压缩存储,对象存储友好) |
| 查询速度 | 全文搜索快,聚合能力强 | 标签过滤快,内容搜索需扫描 |
| 与 Prometheus 集成 | 需额外配置 | 原生集成,统一 Grafana 面板 |
| 运维复杂度 | 较高(需管理 ES 集群) | 较低(单二进制部署) |
| 适用场景 | 需要深度日志分析、安全审计 | Kubernetes 环境、快速故障定位 |
选型建议:
- 已有 Elasticsearch 基础设施或需要复杂日志分析 → 选择 ELK。
- 以 Kubernetes 为主、已使用 Prometheus + Grafana → 选择 Loki。
- 中小规模集群(< 50 节点)→ Loki 更轻量;大规模集群(> 200 节点)→ ELK 更成熟。
2.5 故障排查常用命令
- 查看当前容器日志驱动:
docker inspect --format '{{.HostConfig.LogConfig.Type}}' <container> - 实时查看日志:
docker logs -f --tail 100 <container> - 检查日志文件大小:
ls -lh /var/lib/docker/containers/$(docker ps -q --no-trunc)/*-json.log - journald 查询容器日志:
journalctl CONTAINER_NAME=nginx-prod --since "5 min ago" - 测试 syslog 连通性:
logger -n 192.168.1.100 -P 514 "test message"
排障技巧: 当日志丢失时,优先检查日志驱动配置是否正确、磁盘空间是否充足、采集器(Filebeat/Promtail)是否正常运行。使用
docker events 监控容器生命周期事件,辅助定位日志中断原因。