排查容器运行日志是 Docker 日常运维中的关键技能。以下是系统化的排查步骤与常用命令。


一、基本命令:docker logs

1. 查看容器标准输出(stdout/stderr)

bash

# 查看完整日志(从容器启动到现在)
docker logs <容器名或ID>

# 实时跟踪日志(类似 tail -f)
docker logs -f <容器名>

# 查看最近的 N 行日志
docker logs --tail 100 <容器名>

# 带时间戳输出
docker logs -t <容器名>

# 查看最近 5 分钟的日志(需要时间戳支持)
docker logs --since 5m <容器名>

注意docker logs 只能查看使用 json-file(默认)或 journald 日志驱动的容器日志。如果容器使用了 nonesyslogfluentd 等驱动,docker logs 可能无输出或报错。


二、进入容器内部查看应用日志文件

很多应用会将日志写入文件(如 /var/log//app/logs/ 等),需要进入容器内部查看:

bash

# 进入容器 shell
docker exec -it <容器名> /bin/bash   # 或 /bin/sh

# 进入后使用常规 Linux 命令查看日志
cat /var/log/app.log
tail -f /var/log/app.log
less /var/log/app.log
grep ERROR /var/log/app.log

# 或者一次性执行(不进入 shell)
docker exec <容器名> tail -100 /var/log/app.log
docker exec <容器名> cat /var/log/app.log | grep "ERROR"

三、检查容器状态与事件

有时容器启动即崩溃,来不及用 docker logs 看到日志。可以:

bash

# 查看容器退出代码和错误摘要
docker ps -a | grep <容器名>
docker inspect <容器名> --format='{{.State.Status}} {{.State.Error}}'

# 查看 Docker 守护进程的事件(包括容器创建、启动、崩溃)
docker events --filter event=die --filter container=<容器名>

四、定位日志文件位置(默认 json-file 驱动)

Docker 默认将容器的 stdout/stderr 写入宿主机的 JSON 文件,通常位于:

bash

/var/lib/docker/containers/<容器完整ID>/<容器完整ID>-json.log

可以直接用 tailgrep 等命令查看(需要 root 或 sudo 权限):

bash

sudo tail -f /var/lib/docker/containers/*/*-json.log | grep <容器名>

注意:直接操作日志文件可能导致 Docker 日志轮转出错,一般推荐优先使用 docker logs


五、限制与轮转日志(避免磁盘爆满)

默认配置下,容器日志会无限增长,可能占满磁盘。通过配置日志驱动来限制:

方法一:运行时设置(全局默认)

编辑 /etc/docker/daemon.json

json

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}

重启 Docker:sudo systemctl restart docker

方法二:单容器启动时指定

bash

docker run -d --log-opt max-size=10m --log-opt max-file=3 --name myapp myimage

方法三:清理现有日志

bash

# 清空特定容器的日志文件(不删除容器)
sudo sh -c "truncate -s 0 /var/lib/docker/containers/*/*-json.log"

# 或使用 docker 命令(需要 1.13+)
docker logs <容器名> > /dev/null 2>&1   # 并不会清空,需配合 truncate

更推荐使用 logrotate 或 Docker 的内置轮转。


六、使用其他日志驱动(生产环境常用)

  • syslog:将所有容器的日志发送到宿主机的 syslog,便于集中管理。

  • fluentd / logstash:将日志发往 Elasticsearch 等分析平台。

  • awslogs(EC2)、gelf(Graylog)等。

配置示例(daemon.json):

json

{
  "log-driver": "fluentd",
  "log-opts": {
    "fluentd-address": "localhost:24224",
    "tag": "docker.{{.Name}}"
  }
}

此时 docker logs 将不可用,需通过对应的日志收集工具查看。


七、结合 Linux 工具进行高级排查

bash

# 实时跟踪并高亮 ERROR
docker logs -f <容器名> | grep --color=always -E "ERROR|$"

# 查看最后100行并过滤出包含 "timeout" 的行
docker logs --tail 100 <容器名> | grep timeout

# 统计错误出现频率
docker logs --since 1h <容器名> | grep -c "NullPointerException"

# 保存日志到文件
docker logs <容器名> > container.log 2>&1

八、常见问题与解决思路

现象 排查步骤
docker logs 无输出 检查容器日志驱动:docker inspect <容器名> | grep LogConfig;尝试 docker exec 查看应用日志文件
日志量巨大导致磁盘满 使用 docker system df 查看占用;清空或轮转日志;设置日志大小限制
容器启动后立即退出 使用 docker logs 或 docker events 查看退出前最后几行输出;尝试交互式启动:docker run -it <镜像> /bin/bash 然后手动运行启动命令
日志显示 no such file or directory 检查挂载卷或配置文件路径是否正确;检查容器内用户权限
容器内无 tail/less/grep 在宿主机上用 docker cp 将日志文件拷出:docker cp <容器>:/app/log/app.log ./

九、最佳实践总结

  1. 默认情况下:优先使用 docker logs -f --tail 200 <容器名> 实时跟踪。

  2. 应用自身日志:建议也输出到 stdout/stderr,同时写入文件,方便 docker logs 和文件持久化两种方式。

  3. 生产环境:使用 json-file 驱动并配置 max-size / max-file,或者采用 fluentd/splunk 等集中日志系统。

  4. 不要手动删除/var/lib/docker/containers下的json.log文件,应使用 truncate 或 Docker 的日志轮转机制。

  5. 容器编排(K8s):使用 kubectl logs <pod> 查看,原理类似。

掌握这些命令和方法,可以快速定位绝大多数容器运行问题。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐