注:本文已发布超过一年,请注意您所使用工具的相关版本是否适用
最近我们踩了一个之前很难遇到的坑,k8s 集群内同时并发运行的 job 2000+,一个 job 只有一个 Pod,一次运行一般 1 - 2min 就可以结束,但是线上数据统计发现每分钟新增的数据只有几十条,这个很不符合常理,关键是还没有报错。
因为我们的 job 很多,加上已完成未删除的 job 有上万个同时存在,并且 controller 会根据 cr 的需求不断地增删对应的 job,所以排查起来相对比较困难。
最后发现有一个 job 执行了 3h 都还没有执行完毕,这个成功的引起了我的注意,查看发现这个 job 的确没有完成,并且这个 job 关联的 pod 才刚刚创建,job 的信息里面也只有一个 active: 1 并没有失败的 job 出现
然后去腾讯云查看 k8s 的审计日志,离谱的事情来了

这个 job 对应的 pod 被 pod gc 删除了 50 次,然后查看上线服务的日志也发现存在大量的重复数据上报请求被丢弃掉了。
省流版: 来自官网的温馨提示
Job 控制器(Controller) 依靠计算集群中存在的 Pod 来跟踪作业状态。 也就是说,维持一个统计
succeeded和failed的 Pod 的计数器。 然而,Pod 可以因为一些原因被移除,包括:
- 当一个节点宕机时,垃圾收集器会删除孤立(Orphan)Pod。
- 垃圾收集器在某个阈值后删除已完成的 Pod(处于 `Succeeded` 或 `Failed` 阶段)。
- 人工干预删除 Job 的 Pod。
- 一个外部控制器(不包含于 Kubernetes)来删除或取代 Pod。
看一下源码 pkg/controller/podgc/doc.go 中的说明
1 | |
简单翻译一下就是,当已结束状态(Failed or Succeeded)的 Pod 的数量 > 配置的值的时候,Pod Gc Controller 就会按照创建时间从远往近开始删除已结束状态的 Pod
后面单独出一篇文章分析 Pod Gc,这里简单看一下 gcTerminated 部分的代码
1 | |
我们可以看到这个删除逻辑也是非常的简单粗暴了,只要超过数量然后就开始删除,但是这个有个问题是,我们现在 terminated pod 数量比 terminatedPodThreshold 这个值大,并且还有 controller 在反复创建 job,这就会导致 pod gc 频繁工作导致 job 一直无法完成了
回顾一下这个坑,其实早有预兆,但是机会给了一次次没有及时抓住最后还是跳了下去
最后一个 github 查看源码的 tips,现在只要把 github.com 改成 github.dev 就能直接用 vscode web 版本查看仓库代码,并且还支持代码跳转,文中的所有源码链接都是 github.dev 的链接,可以体验一下

注:本文已发布超过一年,请注意您所使用工具的相关版本是否适用
最近我们踩了一个之前很难遇到的坑,k8s 集群内同时并发运行的 job 2000+,一个 job 只有一个 Pod,一次运行一般 1 - 2min 就可以结束,但是线上数据统计发现每分钟新增的数据只有几十条,这个很不符合常理,关键是还没有报错。
因为我们的 job 很多,加上已完成未删除的 job 有上万个同时存在,并且 controller 会根据 cr 的需求不断地增删对应的 job,所以排查起来相对比较困难。
最后发现有一个 job 执行了 3h 都还没有执行完毕,这个成功的引起了我的注意,查看发现这个 job 的确没有完成,并且这个 job 关联的 pod 才刚刚创建,job 的信息里面也只有一个 active: 1 并没有失败的 job 出现
然后去腾讯云查看 k8s 的审计日志,离谱的事情来了

这个 job 对应的 pod 被 pod gc 删除了 50 次,然后查看上线服务的日志也发现存在大量的重复数据上报请求被丢弃掉了。
省流版: 来自官网的温馨提示
Job 控制器(Controller) 依靠计算集群中存在的 Pod 来跟踪作业状态。 也就是说,维持一个统计
succeeded和failed的 Pod 的计数器。 然而,Pod 可以因为一些原因被移除,包括:
- 当一个节点宕机时,垃圾收集器会删除孤立(Orphan)Pod。
- 垃圾收集器在某个阈值后删除已完成的 Pod(处于 `Succeeded` 或 `Failed` 阶段)。
- 人工干预删除 Job 的 Pod。
- 一个外部控制器(不包含于 Kubernetes)来删除或取代 Pod。
看一下源码 pkg/controller/podgc/doc.go 中的说明
1 | |
简单翻译一下就是,当已结束状态(Failed or Succeeded)的 Pod 的数量 > 配置的值的时候,Pod Gc Controller 就会按照创建时间从远往近开始删除已结束状态的 Pod
后面单独出一篇文章分析 Pod Gc,这里简单看一下 gcTerminated 部分的代码
1 | |
我们可以看到这个删除逻辑也是非常的简单粗暴了,只要超过数量然后就开始删除,但是这个有个问题是,我们现在 terminated pod 数量比 terminatedPodThreshold 这个值大,并且还有 controller 在反复创建 job,这就会导致 pod gc 频繁工作导致 job 一直无法完成了
回顾一下这个坑,其实早有预兆,但是机会给了一次次没有及时抓住最后还是跳了下去
最后一个 github 查看源码的 tips,现在只要把 github.com 改成 github.dev 就能直接用 vscode web 版本查看仓库代码,并且还支持代码跳转,文中的所有源码链接都是 github.dev 的链接,可以体验一下
