如何查看 Docker 安装的事件历史记录

已发表: 2022-08-11

码头工人标志

每当守护进程执行重要操作时,Docker 引擎都会记录一个事件。 您可以访问事件日志以识别操作发生的时间并跟踪对象随时间的变化。

在本文中,我们将解释作为事件捕获的内容以及您可能希望在何时查看它们。 然后,我们将展示如何使用 Docker CLI 和 REST API 实时监控事件。

什么是 Docker 事件?

Docker 事件描述了 Docker 守护进程所执行的活动。 大多数与容器、图像、卷和网络等对象的交互都会记录一个事件,创建一个日志,您可以使用它来检查过去的更改。

有许多不同类型的事件可以识别环境中的特定变化:

  • 创建和删除容器
  • 容器健康检查状态
  • 使用docker exec在容器内执行的命令
  • 拉取和推送图像
  • 创建、销毁、挂载和卸载卷
  • 启用和禁用 Docker 守护程序插件

您可以在 Docker 的文档中查看完整列表。

每个记录的事件都包含一个时间戳和受影响对象的 ID。 您可以使用此信息来收集环境更改的历史记录,无论您是否观察到它们的原始触发器。

存储的事件还可以帮助诊断问题,例如意外的容器故障。 查看日志可让您确定容器停止的准确时间,并提供可以与其他日志关联的数据点。 事件可以确定容器的健康检查何时开始失败,从而缩小您需要检查外部服务以确定问题根本原因的时间。

使用 Docker CLI 流式处理 Docker 事件

docker events CLI 命令将事件从 Docker 守护程序流式传输到终端窗口。 事件将实时显示,直到您通过按 Ctrl+C 键盘组合终止进程。

运行不带参数的命令将不会显示任何输出。 仅显示新活动,因此输出保持为空,直到事件发生。 您可以通过在不同的 shell 中启动一个新容器来激发一个:

 $ docker run --rm hello-world

现在,运行docker events命令的终端窗口中应该出现几个事件:

 2022-05-31T15:20:00.267970018+01:00 图像拉 hello-world:latest (name=hello-world)
2022-05-31T15:20:00.347054862+01:00 容器创建 4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378(图像=hello-world,名称=nifty_morse)
2022-05-31T15:20:00.347805277+01:00 容器附加 4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378(图像=hello-world,名称=nifty_morse)
2022-05-31T15:20:00.621070053+01:00 容器启动 4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378(图像=hello-world,名称=nifty_morse)
...

每个事件都显示在自己的行上。 首先显示事件时间戳,然后是受影响对象的类型(例如imagecontainer ),然后是执行的操作(例如createattachstart )。 消息的其余部分包含有关对象的有用元数据。 上面的示例显示hello-world:latest图像已被拉取,并从中创建了一个容器。

格式化输出

原始事件列表通常很笨重。 您可以使用接受 Go 模板字符串的--format标志重新格式化输出:

 $ docker events --format '{{ .Time }} {{ .Action }} {{ .Type}} {{ .ID }}'

运行此示例将产生如下所示的输出:

 1654006800 拉图像 hello-world:latest
1654006800 创建容器 4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378
1654006800 附加容器 4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378
1654006800 启动容器 4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378

您可以使用{{ json . }} {{ json . }}作为您的模板字符串:

 $ docker events --format '{{ json . }}' | jq
{
  “状态”:“创建”,
  “id”:“4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378”,
  “来自”:“你好世界”,
  “类型”:“容器”,
  “行动”:“创造”,
  “演员”:{
    "ID": "4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378",
    “属性”: {
      “图像”:“你好世界”,
      “名称”:“nifty_morse”
    }
  },
  “范围”:“本地”,
  “时间”:1654006800,
  “时间纳米”:1654006800347054800
}

这里原始 JSON 正在通过jq传递,因此它可以很好地打印在您的终端中。 这使信息更易于浏览。

创建自定义格式字符串时,您可以使用 JSON 输出中的属性作为受支持占位符的参考。 在大多数情况下,您需要将每个属性的第一个字母大写,例如time to {{ .Time }}

过滤事件

繁忙的 Docker 守护进程的事件日志很快就会变得嘈杂。 您可以使用--filter标志将事件缩小到特定的操作、对象或对象类型:

  • docker events --filter type=container – 获取与容器相关的所有事件。
  • docker events --filter event=create – 获取容器创建事件。
  • docker events --filter container=demo-container – 获取为名为demo-container的容器保存的所有事件(您可以引用容器的 ID 或名称)。

除了container之外,您还可以按所有受支持的对象类型名称进行过滤,例如imagenetworkvolume

重复--filter标志时支持多个过滤器。 不同的过滤器被解释为逻辑条件; 同一过滤器的多次使用成为OR子句。 这是一个为app-containerapi-container容器显示create事件的示例:

 $码头事件\
    --filter 容器=应用程序容器
    --filter 容器=api-容器
    --过滤事件=创建

访问历史事件

docker events默认只显示自命令运行以来存储的事件。 您可以通过添加--since标志来包含历史事件。 这接受人类可读的时间表达式或绝对时间戳:

 $ docker events --since 1h
$ docker events --since '2021-05-01T16:00:00'

在给定时间之后记录的事件将立即显示在您的终端中。 新事件将在记录时继续实时显示。

您可以使用--until标志在特定时间之后排除事件。 它的工作原理类似于--since 。 使用--until将禁用新事件的实时流,因为它们会超出请求的时间范围。

从守护进程 REST API 流式处理 Docker 事件

访问存储事件的另一种方法是通过 Docker 守护程序 REST API。 在 Docker 主机上启用 API 后,您可以使用/events端点实时流式传输事件。 事件将以 JSON 格式返回:

 $ 卷曲 http://127.0.0.1:2375/v1.41/events
{
  “类型”:“容器”,
  “行动”:“创造”,
  “演员”:{
    "ID": "4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378",
    “属性”: {
      “图像”:“你好世界”,
      “名称”:“nifty_morse”
    }
  },
  “范围”:“本地”,
  “时间”:1654006800,
  “时间纳米”:1654006800347054800
}

API 端点支持与 CLI 对应项具有相同行为的filtersinceuntil参数。 以下是检索过去一小时内记录的所有容器创建事件的方法:

 $ curl http://127.0.0.1:2375/v1.41/events?since=1h&filters={'type':'container','action':'create'}

向外部服务发送事件

Docker 缺乏将事件发送到外部服务的内置方式。 如果您希望所有容器创建都记录在现有的监控或审计平台中,这可能会很有用。

您可以通过创建持续运行docker events的系统服务来设置自己的解决方案。 它应该将每一行新的输出发送到您的外部系统。

首先编写一个实现所需功能的 Bash 脚本:

 #!/bin/bash
docker events --format '{{ .Time }} {{ .Action }} {{ .Type }} {{ .ID }}' | 读取事件时
做
    卷曲\
        -X 发布\
        -H“内容类型:应用程序/json”\
        -d'{“事件”:“$事件”}'\
        https://example.com/events
完毕

现在在/etc/systemd/system/docker-events.service创建一个新的systemd服务单元:

 [单元]
描述=自定义 Docker 事件监控服务

[服务]
类型=分叉
ExecStart=/usr/local/bin/docker-events.sh

[安装]
WantedBy=多用户.target

最后重新加载systemd以加载您的服务,然后启动并启用该单元:

 $ sudo systemctl 守护进程重载
$ sudo systemctl 启动泊坞窗事件
$ sudo systemctl 启用泊坞窗事件

您的服务现在会将每个新事件流式传输到您的监控平台。 启用该服务会将其配置为在您的主机每次重新启动时自动启动。

概括

每当守护程序修改环境中的对象时,都会创建 Docker 事件。 流式传输事件日志可让您实时监控守护程序活动。 这可以帮助您调试问题、审核更改并确保合规性。

由于事件是直接从 Docker 服务器检索的,因此如果您将来需要检索信息,则不应依赖它们。 仅滚动保留 1,000 个条目,您无法通过 Docker 主机的文件系统访问事件。 该机制最适合您正在寻找与最近活动相关的特定信息的快速临时任务。 对于长期保留,您应该使用自己的系统服务将事件发送到外部存储库。