互联网技术 / 互联网资讯 · 2024年3月20日

深入理解 Kubernetes 中的 Events 对象

此前我写过一篇关于更优雅的 Kubernetes 集群事件度量的文章,利用追踪的思路来采集集群中的 events 并进行展示。现整理原理与实现,供参考。

彻底搞懂 Kubernetes 中的 Events

在写这篇文章时,我定下了一个目标:详细讲解其中的原理。如今年末,这份内容终于整理完毕,与你分享。

概览:Kubernetes 的事件

为了直观理解,我们先从一个简单示例开始,看看 Kubernetes 集群中的 events 是什么样的。

先创建一个命名空间,命名为 MoelOVe(示例用名以便区分),再在其中创建一个名为 Redis 的 Deployment。随后我们查看该命名空间下的所有事件记录。

默认情况下,kubectl get events 输出并不会按事件发生的时间顺序排序,因此常常需要添加 –sort-by=’.{.Metadata.creationTimestamp}’ 这样的参数来实现按时间排序。这也是 Kubernetes v1.23 引入 kubectl alpha events 命令的初衷之一。

排序后的结果能清晰地看到事件的时间线。

单个 Event 对象的深入理解

既然 events 是集群中的一种资源,理论上它的 metadata.name 就是该事件的名称,便于定位和操作。我们可以通过如下命令输出事件的名称:

选择任意一个事件记录,将其以 YAML 进行查看:

kubectl describe 中的 Events

对 Deployment 对象和 Pod 对象分别执行 describe,可以得到如下结果(此处省略中间输出,以便集中理解要点):

发现对不同资源对象执行 describe 时,显示的事件内容与该资源直接相关。对 Deployment 的描述中通常不会包含 Pod 的事件信息。

这说明 Event 对象中包含了其所描述资源对象的信息,它们是有直接联系的。

进一步观察单个 Event,对应的 involvedObject 字段正是与该事件相关联的资源对象信息。

更深入理解 Events

下面的示例创建一个 Deployment,但使用一个不存在的镜像,这样就会进入错误状态:

我们可以看到当前 Pod 处于 ERRImagePull 的状态。查看命名空间中的 events(此处省略了之前部署 Redis 的记录)

对该 Pod 执行 describe:

输出与正常运行的 Pod 不同,最显著的差异在于 Age 列。输出会显示类似 115s 或者 3m58s 的格式,表示该类型的事件在最近的时间段内发生过若干次,最近一次发生在多久之前。

直接执行 kubectl get events 时,往往不会看到重复的多次同类事件,这表明 Kubernetes 会对重复事件进行合并处理。

选取最后一个 Event 并以 YAML 输出:

在输出中你会看到 count 字段,表示同类事件的发生次数;firstTimestamp 和 lastTimestamp 分别表示该事件首次和最近一次出现的时间。于是就能解释前面输出中事件持续出现的原因。

彻底理解 Events

以下是从一个 Event 中抽取的字段示例,帮助理解 Event 的结构和用途:

其中一些字段的含义如下:

因此,当我们把这些 Events 作为追踪的跨度进行采集时,就可以按来源进行分类、按 involvedObject 关联资源、并按时间排序。

总结

本文通过两个示例——一个正确部署的 Deployment 和一个使用不存在镜像的 Deployment——深入讲解了 Events 对象的实际作用及各字段的含义。

对于 Kubernetes 来说,Events 包含了大量有用信息,但并不会直接改变集群状态,它们也不是常规日志。通常在一小时后会被清理,以释放 etcd 的资源。

因此,为了帮助集群管理员了解发生了什么,在生产环境中通常会将 Kubernetes 集群的 events 也进行采集。我个人比较推荐的工具和方案将作为后续分享的内容。

本文为转载整理,来自微信公众号等渠道的背景信息在此致谢。