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(可视化)。

ELK 集中式日志收集架构 ELK 集中式日志收集架构 Docker 容器 Docker 容器 Docker 容器 Filebeat (采集/转发) Logstash (解析/过滤) Elasticsearch (存储/索引) Kibana (可视化) Filebeat 部署在每台宿主机上,采集 /var/lib/docker/containers/*/*.log 并发送至 Logstash

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(可视化)。

Loki 集中式日志收集架构 Loki 集中式日志收集架构 Docker 容器 Docker 容器 Docker 容器 Promtail (采集/标签) Loki (存储/查询) Grafana (可视化) Promtail 自动发现容器并添加标签(container_name、namespace 等),Loki 按标签索引

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 监控容器生命周期事件,辅助定位日志中断原因。