理解k8s中的事件及其原理 概述 事件原理 事件管理机制 扩

这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战

pexels-gratisography-2007
概述
==

在k8s中事件就像信鸽一样,将各个组件发生的事情发送给apiserver,然后apiserver又会将这些信心存储到etcd中,以供有需要的人来查询集群所发生的事情。

事件在k8s中也是一种资源,用于表示集群内发生的情况。由于事件的数量可能会非常庞大,为了防止打爆存储系统,k8s会强制清理一小时之前的事件。

另外一点需要说明的是事件是单纯的用于系统诊断用的,k8s控制器不会基于事件来触发任何行为,也因此k8s清理一小时之前的事件并不会有任何副作用,可以放心清理。

事件实例

Kubernetes的每一个组件都会发出事件,这些事件就是一个要告诉你组件内部发生了什么的小信息。大部分用过Kubernetes的人都已经看到一些“kubectl describe”输出尾部的事件信息。例如:

1
2
3
4
5
6
7
8
9
10
11
sh复制代码$ kubectl describe pod/podinfo-9f56d4b58-2jj8z
Name: podinfo-9f56d4b58-2jj8z
Namespace: default
Node: ...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 42s default-scheduler Successfully assigned default/podinfo-9f56d4b58-2jj8z to node1
Normal Pulled 41s kubelet Container image "ghcr.io/stefanprodan/podinfo:5.1.2" already present on machine
Normal Created 41s kubelet Created container podinfod
Normal Started 41s kubelet Started container podinfod

这些事件告诉了你一个小故事:首先,一个pod被分配到了一个节点,接着那个节点的kubelet开始了一系列的操作:拉取镜像、创建容器并且启动它。”kubectl describe”按照从旧到新的方式输出事件,这是因为最近发生的事情一般最让人感兴趣。

这是另外一个例子,我们将镜像地址改成”example“,一个不存在的地址。

1
2
3
4
5
6
7
8
sh复制代码Type     Reason     Age            From               Message
---- ------ ---- ---- -------
Normal Scheduled 22s default-scheduler Successfully assigned default/podinfo-5487f6dc6c-gvr69 to node1
Normal BackOff 20s kubelet Back-off pulling image "example"
Warning Failed 20s kubelet Error: ImagePullBackOff
Normal Pulling 8s (x2 over 22s) kubelet Pulling image "example"
Warning Failed 6s (x2 over 20s) kubelet Failed to pull image "example": rpc error: code = Unknown desc = failed to pull and unpack image "docker.io/library/example": failed to resolve reference "docker.io/library/example§": pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed
Warning Failed 6s (x2 over 20s) kubelet Error: ErrImagePull

你将会看到最后三行都有”x2”,这是因为Kubernetes会把重复发生的事件合并到一起。例如“Age: 6s (x2 over 20s)”,意思是最近发生的事件发生在6s之前,而第二次发生在20s之前。

第二天再来看这个pod,我得到这样的信息

1
2
3
4
sh复制代码Type     Reason   Age                     From     Message
---- ------ ---- ---- -------
Normal BackOff 19m (x4524 over 17h) kubelet Back-off pulling image "example"
Warning Failed 4m18s (x4591 over 17h) kubelet Error: ImagePullBackOff

这表明,一方面kubelet的执行策略,17个小时之后依然在尝试执行,另一方面,Kubernetes也会关注资源的使用情况,一个小时之后的事件会被自动删除。也就是说我们不能再看的那些错误的详细信息了。

事件的用处

如果你不知道哪里去找一个具体的问题,你可能需要查看所有的事件。

1
2
3
4
5
6
7
8
9
sh复制代码$ kubectl get events -A
NAMESPACE LAST SEEN TYPE REASON OBJECT MESSAGE
...
default 46s Normal Scheduled pod/podinfo-78bbb69b79-wfzrk Successfully assigned default/podinfo-78bbb69b79-wfzrk to kind-control-plane
default 46s Normal Pulled pod/podinfo-78bbb69b79-wfzrk Container image "ghcr.io/stefanprodan/podinfo:5.1.1" already present on machine
default 46s Normal Created pod/podinfo-78bbb69b79-wfzrk Created container podinfod
default 46s Normal Started pod/podinfo-78bbb69b79-wfzrk Started container podinfod
default 47s Normal SuccessfulCreate replicaset/podinfo-78bbb69b79 Created pod: podinfo-78bbb69b79-wfzrk
default 47s Normal ScalingReplicaSet deployment/podinfo Scaled up replica set podinfo-78bbb69b79 to 1

现在你可以看到关于Pod、ReplicaSet和Deployment的不同的事件都在滚动列出。

注意:”kubectl get events” 可能会输出大量信息,特别是集群非常繁忙时。令人头疼的是事件并不是按照时间戳排列的,因此你需要有办法来寻找或者将这些信息输出到文件中进行分析。

时间的命名方式为: “InvoledObject对象名称”+”.”+”事件创建纳秒时间戳”

1
go复制代码fmt.Sprintf("%v.%x", ref.Name, t.UnixNano())

一般事件本身的命名意义不是很大,而其产生对象的名称更有意义,通过这个名称来查询它所发生的事件,当然也可能查不到,因为事件超过一个小时就会被删除。

事件原理

事件结构

Kubernetes使用对象模型存储事件,正如Deployment和Pod那样。我们通过kubectl来看一下Event的内部信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
yaml复制代码$ kubectl get event/podinfo-84b5bccbfd-rgb42.166185b1cd1dc668 -o yaml
apiVersion: v1
kind: Event
metadata:
name: podinfo-84b5bccbfd-rgb42.166185b1cd1dc668
namespace: default
type: Normal
count: 4636
firstTimestamp: "2021-02-07T16:59:00Z"
lastTimestamp: "2021-02-08T10:39:04Z"
message: Back-off pulling image "example"
reason: BackOff
source:
component: kubelet
host: node1
involvedObject:
apiVersion: v1
kind: Pod
name: podinfo-84b5bccbfd-rgb42
namespace: default

正如你所看到的,每一个事件都是一个对象,属于一个命名空间,拥有一个唯一的名字,其他主要字段详述如下:

  • Count,firstTimestamp和lasteTimestamp 表示事件重复了多少次
  • Message 人类可读的文本信息
  • Reason 简短的编码,可用于过滤器
  • Type Normal或者Warning
  • Source 事件发出的来源
  • InvolvedObject 引用的另一个Kubernetes对象,例如Pod或者Deployment

现在我们清楚了,通过kubectl describe展示的事件列表,正是InvoledObject匹配的事件。

事件管理机制

Event事件管理主要包含三部分:

  • EventRecorder:事件生成器,k8s组件通过调用它的方法来生成事件;
  • EventBroadcaster:事件广播器,负责消费EventRecorder产生的事件,然后分发给broadcasterWatcher;
  • broadcasterWatcher:用于定义事件的处理方式,如上报apiserver;

事件管理的整体流程如下:

image-20201011221745830
扩展阅读
====

www.kubernetes.org.cn/1031.html这是一个系列文章,分为上中下三篇,从浅入深以通俗的方式讲解了k8s的事件机制,值得一看。

kubernetes.io/docs/tasks/… 官方文档,介绍了如何通过事件调试应用程序,推荐查阅,并最好实际操作一下

www.bluematador.com/blog/kubern… 详细解释了事件使用

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%