这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战
概述
在k8s中事件就像信鸽一样,将各个组件发生的事情发送给apiserver,然后apiserver又会将这些信心存储到etcd中,以供有需要的人来查询集群所发生的事情。
事件在k8s中也是一种资源,用于表示集群内发生的情况。由于事件的数量可能会非常庞大,为了防止打爆存储系统,k8s会强制清理一小时之前的事件。
另外一点需要说明的是事件是单纯的用于系统诊断用的,k8s控制器不会基于事件来触发任何行为,也因此k8s清理一小时之前的事件并不会有任何副作用,可以放心清理。
事件实例
Kubernetes的每一个组件都会发出事件,这些事件就是一个要告诉你组件内部发生了什么的小信息。大部分用过Kubernetes的人都已经看到一些“kubectl describe"输出尾部的事件信息。例如:
$ 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“,一个不存在的地址。
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,我得到这样的信息
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也会关注资源的使用情况,一个小时之后的事件会被自动删除。也就是说我们不能再看的那些错误的详细信息了。
事件的用处
如果你不知道哪里去找一个具体的问题,你可能需要查看所有的事件。
$ 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对象名称"+"."+"事件创建纳秒时间戳"
fmt.Sprintf("%v.%x", ref.Name, t.UnixNano())
一般事件本身的命名意义不是很大,而其产生对象的名称更有意义,通过这个名称来查询它所发生的事件,当然也可能查不到,因为事件超过一个小时就会被删除。
事件原理
事件结构
Kubernetes使用对象模型存储事件,正如Deployment和Pod那样。我们通过kubectl来看一下Event的内部信息。
$ 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;
事件管理的整体流程如下:
扩展阅读
www.kubernetes.org.cn/1031.html这是一个系列文章,分为上中下三篇,从浅入深以通俗的方式讲解了k8s的事件机制,值得一看。
kubernetes.io/docs/tasks/… 官方文档,介绍了如何通过事件调试应用程序,推荐查阅,并最好实际操作一下
www.bluematador.com/blog/kubern… 详细解释了事件使用