第十七篇:《Docker 日志管理:驱动配置与集中收集》

容器默认会将 stdout/stderr 输出保存到宿主机的 JSON 文件中,随着容器运行时间增长,日志文件可能占满磁盘,导致服务不可用。同时,分布式环境下查看分散在各主机上的日志极其低效。本文深入讲解 Docker 的日志驱动机制,如何限制日志大小、配置不同的日志驱动(json-file、syslog、fluentd),并搭建 ELK 或 Loki 实现集中日志管理。

一、Docker 日志基础

容器中的应用程序如果输出日志到标准输出(stdout)和标准错误(stderr),Docker 会捕获这些输出并通过日志驱动(logging driver)进行处理。默认驱动是 json-file,将日志写入宿主机的 /var/lib/docker/containers//-json.log 文件。

问题:

容器不限制日志文件大小,可能导致磁盘被写满。

默认驱动不支持日志轮转和压缩。

多主机环境下日志分散,难以统一查看。

二、配置日志驱动

2.1 查看当前日志驱动

bash 复制代码
docker info | grep "Logging Driver"

2.2 运行时指定日志驱动

bash 复制代码
# 使用 syslog 驱动
docker run --log-driver syslog --log-opt syslog-address=tcp://192.168.1.10:514 alpine echo "test"

# 使用 fluentd 驱动
docker run --log-driver fluentd --log-opt fluentd-address=192.168.1.10:24224 ...

2.3 全局默认驱动配置(daemon.json)

编辑 /etc/docker/daemon.json:

json

{

"log-driver": "json-file",

"log-opts": {

"max-size": "10m",

"max-file": "3",

"compress": "true"

}

}

重启 Docker:systemctl restart docker。

三、常用日志驱动详解

四、json-file 驱动配置(本地轮转)

bash 复制代码
# 运行容器时指定
docker run -d --log-driver json-file \
  --log-opt max-size=10m \
  --log-opt max-file=3 \
  --log-opt compress=true \
  nginx

max-size:单个日志文件最大大小(如 10m、1g)。

max-file:最多保留的文件数(轮转后保留旧文件数量)。

compress:是否压缩旧日志。

查看日志文件:

bash 复制代码
ls /var/lib/docker/containers/<container-id>/
# 会出现:<id>-json.log, <id>-json.log.1.gz 等

五、集中日志收集方案

5.1 使用 ELK(Elasticsearch + Logstash + Kibana)

架构:容器 → 日志驱动 → Logstash → Elasticsearch → Kibana

步骤:

配置 daemon.json 使用 gelf 驱动发送到 Logstash:

json

{

"log-driver": "gelf",

"log-opts": {

"gelf-address": "udp://localhost:12201"

}

}

启动 Logstash 配置 gelf input:

ruby

input {

gelf {

port => 12201

}

}

output {

elasticsearch {

hosts => "http://elasticsearch:9200"

}

}

启动 Elasticsearch 和 Kibana(可通过 Docker Compose)。

5.2 轻量级方案:Loki + Promtail(Grafana 栈)

Loki 是受 Prometheus 启发的日志聚合系统,不索引全文,只索引标签,成本低。

docker-compose 示例:

yaml 复制代码
version: '3'
services:
  loki:
    image: grafana/loki:latest
    ports:
      - "3100:3100"
  promtail:
    image: grafana/promtail:latest
    volumes:
      - /var/lib/docker/containers:/var/lib/docker/containers:ro
      - /var/run/docker.sock:/var/run/docker.sock
    command: -config.file=/etc/promtail/promtail-docker-config.yaml
  grafana:
    image: grafana/grafana:latest
    ports:
      - "3000:3000"

在 Grafana 中添加 Loki 数据源,即可通过 LogQL 查询日志。

5.3 使用 Fluentd(最通用)

bash 复制代码
# 启动 Fluentd 容器
docker run -d --name fluentd \
  -p 24224:24224 \
  -v /var/log/fluentd:/fluentd/log \
  fluent/fluentd:latest

# 运行容器时指定日志驱动
docker run --log-driver fluentd --log-opt fluentd-address=localhost:24224 ...

Fluentd 可将日志转发到 Elasticsearch、S3、Kafka 等。

六、日志驱动常见问题

七、清理日志命令

bash 复制代码
# 清理所有容器的日志文件(保留最近 3 天?)
docker container prune --filter "until=72h"

# 手动清理单容器日志文件
truncate -s 0 /var/lib/docker/containers/*/*-json.log

# 使用 logrotate 工具(推荐)
cat /etc/logrotate.d/docker
/var/lib/docker/containers/*/*-json.log {
    daily
    rotate 7
    compress
    missingok
    delaycompress
    copytruncate
}

八、最佳实践

生产环境必须配置日志轮转(max-size / max-file)。

集中日志收集:选择 ELK / Loki / Splunk,避免登录各主机查看。

避免在容器内写日志文件:应输出到 stdout/stderr,由 Docker 驱动统一处理。

使用标签丰富日志:如 --log-opt tag="{{.ImageName}}|{{.Name}}"(对于 json-file 驱动有效)。

安全考虑:日志中避免输出密码、token 等敏感信息。

监控磁盘使用率:设置告警,避免日志占满导致容器崩溃。

九、小结

Docker 日志管理不仅仅是防止磁盘爆满,更是可观测性的基石。通过选择合适的日志驱动和集中收集工具,你可以轻松查看、搜索和告警,显著提升故障排查效率。

相关推荐
Elastic 中国社区官方博客几秒前
列式存储并不等同于列式数据库。Columnar 模式为 Elasticsearch 带来了什么
大数据·运维·数据库·elasticsearch·搜索引擎
fengkai454533 分钟前
八、Docker详解4-5
运维·docker
智恒百亿1 小时前
RTX 5090 八卡服务器 vs RTX PRO 6000 整机:AI 推理、微调与渲染选型部署指南
运维·服务器·rtx5090
蓝胖的四次元口袋3 小时前
Docker Compose多容器编排与Nginx集群实战
运维·nginx·docker compose
懂软件的胡子个哥3 小时前
微信 API 消息回调怎么设计,才能避免丢消息和重复处理
运维·微信·架构·wechatapi·个人微信号二次开发
吉甫作诵3 小时前
Redis 常用命令大全:11 大类命令速查手册
运维·数据库·redis·缓存·nosql
Acrellea5 小时前
告别粗放式能耗管理!安科瑞EIOT平台助力产业园区智慧低碳运营
运维·安全·能源
Databuff6 小时前
五款主流 SSH 免费工具介绍
运维·ssh·运维开发
菜鸟学编程o6 小时前
Linux常见指令
linux·运维·服务器
pt10437 小时前
AIOps机器学习——当警报阈值被调高之后
运维·人工智能·自动化