彻底搞懂 Kubernetes 中的 Events

彻底搞懂 Kubernetes 中的 Events

作者:张晋涛 2021-12-29 17:29:07

云计算 既然 events 是 Kubernetes 集群中的一种资源,正常情况下它的 metadata.name 中应该包含其名称,用于进行单独操作。

 [[442818]]

之前我写了一篇《更优雅的 Kubernetes 集群事件度量方案》,利用 Jaeger 利用 tracing 的方式来采集 Kubernetes 集群中的 events 并进行展示。最终效果如下:

写那篇文章的时候,立了个 flag 要详细介绍下其中的原理,鸽了很久,现在年底了,也该发出来了。

Eents 概览

我们先来做个简单的示例,来看看 Kubernetes 集群中的 events 是什么。

创建一个新的名叫 moelove 的 namespace ,然后在其中创建一个叫做 redis 的 deployment。接下来查看这个 namespace 中的所有 events。

  1. (MoeLove)  kubectl create ns moelove 
  2. namespace/moelove created 
  3. (MoeLove)  kubectl -n moelove create deployment redis --image=ghcr.io/moelove/redis:alpine  
  4. deployment.apps/redis created 
  5. (MoeLove)  kubectl -n moelove get deploy 
  6. NAME    READY   UP-TO-DATE   AVAILABLE   AGE 
  7. redis   1/1     1            1           11s 
  8. (MoeLove)  kubectl -n moelove get events 
  9. LAST SEEN   TYPE     REASON              OBJECT                        MESSAGE 
  10. 21s         Normal   Scheduled           pod/redis-687967dbc5-27vmr    Successfully assigned moelove/redis-687967dbc5-27vmr to kind-worker3 
  11. 21s         Normal   Pulling             pod/redis-687967dbc5-27vmr    Pulling image "ghcr.io/moelove/redis:alpine" 
  12. 15s         Normal   Pulled              pod/redis-687967dbc5-27vmr    Successfully pulled image "ghcr.io/moelove/redis:alpine" in 6.814310968s 
  13. 14s         Normal   Created             pod/redis-687967dbc5-27vmr    Created container redis 
  14. 14s         Normal   Started             pod/redis-687967dbc5-27vmr    Started container redis 
  15. 22s         Normal   SuccessfulCreate    replicaset/redis-687967dbc5   Created pod: redis-687967dbc5-27vmr 
  16. 22s         Normal   ScalingReplicaSet   deployment/redis              Scaled up replica set redis-687967dbc5 to 1 

但是我们会发现默认情况下 kubectl get events 并没有按照 events 发生的顺序进行排列,所以我们往往需要为其增加 –sort-by='{.metadata.creationTimestamp}’ 参数来让其输出可以按时间进行排列。

这也是为何 Kubernetes v1.23 版本中会新增 kubectl alpha events 命令的原因。

按时间排序后可以看到如下结果:

  1. (MoeLove)  kubectl -n moelove get events --sort-by='{.metadata.creationTimestamp}' 
  2. LAST SEEN   TYPE     REASON              OBJECT                        MESSAGE 
  3. 2m12s       Normal   Scheduled           pod/redis-687967dbc5-27vmr    Successfully assigned moelove/redis-687967dbc5-27vmr to kind-worker3 
  4. 2m13s       Normal   SuccessfulCreate    replicaset/redis-687967dbc5   Created pod: redis-687967dbc5-27vmr 
  5. 2m13s       Normal   ScalingReplicaSet   deployment/redis              Scaled up replica set redis-687967dbc5 to 1 
  6. 2m12s       Normal   Pulling             pod/redis-687967dbc5-27vmr    Pulling image "ghcr.io/moelove/redis:alpine" 
  7. 2m6s        Normal   Pulled              pod/redis-687967dbc5-27vmr    Successfully pulled image "ghcr.io/moelove/redis:alpine" in 6.814310968s 
  8. 2m5s        Normal   Created             pod/redis-687967dbc5-27vmr    Created container redis 
  9. 2m5s        Normal   Started             pod/redis-687967dbc5-27vmr    Started container redis 

通过以上的操作,我们可以发现 events 实际上是 Kubernetes 集群中的一种资源。当 Kubernetes 集群中资源状态发生变化时,可以产生新的 events。

深入 Events

单个 Event 对象

既然 events 是 Kubernetes 集群中的一种资源,正常情况下它的 metadata.name 中应该包含其名称,用于进行单独操作。所以我们可以使用如下命令输出其 name :

  1. (MoeLove)  kubectl -n moelove get events --sort-by='{.metadata.creationTimestamp}' -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' 
  2. redis-687967dbc5-27vmr.16c4fb7bde8c69d2 
  3. redis-687967dbc5.16c4fb7bde6b54c4 
  4. redis.16c4fb7bde1bf769 
  5. redis-687967dbc5-27vmr.16c4fb7bf8a0ab35 
  6. redis-687967dbc5-27vmr.16c4fb7d8ecaeff8 
  7. redis-687967dbc5-27vmr.16c4fb7d99709da9 
  8. redis-687967dbc5-27vmr.16c4fb7d9be30c06 

选择其中的任意一条 event 记录,将其输出为 YAML 格式进行查看:

  1. (MoeLove)  kubectl -n moelove get events redis-687967dbc5-27vmr.16c4fb7bde8c69d2 -o yaml 
  2. action: Binding 
  3. apiVersion: v1 
  4. eventTime: "2021-12-28T19:31:13.702987Z" 
  5. firstTimestamp: null 
  6. involvedObject: 
  7.   apiVersion: v1 
  8.   kind: Pod 
  9.   name: redis-687967dbc5-27vmr 
  10.   namespace: moelove 
  11.   resourceVersion: "330230" 
  12.   uid: 71b97182-5593-47b2-88cc-b3f59618c7aa 
  13. kind: Event 
  14. lastTimestamp: null 
  15. message: Successfully assigned moelove/redis-687967dbc5-27vmr to kind-worker3 
  16. metadata: 
  17.   creationTimestamp: "2021-12-28T19:31:13Z" 
  18.   name: redis-687967dbc5-27vmr.16c4fb7bde8c69d2 
  19.   namespace: moelove 
  20.   resourceVersion: "330235" 
  21.   uid: e5c03126-33b9-4559-9585-5e82adcd96b0 
  22. reason: Scheduled 
  23. reportingComponent: default-scheduler 
  24. reportingInstance: default-scheduler-kind-control-plane 
  25. source: {} 
  26. type: Normal 

可以看到其中包含了很多信息, 这里我们先不展开。我们看另一个例子。

kubectl describe 中的 Events

我们可以分别对 Deployment 对象和 Pod 对象执行 describe 的操作,可以得到如下结果(省略掉了中间输出):

  • 对 Deployment 操作
  1. (MoeLove)  kubectl -n moelove describe deploy/redis                 
  2. Name:                   redis 
  3. Namespace:              moelove 
  4. ... 
  5. Events: 
  6.   Type    Reason             Age   From                   Message 
  7.   ----    ------             ----  ----                   ------- 
  8.   Normal  ScalingReplicaSet  15m   deployment-controller  Scaled up replica set redis-687967dbc5 to 1 
  • 对 Pod 操作
  1. (MoeLove)  kubectl -n moelove describe pods redis-687967dbc5-27vmr 
  2. Name:         redis-687967dbc5-27vmr                                                                  
  3. Namespace:    moelove 
  4. Priority:     0 
  5. Events: 
  6.   Type    Reason     Age   From               Message 
  7.   ----    ------     ----  ----               ------- 
  8.   Normal  Scheduled  18m   default-scheduler  Successfully assigned moelove/redis-687967dbc5-27vmr to kind-worker3 
  9.   Normal  Pulling    18m   kubelet            Pulling image "ghcr.io/moelove/redis:alpine" 
  10.   Normal  Pulled     17m   kubelet            Successfully pulled image "ghcr.io/moelove/redis:alpine" in 6.814310968s 
  11.   Normal  Created    17m   kubelet            Created container redis 
  12.   Normal  Started    17m   kubelet            Started container redis 

我们可以发现 对不同的资源对象进行 describe 的时候,能看到的 events 内容都是与自己有直接关联的。在 describe Deployment 的时候,看不到 Pod 相关的 Events 。

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

结合前面我们看到的单个 Event 对象,我们发现 involvedObject 字段中内容就是与该 Event 相关联的资源对象的信息。

更进一步了解 Events

我们来看看如下的示例,创建一个 Deployment ,但是使用一个不存在的镜像:

  1. (MoeLove)  kubectl -n moelove create deployment non-exist --image=ghcr.io/moelove/non-exist 
  2. deployment.apps/non-exist created 
  3. (MoeLove)  kubectl -n moelove get pods 
  4. NAME                        READY   STATUS         RESTARTS   AGE 
  5. non-exist-d9ddbdd84-tnrhd   0/1     ErrImagePull   0          11s 
  6. redis-687967dbc5-27vmr      1/1     Running        0          26m 

我们可以看到当前的 Pod 处于一个 ErrImagePull 的状态。查看当前 namespace 中的 events (我省略掉了之前 deploy/redis 的记录)

  1. (MoeLove)  kubectl -n moelove get events --sort-by='{.metadata.creationTimestamp}'                                                            
  2. LAST SEEN   TYPE      REASON              OBJECT                           MESSAGE 
  3. 35s         Normal    SuccessfulCreate    replicaset/non-exist-d9ddbdd84   Created pod: non-exist-d9ddbdd84-tnrhd 
  4. 35s         Normal    ScalingReplicaSet   deployment/non-exist             Scaled up replica set non-exist-d9ddbdd84 to 1 
  5. 35s         Normal    Scheduled           pod/non-exist-d9ddbdd84-tnrhd    Successfully assigned moelove/non-exist-d9ddbdd84-tnrhd to kind-worker3 
  6. 17s         Warning   Failed              pod/non-exist-d9ddbdd84-tnrhd    Error: ErrImagePull 
  7. 17s         Warning   Failed              pod/non-exist-d9ddbdd84-tnrhd    Failed to pull image "ghcr.io/moelove/non-exist": rpc error: code = Unknown desc = failed to pull and unpack image "ghcr.io/moelove/non-exist:latest": failed to resolve reference "ghcr.io/moelove/non-exist:latest": failed to authorize: failed to fetch anonymous token: unexpected status: 403 Forbidden 
  8. 18s         Normal    Pulling             pod/non-exist-d9ddbdd84-tnrhd    Pulling image "ghcr.io/moelove/non-exist" 
  9. 4s          Warning   Failed              pod/non-exist-d9ddbdd84-tnrhd    Error: ImagePullBackOff 
  10. 4s          Normal    BackOff             pod/non-exist-d9ddbdd84-tnrhd    Back-off pulling image "ghcr.io/moelove/non-exist" 

对这个 Pod 执行 describe 操作:

  1. (MoeLove)  kubectl -n moelove describe pods non-exist-d9ddbdd84-tnrhd 
  2. ... 
  3. Events: 
  4.   Type     Reason     Age                    From               Message 
  5.   ----     ------     ----                   ----               ------- 
  6.   Normal   Scheduled  4m                     default-scheduler  Successfully assigned moelove/non-exist-d9ddbdd84-tnrhd to kind-worker3 
  7.   Normal   Pulling    2m22s (x4 over 3m59s)  kubelet            Pulling image "ghcr.io/moelove/non-exist" 
  8.   Warning  Failed     2m21s (x4 over 3m59s)  kubelet            Failed to pull image "ghcr.io/moelove/non-exist": rpc error: code = Unknown desc = failed to pull and unpack image "ghcr.io/moelove/non-exist:latest": failed to resolve reference "ghcr.io/moelove/non-exist:latest": failed to authorize: failed to fetch anonymous token: unexpected status: 403 Forbidden 
  9.   Warning  Failed     2m21s (x4 over 3m59s)  kubelet            Error: ErrImagePull 
  10.   Warning  Failed     2m9s (x6 over 3m58s)   kubelet            Error: ImagePullBackOff 
  11.   Normal   BackOff    115s (x7 over 3m58s)   kubelet            Back-off pulling image "ghcr.io/moelove/non-exist" 

我们可以发现,这里的输出和之前正确运行 Pod 的不一样。最主要的区别在于 Age 列。这里我们看到了类似 115s (x7 over 3m58s) 这样的输出。

它的含义表示:该类型的 event 在 3m58s 中已经发生了 7 次,最近的一次发生在 115s 之前

但是当我们去直接 kubectl get events 的时候,我们并没有看到有 7 次重复的 event 。这说明 Kubernetes 会自动将重复的 events 进行合并。

选择最后一条 Events (方法前面内容已经讲了) 并将其内容使用 YAML 格式进行输出:

  1. (MoeLove)  kubectl -n moelove get events non-exist-d9ddbdd84-tnrhd.16c4fce570cfba46 -o yaml 
  2. apiVersion: v1 
  3. count: 43 
  4. eventTime: null 
  5. firstTimestamp: "2021-12-28T19:57:06Z" 
  6. involvedObject: 
  7.   apiVersion: v1 
  8.   fieldPath: spec.containers{non-exist} 
  9.   kind: Pod 
  10.   name: non-exist-d9ddbdd84-tnrhd 
  11.   namespace: moelove 
  12.   resourceVersion: "333366" 
  13.   uid: 33045163-146e-4282-b559-fec19a189a10 
  14. kind: Event 
  15. lastTimestamp: "2021-12-28T18:07:14Z" 
  16. message: Back-off pulling image "ghcr.io/moelove/non-exist" 
  17. metadata: 
  18.   creationTimestamp: "2021-12-28T19:57:06Z" 
  19.   name: non-exist-d9ddbdd84-tnrhd.16c4fce570cfba46 
  20.   namespace: moelove 
  21.   resourceVersion: "334638" 
  22.   uid: 60708be0-23b9-481b-a290-dd208fed6d47 
  23. reason: BackOff 
  24. reportingComponent: "" 
  25. reportingInstance: "" 
  26. source: 
  27.   component: kubelet 
  28.   host: kind-worker3 
  29. type: Normal 

这里我们可以看到其字段中包括一个 count 字段,表示同类 event 发生了多少次。以及 firstTimestamp 和 lastTimestamp 分别表示了这个 event 首次出现了最近一次出现的时间。这样也就解释了前面的输出中 events 持续的周期了。

彻底搞懂 Events

以下内容是从 Events 中随便选择的一条,我们可以看到它包含的一些字段信息:

  1. apiVersion: v1 
  2. count: 1 
  3. eventTime: null 
  4. firstTimestamp: "2021-12-28T19:31:13Z" 
  5. involvedObject: 
  6.   apiVersion: apps/v1 
  7.   kind: ReplicaSet 
  8.   name: redis-687967dbc5 
  9.   namespace: moelove 
  10.   resourceVersion: "330227" 
  11.   uid: 11e98a9d-9062-4ccb-92cb-f51cc74d4c1d 
  12. kind: Event 
  13. lastTimestamp: "2021-12-28T19:31:13Z" 
  14. message: 'Created pod: redis-687967dbc5-27vmr' 
  15. metadata: 
  16.   creationTimestamp: "2021-12-28T19:31:13Z" 
  17.   name: redis-687967dbc5.16c4fb7bde6b54c4 
  18.   namespace: moelove 
  19.   resourceVersion: "330231" 
  20.   uid: 8e37ec1e-b3a1-420c-96d4-3b3b2995c300 
  21. reason: SuccessfulCreate 
  22. reportingComponent: "" 
  23. reportingInstance: "" 
  24. source: 
  25.   component: replicaset-controller 
  26. type: Normal 

其中主要字段的含义如下:

  • count: 表示当前同类的事件发生了多少次 (前面已经介绍)
  • involvedObject: 与此 event 有直接关联的资源对象 (前面已经介绍) , 结构如下:
  1. type ObjectReference struct { 
  2.  Kind string 
  3.  Namespace string 
  4.  Name string 
  5.  UID types.UID 
  6.  APIVersion string 
  7.  ResourceVersion string 
  8.  FieldPath string 
  • source: 直接关联的组件, 结构如下:
  1. type EventSource struct { 
  2.  Component string 
  3.  Host string 
  • reason: 简单的总结(或者一个固定的代码),比较适合用于做筛选条件,主要是为了让机器可读,当前有超过 50 种这样的代码;
  • message: 给一个更易让人读懂的详细说明
  • type: 当前只有 Normal 和 Warning 两种类型, 源码中也分别写了其含义:
  1. // staging/src/k8s.io/api/core/v1/types.go 
  2. const ( 
  3.  // Information only and will not cause any problems 
  4.  EventTypeNormal string = "Normal" 
  5.  // These events are to warn that something might go wrong 
  6.  EventTypeWarning string = "Warning" 

所以,当我们将这些 Events 都作为 tracing 的 span 采集回来后,就可以按照其 source 进行分类,按 involvedObject 进行关联,按时间进行排序了。

总结

在这篇文章中,我主要通过两个示例,一个正确部署的 Deploy,以及一个使用不存在镜像部署的 Deploy,深入的介绍了 Events 对象的实际的作用及其各个字段的含义。

对于 Kubernetes 而言,Events 中包含了很多有用的信息,但是这些信息却并不会对 Kubernetes 造成什么影响,它们也并不是实际的 Kubernetes 的日志。默认情况下 Kubernetes 中的日志在 1 小时后就会被清理掉,以便释放对 etcd 的资源占用。

所以为了能更好的让集群管理员知道发生了什么,在生产环境中,我们通常会把 Kubernetes 集群的 events 也给采集回来。我个人比较推荐的工具是:https://github.com/opsgenie/kubernetes-event-exporter

本文转载自微信公众号「MoeLove」,可以通过以下二维码关注。转载本文请联系MoeLove公众号。

 

文章来源网络,作者:运维,如若转载,请注明出处:https://shuyeidc.com/wp/264741.html<

(0)
运维的头像运维
上一篇2025-05-05 04:19
下一篇 2025-05-05 04:20

相关推荐

  • 个人主题怎么制作?

    制作个人主题是一个将个人风格、兴趣或专业领域转化为视觉化或结构化内容的过程,无论是用于个人博客、作品集、社交媒体账号还是品牌形象,核心都是围绕“个人特色”展开,以下从定位、内容规划、视觉设计、技术实现四个维度,详细拆解制作个人主题的完整流程,明确主题定位:找到个人特色的核心主题定位是所有工作的起点,需要先回答……

    2025-11-20
    0
  • 社群营销管理关键是什么?

    社群营销的核心在于通过建立有温度、有价值、有归属感的社群,实现用户留存、转化和品牌传播,其管理需贯穿“目标定位-内容运营-用户互动-数据驱动-风险控制”全流程,以下从五个维度展开详细说明:明确社群定位与目标社群管理的首要任务是精准定位,需明确社群的核心价值(如行业交流、产品使用指导、兴趣分享等)、目标用户画像……

    2025-11-20
    0
  • 香港公司网站备案需要什么材料?

    香港公司进行网站备案是一个涉及多部门协调、流程相对严谨的过程,尤其需兼顾中国内地与香港两地的监管要求,由于香港公司注册地与中国内地不同,其网站若主要服务内地用户或使用内地服务器,需根据服务器位置、网站内容性质等,选择对应的备案路径(如工信部ICP备案或公安备案),以下从备案主体资格、流程步骤、材料准备、注意事项……

    2025-11-20
    0
  • 如何企业上云推广

    企业上云已成为数字化转型的核心战略,但推广过程中需结合行业特性、企业痛点与市场需求,构建系统性、多维度的推广体系,以下从市场定位、策略设计、执行落地及效果优化四个维度,详细拆解企业上云推广的实践路径,精准定位:明确目标企业与核心价值企业上云并非“一刀切”的方案,需先锁定目标客户群体,提炼差异化价值主张,客户分层……

    2025-11-20
    0
  • PS设计搜索框的实用技巧有哪些?

    在PS中设计一个美观且功能性的搜索框需要结合创意构思、视觉设计和用户体验考量,以下从设计思路、制作步骤、细节优化及交互预览等方面详细说明,帮助打造符合需求的搜索框,设计前的规划明确使用场景:根据网站或APP的整体风格确定搜索框的调性,例如极简风适合细线条和纯色,科技感适合渐变和发光效果,电商类则可能需要突出搜索……

    2025-11-20
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注