一、Docker 日志驱动:选对工具事半功倍
容器日志就像快递单号,没选对记录方式,查问题时就可能抓瞎。Docker 默认的 json-file 驱动把日志存在本地 JSON 文件里,适合开发调试,但生产环境会遇到磁盘爆炸的风险。比如一个高频服务跑一天可能产生 10GB 日志,用默认配置的容器分分钟能把硬盘写满。
这时候就该看看其他日志驱动了。syslog 驱动直接把日志扔给系统日志服务,适合传统运维体系;journald 则是 Systemd 生态的专属方案。如果是云原生环境,awslogs 或 gcplogs 能无缝对接云服务。最灵活的是 fluentd,它能像乐高积木一样对接各种存储。
举个实际配置例子(技术栈:Docker + Fluentd):
# 启动容器时指定 fluentd 驱动
docker run --log-driver=fluentd \
--log-opt fluentd-address=192.168.1.100:24224 \
--log-opt tag="app.{{.Name}}" \
nginx:alpine
# 对应 fluentd 配置(/etc/fluent/fluent.conf)
<source>
@type forward # 接收 Docker 日志
port 24224
</source>
<match app.nginx*> # 按容器名路由日志
@type elasticsearch # 输出到 ES
host 192.168.1.101
port 9200
logstash_format true
</match>
注:这里用 tag 参数实现日志分类,{{.Name}} 会自动替换为容器名,就像给快递贴分类标签。
二、日志轮转:给日志装上自动删除按钮
不控制日志体积的运维就像不关水龙头接水,迟早要淹了机房。Docker 的 json-file 驱动支持本地日志轮转,关键配置看这两个参数:
max-size:单个日志文件最大尺寸(如 10m)max-file:保留的旧日志文件数量
实战配置示例:
# 限制每个日志文件 10MB,最多保留 3 个
docker run --log-driver=json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
redis:6
注:这个配置下,当 redis-json.log 超过 10MB 时会自动创建 redis-json.log.1,类似 Linux 的 logrotate 机制。
更复杂的场景可以用 logrotate 工具直接管理宿主机上的日志文件,比如每天切割并压缩旧日志:
# /etc/logrotate.d/docker 配置示例
/var/lib/docker/containers/*/*.log {
daily # 每天轮转
rotate 7 # 保留7天
compress # 启用压缩
delaycompress # 延迟压缩前一个文件
missingok # 文件不存在也不报错
size 100M # 超过100MB立即触发
}
三、集中式收集:让日志坐上高铁
当你有 20 台 Docker 主机时,登录每台机器查日志就像跑遍全市邮局找快递。这时候需要 ELK(Elasticsearch+Logstash+Kibana)或 EFK(Elasticsearch+Fluentd+Kibana)这样的集装车运输日志。
以 Fluentd 为例的完整管道配置(技术栈:Docker+Fluentd+ES):
# Step1: 启动 Fluentd 收集器(带 Elasticsearch 插件)
docker run -d -p 24224:24224 \
-v /path/to/fluent.conf:/fluentd/etc/fluent.conf \
fluent/fluentd:v1.14-1
# Step2: 业务容器日志定向到 Fluentd
docker run -d --log-driver=fluentd \
--log-opt fluentd-address=fluentd-host:24224 \
--log-opt tag="microservice.payment" \
your-payment-service:1.0
# 对应的 Fluentd 配置片段
<filter microservice.**> # 过滤支付服务日志
@type parser # 解析原始日志
key_name log # 解析的字段名
<parse>
@type json # 按JSON格式解析
</parse>
</filter>
<match **> # 所有日志最终去向
@type elasticsearch
hosts es01:9200,es02:9200 # ES集群地址
logstash_prefix docker-${tag_parts[0]} # 按服务名建索引
</match>
注:${tag_parts[0]} 会提取 tag 的第一段(如 microservice),实现按业务分类存储。
四、避坑指南与高阶玩法
时区问题:容器内默认 UTC 时间,可以在 Fluentd 里用
time_key和time_format转换:<filter> @type record_transformer enable_ruby true <record> local_time "${Time.now.localtime}" </record> </filter>敏感信息过滤:用
grep插件屏蔽密码等数据:<filter **> @type grep exclude password .*[pP]assw(or)?d=.* </filter>性能调优:高并发场景建议启用 Fluentd 的异步缓冲:
<match **> @type elasticsearch # ...其他配置... <buffer> # 缓冲设置 @type file path /var/log/fluentd/buffer flush_interval 5s # 5秒刷一次磁盘 chunk_limit_size 8MB # 每个块最大8MB </buffer> </match>
对于需要实时报警的场景,可以结合 Grafana 的 AlertManager 设置规则,比如当 5 分钟内出现 10 次 "OutOfMemoryError" 就触发企业微信通知。
五、技术选型风向标
- 中小团队:直接使用 Docker 内置的
local日志驱动 +logrotate,成本最低 - 混合云环境:
fluentd+Elasticsearch组合最灵活,适配各种存储后端 - K8s 生态:考虑
Loki,它的索引体积比 ES 小 10 倍,查询语法类似 PromQL
日志管理就像城市垃圾分类,初期觉得麻烦,但系统搭建好后,排障效率能提升 80%。曾经有个生产环境 CPU 飙高的问题,通过日志系统的关键字聚合,5 分钟就定位到是某个循环里的正则表达式失控,而传统逐台排查的方式可能需要两小时。
评论