第十七篇:《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 日志管理不仅仅是防止磁盘爆满,更是可观测性的基石。通过选择合适的日志驱动和集中收集工具,你可以轻松查看、搜索和告警,显著提升故障排查效率。

相关推荐
打工仔折腾 AI5 分钟前
Docker镜像分层与卷挂载到底怎么工作:一次文件系统层面的实测分析
运维·人工智能·后端·python·docker·容器·性能优化
大猫会长42 分钟前
调用codebuddy集成的supabase授权白屏解决方法
linux·运维·服务器
夜之眷属1 小时前
服务器被挖矿病毒入侵的排查与清理实录
运维·服务器
极客先躯1 小时前
高级java每日一道面试题-2026年01月20日-实战篇[Docker]-如何实现镜像的跨区域复制?
java·运维·docker·容器·架构图
韩振方2 小时前
为什么服务显示占了 8G,实际内存却没那么多?
运维
xixiaoyunya3 小时前
虚拟机备份怎么做:镜像级与文件级搭配的完整实操方案
linux·运维·网络
阿明63 小时前
进程替换【Linux】
linux·运维·服务器
sunoo-2293 小时前
【嵌入式Linux驱动学习】Day1-Day2 全流程梳理:环境搭建→U-Boot→内核→根文件系统→驱动基础
linux·运维·驱动开发·笔记·学习·阿里云·恩智浦
YonyouHRSaaS3 小时前
从安全、信创、运维三方面看,人力资源管理系统哪种部署方式更适合企业HR?
运维·安全·hr系统·人力资源管理系统·hr saas·人事管理系统
倔强的石头1064 小时前
【Linux指南】动静态库系列(十二):库工程发布与错误排查:从能跑到可维护
linux·运维·服务器