Docker日志驱动程序

Docker 包含多种日志记录机制,可帮助您 从正在运行的容器和服务中获取信息。这些机制称为日志记录驱动程序。每个 Docker 守护程序都有一个默认的日志记录驱动程序,每个容器都会使用该驱动程序,除非您将其配置为使用不同的日志记录驱动程序,或简称为“日志驱动程序”。

默认情况下,Docker 使用json-file日志记录驱动程序,它在内部将容器日志缓存为 JSON。除了使用 Docker 附带的日志驱动程序之外,您还可以实现和使用日志记录驱动程序插件。

默认情况下,Docker不执行日志轮换。因此,使用默认的json-file日志驱动程序可能会导致大量输出的容器占用大量磁盘空间,可能导致磁盘空间耗尽。(这应该经常发生)

Docker 将 json-file 日志记录驱动程序(没有日志轮换)作为默认设置,以保持与旧版本 Docker 的向后兼容性,以及 Docker 用作 Kubernetes 运行时的情况。

对于其他情况,建议使用local日志记录驱动程序,因为它默认执行日志轮换,并使用更有效的文件格式。请参阅下面的 配置默认日志记录驱动程序 部分以了解如何将local日志记录驱动程序配置为默认值,以及local file logging driver页面获取有关local日志记录驱动程序的更多详细信息。

配置默认日志记录驱动程序

要配置Docker的默认日志记录驱动程序,在daemon.json配置文件中使用log-driver来指定要使用的日志记录驱动程序。更多关于daemon.json配置文件的信息,参考Deamon configuration file

默认的配置是json-file(路径通常为/var/lib/docker/containers/CONTAINER_ID/CONTAINER_ID-json.log)。下面是一个配置示例:

{
  "log-driver": "local"
}

如果日志驱动程序支持个性化配置,可以在daemon.json文件中配置一个名为log-opts的JSON对象。下面是一个json-file驱动程序的配置示例:

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3",
    "labels": "production_status",
    "env": "os,customer"
  }
}

重启Docker来生效配置,新创建的容器会使用新的日志配置,已存在的容器仍然使用原有配置。

daemon.json配置文件中的log-opts配置必须都是字符串,布尔值和数字也必须使用双引号,比如上面的max-file

如果你从未指定日志驱动程序,默认配置是json-file。要获取当前Docker日志驱动程序,使用docker info命令搜索Logging Driver字段。在Linux、macOS、或PowerShell下可以使用下面的命令: docker info --format '{{.LoggingDriver}}'

修改daemon.json文件中日志驱动程序的配置只会影响后续创建的容器。已经存在的容器会保留其创建时使用的日志驱动程序。要升级的话,需要重建容器。

给容器配置日志驱动程序

当你启动容器时,你可以使用--log-driver选项给容器指定单独的日志驱动程序。如果指定的日志驱动程序有个性化配置,可以使用--log-opt <NAME>=<VALUE>来指定。即便是使用默认的日志驱动程序,也可以单独指定个性化配置。

下面的示例使用none日志驱动程序启动了一个Alpine容器。

docker run --it --log-driver none alpine ash

要查看一个正在运行的容器使用的日志驱动程序,可以使用下面的命令:

docker inspect -f '{{.HostConfig.LogConfig.Type}}' <CONTAINER>

配置日志信息从容器到日志驱动的交付模式

Docker提供了两种消息交付模式:

  • (default)direct, blocking delivery from container to driver
  • non-blocking delivery that stores log messages in an intermediate per-container ring buffer for consumption by driver

The non-blocking message delivery mode prevents applications from blocking due to logging back pressure. Applications are likely to fail in unexpected ways when STDERR or STDOUT streams block.

When the buffer is full and a new message is enqueued, the oldest message in memory is dropped. Dropping messages is often preferred to blocking the log-writing process of an application.

The mode log option controls whether to use the blocking (default) or non-blocking message delivery.

The max-buffer-size log option controls the size of the ring buffer used for intermediate message storage when mode is set to non-blocking. max-buffer-size defaults to 1 megabyte.

The following example starts an Alpine container with log output in non-blocking mode and a 4 megabyte buffer:

docker run -it --log-opt mode=non-blocking --log-opt max-buffer-size=4m alpine ping 127.0.0.1

这段大概是说Docker提供了两种日志交付模型,一个阻塞模型一个非阻塞模型。默认使用的是阻塞模型

阻塞模型大概就是STDOUT和STDERR直接往日志驱动里写,但在某些情况下容器可能会在某些情况下挂掉

非阻塞模型在容器和日志驱动中间有一块缓冲区,缓冲区默认大小为1m,日志先往缓冲区写,但缓冲区满了之后缓冲区中最旧的日志会被丢弃

最后那个示例是启动了一个Alpine容器,容器日志使用非阻塞模型,并且指定了日志缓存为4m

将环境变量或标签与日志记录驱动程序一起使用

有些日志驱动会将容器的--env | -e--label记录为日志的一部分。下面是一个示例:
docker run -dit --label production_status=testing -e os=ubuntu alpine sh

如果日志驱动程序支持,会将附加内容作为日志进行输出。下面是json-file日志驱动生成的结果:
"attrs":{"production_status":"testing","os":"ubuntu"}

支持的日志驱动

下面是支持的日志驱动,点击链接查看对应驱动的选项、适用范围。如果你适用“日志驱动插件”,你可能看到更多选项

Driver Description
none 没有日志,docker logs也不返回任何输出。
local 日志以指定格式存储,旨在降低开销
json-file 日志以JSON格式存储,Docker的默认日志驱动
syslog 将日志写入syslog。宿主机上必须有syslog正在运行
journald 将日志写入journald。宿主机上必须有journald正在运行
gelf 将日志写入Graylog Extended Log Format(GELF),比如Graylog 或 Logstash
fluentd 将日志写入fluentd。宿主机上必须有fluentd正在运行
awslogs 将日志写入亚马逊 CloudWatch.
splunk Writes log messages to splunk using the HTTP Event Collector.
etwlogs 将日志写入日志追踪器(仅Windows
gcplogs Writes log messages to Google Cloud Platform (GCP) Logging.
logentries Writes log messages to Rapid7 Logentries.

Docker 19.03 以下,docker logs命令只适用于localjson-filejournald日志驱动,20.10之后,支持所有的日志驱动。参考适用远程日志驱动时读取日志


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!