Swarm模式下执行docker service update后service logs丢失错乱问题
Docker服务更新后日志丢失、时序混乱问题解决方案
问题触发条件
- 原Docker服务运行正常,日志可按时间顺序正常打印
- 执行强制更新服务命令:
docker service update --force --image myimageregistry:mytag myservice - 更新完成后执行日志查询命令:
docker service logs myservice
出现如下异常:
- 仅返回部分日志,大量历史日志丢失
- 日志末尾内容不是最新操作生成的日志,时序混乱,呈现旧日志覆盖新日志的表象
- 服务更新过程中实时跟踪(加
-f参数)的终端日志显示正常,但事后重新查询依然出现上述异常
根因分析
该问题由Docker Swarm服务日志的默认存储机制导致:
- Docker Swarm默认使用
json-file日志驱动,每个服务副本的容器日志单独存储在对应运行节点的本地磁盘 - 执行
--force更新时,Swarm会销毁旧的服务副本容器、重建新容器,默认配置下旧容器被删除时,对应的日志文件也会被一并清理 - 实时跟踪日志时能看到完整内容,是因为跟踪会话维持了旧容器日志的输出流,直到旧容器完全销毁,但事后查询只会拉取当前存活副本的日志,已经删除的旧副本日志不会被检索到
- 多节点部署场景下还可能出现日志时序错乱:
docker service logs默认会拉取所有副本的日志但不会做全局排序,不同节点的时钟偏移、日志传输延迟都会导致最终输出的日志顺序不符合实际产生顺序。
解决方案
永久解决方案(推荐)
- 配置集中式日志存储:修改docker daemon配置,将服务日志统一输出到ELK、Loki等集中日志系统,日志存储不受容器生命周期影响
- 调整本地日志驱动配置:如果继续使用本地存储方案,修改对应节点的
/etc/docker/daemon.json配置,开启日志轮转且保留已删除容器的日志,修改后重启docker daemon生效:
{ "log-driver": "json-file", "log-opts": { "max-size": "100m", "max-file": "5", "keep-stopped-containers-logs": "true" } }
临时查询修复方案
- 查询日志时添加
--timestamps(简写-t)参数打印日志时间戳,同时可搭配--since、--until参数限定时间范围,根据时间戳手动排序即可获得正确时序的日志 - 若需要查询已经删除的旧副本日志,可登录到旧容器原运行节点,执行
docker ps -a找到已停止的旧容器ID,通过docker logs <旧容器ID>命令查询对应日志
内容的提问来源于stack exchange,提问作者Guillaume B
相关产品推荐
相关产品推荐

