目录

Kubernetes事件中心

概述

众所周知 k8s 的 event 存活的时间并不长,因为都会存到 etcd 里的,所以不能一直存着,如果在排查问题的时候,想找找之前的 event,那就必须有旁路的组件逻辑去采集,或者说把 event 按照等级进行告警,并且把具体的 event 接入到企业的告警链路,这样价值就很大了,毕竟现在大部分告警都是基于指标,也就是 Prometheus 的那一套,但是指标归指标,有时候容器真正出现什么问题了,在指标上很难进行转换并且告知到相关负责人,但是 event 就不一样了,event 有具体 message 的信息,在触发产生 Warning 等级的 event 的时候,可以作为告警信息发送出去

event数据结构

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
{
    "apiVersion": "v1",
    "items": [
        {
            "apiVersion": "v1",
            "count": 109050,
            "eventTime": null,
            "firstTimestamp": "2022-01-09T06:26:12Z",
            "involvedObject": {
                "apiVersion": "policy/v1beta1",
                "kind": "PodDisruptionBudget",
                "name": "zk-pdb",
                "namespace": "zookeeper",
                "resourceVersion": "5087419",
                "uid": "36509393-7b93-4cd6-b3bc-bfde71c1e7ca"
            },
            "kind": "Event",
            "lastTimestamp": "2022-02-16T03:11:21Z",
            "message": "No matching pods found",
            "metadata": {
                "creationTimestamp": "2022-01-09T06:26:12Z",
                "name": "zk-pdb.16c8862865eaa160",
                "namespace": "zookeeper",
                "resourceVersion": "26938703",
                "selfLink": "/api/v1/namespaces/zookeeper/events/zk-pdb.16c8862865eaa160",
                "uid": "4380614c-7167-495a-bc07-2edb87fea660"
            },
            "reason": "NoPods",
            "reportingComponent": "",
            "reportingInstance": "",
            "source": {
                "component": "controllermanager"
            },
            "type": "Normal"
        }
    ],
    "kind": "List",
    "metadata": {
        "resourceVersion": "",
        "selfLink": ""
    }
}

可以看到,其实一个 event 的信息并不太详细,如果写入 Kafka/ES 之类的,并且作为平台呈现给用户的时候,那么用户怎么去查对应的事件呢?有点麻烦,当然可以用 involvedObject 这个字段去检索,但是里面的字段其实不太丰富,如果这样直接入库,似乎检索的场景有点有限。

于是很正常的,会想到能不会给 event 也打些标签呢,比如说通过 watch 事件,然后 onAdd 的时候给他打上 pod 的一些 label?问题不大,但是可能要考虑一下,如果集群是比较忙的,会产生很多 event 的,如果每个 event 都这么粗暴的加上一堆 label,那么存入 etcd 肯定会有额外的压力的,相对来说,这可能不是一个特别好的方法。

最后我们在设计事件中心的时候,其实可以在采集或者写入到目标地址前,通过一次 k8s 的客户端的查询,来获取一些 pod 或者其他类型资源对象的 label,或者一些如 ip 之类的信息,组合到即将入库的 event 中,当然这个时候 event 可能是一个 json 或者是事件中心进程内存里的一个对象,加多少 label 也不会对 k8s 集群有什么压力的,当然了,因为需要再查一次 pod 或者 deployment 之类的,这里肯定也会有一些网络开销,但是基本可以忽略不计吧。

警告
本文最后更新于 2020年4月9日,文中内容可能已过时,请谨慎参考。