bigywater.tech
Kubernetes · 22

Event:事件的限流、聚合与保留时间

kubectl describe 最底下那几行 Events 是从哪来的?为什么崩溃的 Pod 每次重启不会让事件越攒越多?这篇用一个反复崩溃的 Pod 观察 Event 对象的 count 递增、两套 API 里的字段、etcd 里的过期机制,以及 Pod 删除之后事件还在的现象。

3→5 / 2→4
100 秒内 Created、Pulled、Started 与 BackOff 事件的 count 变化(Event 对象数量始终是 5 个)
TTL 3660 秒
etcd 里事件 key 绑着的 lease 的时长,Pod 的 key 没有 lease
x5 over 103s
Pod 删除之后 kubectl events --for pod/crash 里 Pulled 一行的重复次数

重复的事件会合并

实测 · 本机执行输出
  20 秒时 kubectl get events -n k16 有 5 个 Event 对象:
    reason=Scheduled  type=Normal   count=1 first=2026-10-10T09:08:37Z last=2026-10-10T09:08:37Z
    reason=Pulled     type=Normal   count=3 first=2026-10-10T09:08:38Z last=2026-10-10T09:08:50Z
    reason=Created    type=Normal   count=3 first=2026-10-10T09:08:38Z last=2026-10-10T09:08:50Z
    reason=Started    type=Normal   count=3 first=2026-10-10T09:08:38Z last=2026-10-10T09:08:51Z
    reason=BackOff    type=Warning  count=2 first=2026-10-10T09:08:40Z last=2026-10-10T09:08:51Z
  100 秒时有 5 个 Event 对象:
    reason=Scheduled  type=Normal   count=1 first=2026-10-10T09:08:37Z last=2026-10-10T09:08:37Z
    reason=Pulled     type=Normal   count=5 first=2026-10-10T09:08:38Z last=2026-10-10T09:10:04Z
    reason=Created    type=Normal   count=5 first=2026-10-10T09:08:38Z last=2026-10-10T09:10:04Z
    reason=Started    type=Normal   count=5 first=2026-10-10T09:08:38Z last=2026-10-10T09:10:05Z
    reason=BackOff    type=Warning  count=4 first=2026-10-10T09:08:40Z last=2026-10-10T09:10:05Z
  同一个 Event 对象(名字不变)count 变大的有 4 个:Pulled 3→5, Created 3→5, Started 3→5, BackOff 2→4

容器 exit 1 后被 kubelet 按退避时间不停重启。20 秒时有 5 个 Event 对象,100 秒时仍然是 5 个——Created、Pulled、Started 从 count=3 涨到 5,BackOff 从 2 涨到 4,名字不变,lastTimestamp 不断更新,firstTimestamp 保持第一次的时间。kubelet 的事件记录器把“同一个来源、同一个对象、同一个原因和消息”的事件合并成一个对象,而不是每次新建一个。

两套 API

实测 · 本机执行输出
  事件对象 crash.18dd1feacbf4fdde(reason=BackOff)
    core/v1:       count=4 firstTimestamp=2026-10-10T09:08:40Z lastTimestamp=2026-10-10T09:10:05Z source={'component': 'kubelet', 'host': 'kx-main-worker2'} reportingComponent=kubelet involvedObject=Pod/crash
    events.k8s.io: eventTime=None series=None deprecatedCount=4 deprecatedFirstTimestamp=2026-10-10T09:08:40Z reportingController=kubelet regarding=Pod/crash
  两套 API 读的是同一份存储:True(uid 相同)

同一个 BackOff 事件从 core/v1 读,count=4、firstTimestamp、lastTimestamp 和 source.component=kubelet 都在顶层;从 events.k8s.io/v1 读,新 API 的 eventTime、series 是空的,这些信息放在 deprecatedCount、deprecatedFirstTimestamp 里,reportingController=kubelet。两者 uid 相同,是同一份存储的两个视图;写 Event 的组件用旧的记录方式,新 API 的 series 就不会有值。

事件什么时候消失

实测 · 本机执行输出
  etcd key /registry/events/k16/crash.18dd1feacbf4fdde:lease=非 0(532aa124d675144d)
  etcdctl lease timetolive:lease 532aa124d675144d granted with TTL(3660s), remaining(3646s)
  对比:一个 Pod 的 key(/registry/pods/kube-system/coredns-559f6c778d-g7z75)的 lease=0(没有过期时间)

etcd 里 /registry/events/… 的每个 key 都绑着一个 lease:etcdctl lease timetolive 显示 granted with TTL(3660s),到点 etcd 自己删除,不需要任何控制器清理;而 Pod 的 key lease=0,永不过期。所以事件只能回溯大约一小时。

Pod 没了,事件还在

实测 · 本机执行输出
  Pod crash 已经删除(Error from server (NotFound): pods "crash" not found);kubectl get events 仍然有 5 个对象,involvedObject 都指向 ['crash']
  kubectl events --for pod/crash:LAST SEEN            TYPE      REASON      OBJECT      MESSAGE | 104s                 Normal    Scheduled   Pod/crash   Successfully assigned k16/crash to kx-main-worker2 | 17s (x5 over 103s)   Normal    Pulled      Pod/crash   Container image "busybox:1.36" already present on machine and can | 17s (x5 over 103s)   Normal    Created     Pod/crash   Container created
  kubectl describe pod crash:Error from server (NotFound): pods "crash" not found

删除 Pod 之后 kubectl get pod 和 kubectl describe pod 都是 NotFound,但 5 个 Event 对象仍在,kubectl events --for pod/crash 能看到完整的时间线(Pulled 一行是 x5 over 103s)。排查“已经被删掉的 Pod 为什么重启”时,事件往往是唯一的线索;而它不是持久的,一小时后就没有了。

分步演示

事件对象
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / kind(Docker 里的单节点或多节点真实集群,节点是 Docker Desktop 虚拟机里的容器)/ kubectl;用空的 kubeconfig 之外的独立 kubeconfig,不碰用户自己的集群;计时用 date +%s%N / kubectl 事件时间戳,数字每次运行会有小幅抖动。三节点 kind 集群 kx-main(Kubernetes v1.37.0);Pod crash 运行 busybox:1.36,命令 sh -c "echo boom; exit 1",默认 restartPolicy Always;事件分别用 kubectl get events -o json 和 kubectl get --raw /apis/events.k8s.io/v1/… 读取;lease 信息用 etcd 静态 Pod 里的 etcdctl get -w json 与 lease timetolive;两次快照在 Pod 创建后约 20 秒和 100 秒;每种情形各一次
    • 没有验证:事件的限流(客户端的 spam filter,同一来源短时间内能发多少事件)与“combined from similar events”聚合;--event-ttl 参数改变后的行为;使用 events.k8s.io 新记录方式的组件(series 有值)的情形;大量事件对 etcd 的压力;Event 的 reportingInstance 在控制器侧的写法;ImagePullBackOff 路径的事件(本机拉不到镜像,每次尝试约 30 秒,节奏太慢)
    京ICP备2026067502号-1京公网安备11010502063487号