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

相关推荐
love530love1 小时前
【笔记】ComfyUI 源码部署版更新后一键修复:从手动补丁到自动化工作流
运维·人工智能·windows·笔记·python·自动化·comfyui
hj2862511 小时前
Linux + 计算机网络全套精炼整理笔记
linux·运维
剑神一笑1 小时前
Linux chmod 命令深度解析:从权限位到符号模式的完整指南
linux·运维·chrome
流浪0011 小时前
LInux系统篇(二):深入剖析 Linux 进程:状态变迁、优先级及调度切换逻辑
linux·运维·服务器
daad7771 小时前
记录一个串口模块没有回包的问题
linux·运维·服务器
青梅橘子皮2 小时前
Linux---虚拟地址空间
linux·运维·算法
SilentSamsara2 小时前
Python 服务的 K8s 部署:HPA/ConfigMap/Secret 完整配置
开发语言·python·青少年编程·容器·kubernetes
晚风予卿云月2 小时前
【Linux】进程控制(一)—进程创建、进程终止与信号全流程详解
linux·运维·服务器·后端开发
roman_日积跬步-终至千里2 小时前
【架构实践(1)】架构师如何正确理解业务
运维·架构