ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

docker logs 看不到输出?日志驱动与采集方案对比

docker logs 看不到输出?日志驱动与采集方案对比 docker logs 容器名 敲下去空空如也但容器明明在跑、业务也正常。或者反过来应用日志写在某个文件里docker logs 却什么都没有。这是 Docker 日志机制最让人困惑的地方docker logs 只能看到输出到 stdout/stderr 的内容且依赖日志驱动的支持。这篇讲清楚三件事为什么 docker logs 会空、Docker 有哪些日志驱动各自什么行为、以及生产环境怎么做日志采集。为什么 docker logs 是空的四个常见原因按出现频率排原因一应用把日志写进文件而不是 stdout/stderrDocker 的日志机制只捕获进程的标准输出和标准错误。如果你的应用配置了 logback/log4j 写 /var/log/app.log 或者 Windows 风格的路径这些内容进了容器文件系统不会进 docker logs。验证docker logs app # 空 docker exec app ls -la /var/log/ # 发现 app.log 在涨 docker exec app tail -f /var/log/app.log # 日志其实在这里解法把应用日志改成输出到 stdout。logback 示例appender nameCONSOLE classch.qos.logback.core.ConsoleAppender encoder pattern%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n/pattern /encoder /appender root levelINFO appender-ref refCONSOLE/ /root容器化应用的日志最佳实践就是写 stdout让 Docker/编排平台去收集而不是应用自己管文件。原因二日志驱动不是 json-file/localdocker logs 不支持docker logs 命令只对这些驱动有效json-file、local、journald部分。如果 daemon 或容器配了 syslog、fluentd、gelf、awslogs 等驱动日志被发往外部系统docker logs 直接报Error response from daemon: configured logging driver does not support reading或者返回空。查看当前驱动docker inspect 容器名 --format {{.HostConfig.LogConfig.Type}} # 输出如json-file / syslog / none如果输出 none日志被完全丢弃docker logs 必然空。原因三服务以 daemon 模式跑没有前台输出有些服务默认后台运行daemonize主进程 fork 后退出或脱离终端stdout 没有持续输出。典型是 nginx 默认 daemon on;。容器里跑 nginx 官方镜像没问题镜像里改了配置但自己打包的服务如果 daemonize 了docker logs 就看不到东西而且容器可能因为主进程退出而停掉。解法让服务前台跑。nginx 配置加 daemon off;很多服务有 --foreground / -f 参数。原因四输出被缓冲没 flushPython、Node 等语言默认对非终端的 stdout 做块缓冲日志攒在缓冲区没写出去docker logs 暂时看不到进程退出或缓冲满才刷出来。解法# Python 关闭缓冲 docker run -e PYTHONUNBUFFERED1 myapp # 或 python -u app.py # Node 一般行缓冲问题少但用 pm2 等托管时注意其日志重定向 # 通用stdbuf 强制行缓冲 stdbuf -oL -eL your-commandDocker 日志驱动对比Docker 支持多种日志驱动daemon.json 全局配或容器级 --log-driver 覆盖驱动docker logs 可读去向适用json-file✅容器 JSON 文件默认开发/单机默认选择local✅本地高效格式文件单机比 json-file 省空间journald✅部分systemd journal用 systemd 管理的宿主机syslog❌syslog 守护进程传统 syslog 体系gelf❌Graylog 等 GELF 端点Graylog 栈fluentd❌fluentd 收集器Fluentd/EFK 栈awslogs❌CloudWatchAWS 环境none❌丢弃明确不要日志关键认知除了 json-file / local / journald其他驱动下 docker logs 都读不到——日志去了外部系统要去那里查。这不是故障是设计。json-file 的坑默认不轮转不限量日志能写满磁盘。务必配轮转daemon.json{ log-driver: json-file, log-opts: { max-size: 100m, max-file: 3 } }local 驱动格式更紧凑、性能更好同样支持 max-size 轮转单机场景比 json-file 更优{ log-driver: local, log-opts: { max-size: 100m, max-file: 3 } }容器级覆盖与查看全局驱动在 daemon.json单个容器可以覆盖docker run -d --log-driver json-file --log-opt max-size50m --name app myapp:1.0Composeservices: app: image: myapp:1.0 logging: driver: json-file options: max-size: 50m max-file: 3查看容器实际生效的日志配置docker inspect 容器名 --format {{.HostConfig.LogConfig.Type}} {{json .HostConfig.LogConfig.Config}}生产环境日志采集方案单机 docker logs / json-file 够用但多节点生产环境需要集中采集。主流三条路线路线一日志驱动直发push 模式容器日志驱动直接配成 fluentd / gelf / syslog / awslogs日志产生即发往收集端不落地或短暂落地。{ log-driver: fluentd, log-opts: { fluentd-address: localhost:24224, tag: docker.{{.Name}} } }优点实时、不占本地磁盘。缺点收集端挂了日志可能丢取决于驱动缓冲配置且 docker logs 不可用排查不便。路线二文件采集pull 模式sidecar / agent应用日志写 stdoutjson-file 落地或写挂载出来的日志目录宿主机上跑 Filebeat / Promtail / Vector 等 agent tail 文件发往 ES / Loki / ClickHouse。# Compose 把日志目录挂出来给 agent 采 services: app: volumes: - ./logs:/var/log/app优点日志先落地再采集收集端故障不丢docker logs 仍可用json-file。缺点占本地磁盘需轮转、多一层 agent。路线三编排层集成K8s 环境直接用集群日志方案如 EFK、Loki Promtail DaemonSet容器 stdout 由 kubelet 落到节点文件再被采集。Docker 单机场景不适用但思路同源应用写 stdout平台负责收集。选型建议单机/小团队json-file 轮转 需要时 docker logs最简单已有 Grayloggelf 驱动直发已有 EFK/Loki文件采集pull或 fluentd 直发push看是否容忍丢日志原则不变应用一律写 stdout把怎么收集交给平台应用不操心文件轮转和路径排查决策表现象优先怀疑第一条命令docker logs 全空但应用在跑日志写文件没写 stdoutdocker exec app ls /var/log/报 does not support reading驱动非 json-file/localdocker inspect --format {{.HostConfig.LogConfig.Type}}日志延迟出现输出缓冲加 PYTHONUNBUFFERED1 / -u / stdbuf容器一起动就没了日志且容器停服务 daemonize改前台daemon off / --foreground日志把磁盘写满json-file 无轮转daemon.json 配 max-size/max-file小结docker logs 空不是玄学四个原因应用写文件没写 stdout、日志驱动不支持读syslog/fluentd/gelf/none、服务 daemonize 没有前台输出、输出被缓冲没 flush。驱动选择上开发单机用 json-file 或 local记得配轮转生产集中采集按已有栈选 gelf/fluentd 直发或 Filebeat/Promtail 文件采集。无论哪条路线应用日志写 stdout是容器化的第一原则——把收集、轮转、转发都交给平台应用只负责把日志吐到标准输出。记住这条主线日志问题就从为什么看不到变成去哪里看思路立刻清晰。
返回列表