完整的 Docker 日志记录初学者指南

关于登录的知识 码头工人 对于日常系统管理活动非常有帮助,无论是故障排除还是基本监控。 如果不跟踪 Docker 上的日志,则在调查异常时缓解问题将变得更加困难。

这篇文章探讨了该领域的一些重要信息,以便更容易理解如何在 Linux 系统上管理与 Docker 相关的日志文件。

让我从探索最基本的部分开始,然后逐渐深入一些细节。

如何查看 Docker 日志

您可以使用 docker logs 命令以获取正在运行的容器内的服务正在发生的任何事情。

语法很简单:

docker logs container_name_or_ID

您可能已经知道可以使用 docker ps 命令查看正在运行的容器的名称和 ID。

让我们来看一个真实的世界 example. 我已经用 Docker 部署了 Nextcloud。 毫不奇怪,该容器被命名为 nextcloud。

现在,查看名为的容器的日志 nextcloud, 采用:

docker logs nextcloud

这是上述命令输出的截断版本:

172.18.0.2 - - [23/Jul/2021:19:36:09 +0000] "HEAD /.env HTTP/1.1" 302 1571 "-" "python-requests/2.26.0"
172.18.0.2 - - [23/Jul/2021:19:49:52 +0000] "HEAD /c99.php HTTP/1.1" 302 1565 "-" "python-requests/2.26.0"
172.18.0.2 - - [24/Jul/2021:16:25:23 +0000] "HEAD /backup.tar HTTP/1.1" 302 1571 "-" "python-requests/2.26.0"
172.18.0.2 - - [24/Jul/2021:16:25:24 +0000] "HEAD /backup.zip HTTP/1.1" 302 1569 "-" "python-requests/2.26.0"
172.18.0.2 - - [25/Jul/2021:20:36:01 +0000] "GET / HTTP/1.1" 302 1590 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko; compatible; BW/1.1; bit.ly/2W6Px8S) Chrome/84.0.4147.105 Safari/537.36"
172.18.0.2 - - [25/Jul/2021:20:36:07 +0000] "GET /custom_apps/richdocumentscode/proxy.php?req=/hosting/capabilities HTTP/1.1" 200 721 "-" "Nextcloud Server Crawler"
172.18.0.2 - - [25/Jul/2021:20:36:04 +0000] "GET /login HTTP/1.1" 200 7501 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko; compatible; BW/1.1; bit.ly/2W6Px8S) Chrome/84.0.4147.105 Safari/537.36"

日志太多? 好消息是有各种选项可以让查看 docker 日志变得更加容易,就像 Linux 中的日志一样。

跟踪 Docker 日志以仅查看特定数量的行

Docker 日志命令有 --tail 可以以类似于 tail 命令的方式使用的属性。

这意味着,您可以使用它从最后只显示一定数量的 Docker 日志行。

为了 example要查看容器的最后 50 行,可以使用:

docker logs --tail 50 container_name_or_ID

您也可以以这种方式使用上述命令

docker logs -n=50 container_name_or_ID

在活动容器上实时查看 Docker 日志

您完全可以实时查看容器日志。 要“关注”日志,请使用 --follow 或者 -f 属性。

docker logs -f container_name_or_ID

当您使用 follow 选项运行 docker logs 时,您会注意到随着时间的推移,新的日志行将从容器中报告。

要退出,您只需使用 Ctrl+C 组合键并返回到终端提示符。

中的大多数选项 docker logs 可以组合子命令以产生所需的结果。

为了 example, docker logs -f 将从一开始就充满所有日志的屏幕。 你不会想要那个。 您可以做的是将两者结合起来 tailfollow 像这样的选项:

docker logs -f --tail 20 container_name_or_ID

上述命令将显示日志的最后 20 行,然后实时跟踪日志。

通过缩放更新应用容器时,在删除旧容器之前,上述命令会非常有用。

查看 Docker 日志中的时间戳

如果您还想查看日志条目的时间戳,可以使用 -t 选项。

docker logs -t container_name_or_ID

这可以很容易地与其他选项相结合,如 --follow--tail.

下面的命令将显示给定容器的日志文件的最后 10 行,每行都附有时间戳

docker logs -n=10 -t container_name_or_ID

查看指定时间段内的 Docker 日志

在调查问题时,时间可能是一个关键因素,在这种情况下, --since--until 标志可能会非常有帮助。

为了 example,如果您正在调查过去 24 小时内发生的问题,以下命令将显示仅在此期间发生的任何事情的记录内容:

docker logs --since 1440m -t container_name_or_ID

1440m 在上面的命令中表示 24×60 分钟。 添加 -t 或者 --timestamps flag 确保报告的行带有时间戳,以便您更轻松地理解事件或错误。 我建议在查询任何容器时添加它。

同样,如果您在启动部署的前 24 小时后需要日志详细信息,则等效命令为:

docker logs --until 1440m -t nextcloud

除了以分钟为单位指定时间之外,上述两个标志还可以与特定时间戳一起使用 -t 生成。 格式就像 2021-07-28T06:20:00.

docker logs --since 2021-07-28 -t container_name_or_ID

上述命令将显示 2021 年 7 月 28 日的日志。

有关 docker 日志的完整概述,您还可以使用 man docker-logs 查看其手册页。

从容器内访问 Docker 日志

在一些有趣的用例中,您可能希望采用混合方法,从容器中访问特定于应用程序的日志。

为此,您输入 Docker 容器:

docker exec -it container_name_or_ID sh

然后您可以使用常规的 Linux 工具来获取应用程序相关的日志。 一种方法是使用 ps 命令获取所需服务的进程 ID:

ps aux

获取有关此过程的详细信息:

cat /proc/PID_of_process/fd/1

Docker系统服务日志

如果您希望在主机上查看 Docker 服务本身的日志,如果您使用的是 Ubuntu 16.04 或更高版本,则可以使用 journalctl:

sudo journalctl -u docker

Docker 日志存储在哪里?

您应该在 /var/lib/docker/containers 主机系统上的目录。 此目录包含与各个目录中的所有容器相关的日志文件。 您可以使用容器 ID 来识别目录。

我用 docker ps 找到那个 70f19fde9076 是 Nextcloud 容器的容器 ID。

如果我查看存储 docker 日志的目录:

[email protected]:~$ sudo ls -lh /var/lib/docker/containers

total 16K
drwx------ 4 root root 4.0K Jul 27 18:48 0efe12b28562c42619e533ad5f524d56740a7a3739d9e082c758bac95ae2a46f
drwx------ 4 root root 4.0K Jul 27 18:57 12c55f365f93ecb7f91e40bc130ddc2409216a61bbb244cd045a22b4513416d3
drwx------ 4 root root 4.0K Jul 27 18:58 70f19fde907672b9a6e5ff3b7db0c9ecbcb68d419712cb04d03d77694cd2ca4e
drwx------ 4 root root 4.0K Jul 27 18:57 a436399ef16a3efc0a909b9c3f725938e595e0b8fd34644b13f28b2c9bcb4ed7

当前有四个容器在运行,您可以看到第三个与我们需要查看的容器匹配(它以 70f19fde9076)。

如果你检查这个目录的内容,你可以看到我们的日志文件就在那里!

[email protected]:~$ sudo ls -lh /var/lib/docker/containers/70f19fde907672b9a6e5ff3b7db0c9ecbcb68d419712cb04d03d77694cd2ca4e

total 192K
-rw-r----- 1 root root 150K Jul 27 18:58 70f19fde907672b9a6e5ff3b7db0c9ecbcb68d419712cb04d03d77694cd2ca4e-json.log
drwx------ 2 root root 4.0K Jul 19 17:10 checkpoints
-rw------- 1 root root 5.5K Jul 27 18:58 config.v2.json
-rw-r--r-- 1 root root 1.5K Jul 27 18:58 hostconfig.json
-rw-r--r-- 1 root root   13 Jul 27 18:58 hostname
-rw-r--r-- 1 root root  198 Jul 27 18:58 hosts
drwx------ 3 root root 4.0K Jul 19 17:10 mounts
-rw-r--r-- 1 root root   79 Jul 27 18:58 resolv.conf
-rw-r--r-- 1 root root   71 Jul 27 18:58 resolv.conf.hash

因此,对应的日志文件是 70f19fde907672b9a6e5ff3b7db0c9ecbcb68d419712cb04d03d77694cd2ca4e-json.log 这与我运行时正在阅读的文件相同 docker logs 开头的命令。

让我快速验证一下:

[email protected]:~$ sudo cat /var/lib/docker/containers/70f19fde907672b9a6e5ff3b7db0c9ecbcb68d419712cb04d03d77694cd2ca4e/70f19fde907672b9a6e5ff3b7db0c9ecbcb68d419712cb04d03d77694cd2ca4e-json.log

{"log":"172.18.0.2 - - [23/Jul/2021:19:36:09 +0000] "HEAD /.env HTTP/1.1" 302 1571 "-" "python-requests/2.26.0"n","stream":"stdout","time":"2021-07-23T19:36:09.837857567Z"}
{"log":"172.18.0.2 - - [23/Jul/2021:19:49:52 +0000] "HEAD /c99.php HTTP/1.1" 302 1565 "-" "python-requests/2.26.0"n","stream":"stdout","time":"2021-07-23T19:49:52.996108799Z"}
{"log":"172.18.0.2 - - [24/Jul/2021:16:25:23 +0000] "HEAD /backup.tar HTTP/1.1" 302 1571 "-" "python-requests/2.26.0"n","stream":"stdout","time":"2021-07-24T16:25:23.445225166Z"}
{"log":"172.18.0.2 - - [24/Jul/2021:16:25:24 +0000] "HEAD /backup.zip HTTP/1.1" 302 1569 "-" "python-requests/2.26.0"n","stream":"stdout","time":"2021-07-24T16:25:24.772881041Z"}
{"log":"172.18.0.2 - - [25/Jul/2021:20:36:01 +0000] "GET / HTTP/1.1" 302 1590 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko; compatible; BW/1.1; bit.ly/2W6Px8S) Chrome/84.0.4147.105 Safari/537.36"n","stream":"stdout","time":"2021-07-25T20:36:03.678967877Z"}
{"log":"172.18.0.2 - - [25/Jul/2021:20:36:07 +0000] "GET /custom_apps/richdocumentscode/proxy.php?req=/hosting/capabilities HTTP/1.1" 200 721 "-" "Nextcloud Server Crawler"n","stream":"stdout","time":"2021-07-25T20:36:07.404618408Z"}
{"log":"172.18.0.2 - - [25/Jul/2021:20:36:04 +0000] "GET /login HTTP/1.1" 200 7501 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko; compatible; BW/1.1; bit.ly/2W6Px8S) Chrome/84.0.4147.105 Safari/537.36"n","stream":"stdout","time":"2021-07-25T20:36:07.619020402Z"}

日志内容是一样的,但是由于我是直接从主机读取日志文件的,所以这个比较行话很多 docker logs 之前使用的命令。

为 Docker (JSON) 启用日志轮换

默认情况下,对于基于 JSON 文件的日志记录,Docker 上的日志轮换是禁用的。

如果日志文件变得更大,这可能会导致磁盘空间出现问题。 我们基于 Docker 的 Ghost 实例发现其日志文件的大小高达 20 GB。 您可能希望通过启用日志轮换来避免这种情况。

要为 Docker 启用日志轮换,请编辑 /etc/docker/daemon.json 文件:

sudo nano /etc/docker/daemon.json

附加以下行并保存文件:

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

重启 Docker 守护进程:

sudo systemctl restart docker

上述设置当然与通用 Docker 安装相关,默认设置为 JSON 日志记录。 所以请注意,所有其他日志记录机制(如下所列)都有自己的实现轮换的方式。

关于记录驱动程序的简短说明

您是否注意到之前的日志文件名中有“json”? 那是因为 JSON文件 是 Docker 上的默认日志记录驱动程序。

除了 JSON,还有许多其他的日志记录机制可供选择:

对于大规模部署, GELF, AWS, GCP流利的 推荐,因为他们实施集中的方法。 但对于小规模来说, JSON 工作做得很好,而 当地的, 系统日志日记 也相当合适。 系统日志日志存储 如果需要复杂的日志分析,则特别有用。 ETW 是 Windows 特定的,而 斯普伦克 专注于远程日志记录。

从…开始 Docker 引擎 20.10,引入了一个名为“双重日志记录”的新功能,可确保执行 docker logs 命令以及执行日志轮换与有效的日志记录驱动程序无关。

概括

在本文中,我从如何在容器和主机系统级别查看任何 Docker 容器的日志的基础知识开始。 我还向您展示了如何定位驻留在主机系统上的特定于容器的日志文件的物理位置。 我简要地向您展示了如何在主机本身上检查 Docker 服务的日志。

稍后,我讨论了日志记录驱动程序,重点关注默认机制,并强调了新的双日志记录功能。

我希望这些提示对您的日常监控或学习活动有所帮助。 任何更多的想法和建议都非常受欢迎! 请在下面的评论部分分享它们。