先记住这个答案
kubelet依据restartPolicy重启容器时,会先等待指数退避时间:首次10秒,随后20秒、40秒……直到封顶300秒。每个容器独立维护计时器,只要该容器某次无故障运行达到10分钟,计时器被清零,下一次重启重新从10秒开始。若每次运行不足10分钟即退出,退避档位会持续累加。
- 退避从10秒起翻倍,上限300秒
- 容器稳定运行10分钟即重置退避
- 只适用于同一节点内kubelet管理的重启
退避档位递增与封顶
kubelet在容器终止后,依据restartPolicy决定是否重启。若允许重启,它不会立即拉起新容器,而是先等待指数退避的延迟。第一次等待固定为10秒,之后每次失败重启延迟翻倍,序列为10秒、20秒、40秒、80秒、160秒,直到触顶300秒。该计时器按单个容器维护,不受Pod内其他容器影响。
退避的计算只与容器本次运行的持续时长相关。官方判定规则是:若容器无问题地“执行满10分钟”,退避计时器即被清零,下一次重启从10秒重新开始;若不到10分钟就退出,则计时器保留,下一次等待沿用未重置的档位。所谓“无问题”指该次执行期间没有触发任何重启条件。
需要注意,退避递增针对的是同一节点上kubelet派发的重启。若Pod被调度到新节点,或容器被删除重建,新实例的kubelet不继承旧档位,会重新从10秒计。因此退避状态仅存在于一个容器的连续重启周期内。
一个触顶300秒的崩溃服务
假设某数据处理Pod的主容器因配置文件路径错误反复崩溃,退出码为1,restartPolicy设为Always。首次启动后1秒失败,kubelet等10秒重启;第二次失败后等20秒;第三次等40秒;第四次等80秒;第五次等160秒;第六次起按上限300秒等待。通过kubectl get pod -o yaml可看到状态里restartCount为5时两个finishedAt的时间差约160秒。
运维修正配置后容器成功启动,但运行8分钟又因OOM退出。由于不满10分钟,退避未重置,下一次重启仍等待300秒。若它随后连续运行超过10分钟,退避清零,此后若再崩溃,等待时间回到10秒。这个机制避免刚恢复的服务背负历史退避包袱。
实际判断退避阶段,可用kubectl get pod -o jsonpath='{.status.containerStatuses[0].lastState.terminated.finishedAt}'结合当前时间计算。更重要的是观察连续两次重启的创建时间戳差值,若从10秒逐步翻倍,即可确认退避策略正常工作。
重置条件与可配置上限
一个常见边界是“稳定运行10分钟”的定义:只要求单次容器执行连续超过600秒且未触发重启,之前有多少失败记录并不影响。如果kubelet自身重启、节点重启或Pod被驱逐,内存中的退避档位会丢失,从而重新从10秒开始。这是缺乏持久化的正常结果,并非系统错误。
在Kubernetes中,kubelet支持在配置文件的crashLoopBackOff.maxContainerRestartPeriod字段调整退避上限,允许值1秒到300秒,默认300秒。该功能自Kubernetes v1.35起为Beta并默认启用。若设置值小于默认起始延迟10秒,则起始延迟也会被钳制为该值,例如设为2秒时所有等待均固定为2秒;设为100秒则仍从10秒翻倍,只是封顶改为100秒。
调小上限可缩短故障恢复时间,但崩溃频繁时会增加日志压力和CPU消耗;调大虽减少重启次数,却延长了服务不可用窗口。运维应根据应用启动时长和外部依赖超时取舍。对启动快的批次任务,设60秒上限可能优于300秒,但生产稳态服务建议保留默认值。
容易答错的地方
- 以为首次重启就固定等5分钟
- 实际退避从10秒起翻倍,只有连续多次快速崩溃后才会触顶300秒。观察连续失败的重启时间戳,前几次通常为10、20、40秒,而非恒定300秒。
- 认为容器启动一次就算成功并重置退避
- 规则要求容器“无问题运行满10分钟”才重置。启动后仅运行几秒或几分钟就退出不满足条件,退避档位会继续累加,直到某次运行时间超过10分钟。
面试官还会怎么问?
restartPolicy为Never时崩溃容器会退避吗?
不会。退避只应用于kubelet根据restartPolicy决定的重启。Never策略下容器退出后不会被重启,因此不产生退避计时。OnFailure则只对非零退出码重启。
容器运行9分钟崩溃和11分钟崩溃,后续重启等待有何不同?
9分钟未达到10分钟阈值,退避计时不清零,下一次仍按当前档位等待,可能早已触顶300秒;11分钟则计时器重置,下一次重启从10秒开始,差距可达290秒。
kubelet配置中调整退避上限的作用范围是什么?
该配置作用于节点上所有容器的重启退避,是kubelet级别而非Pod级别。可设置1秒到300秒,该功能自Kubernetes v1.35起为Beta并默认启用,无需手动开启特性门控。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。