Kubernetes 中有很多需要重试的地方,比如重启 Pod、CSI 的 PVC 挂载重试等。出错重试时通常都会等待一个指数增长的时间,本文就来解析这个等待重试的机制。
Pod 的 CrashLoopBackOff 状态
经常使用 Kubernetes 的朋友应该对 CrashLoopBackOff 不陌生,这是一种较常见的 Pod 异常状态。通常发生在 Pod 内的进程启动失败或意外退出(退出码不为 0),而 Pod 的重启策略为 OnFailure 或 Always,kubelet 重启该 Pod 后。
该状态表示 Pod 在运行失败不断重启的循环中,而 kubelet 每次重启的时候都会等待指数级增长的时间。这个重启等待时间就是通过 backoff 实现的,以下是相关代码:
backoff 的用法
使用 backoff 的方法很简单,只需要用到 .IsInBackOffSince 和 .Next 方法:
以上代码的输出结果:
也可以对特定 id 重新计时:
将所有 id 全部清除:
backoff 的实现原理
backoff 的实现就百来行代码,短小精悍。主结构体内定义了每个 id 对应的任务执行时间和等待时间。
在记录当前执行时间时,将等待时间设置为上一次等待时间乘 2,实现等待时间指数级增长的效果:
判断当前是否需要执行时,只需要判断是否到了等待时间即可: