ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Volcano Job TTL 回收实战:从 ttlSecondsAfterFinished 到 gc-controller 源码剖析

Volcano Job TTL 回收实战:从 ttlSecondsAfterFinished 到 gc-controller 源码剖析 Volcano Job TTL 回收实战从 ttlSecondsAfterFinished 到 gc-controller 源码剖析【免费下载链接】volcanoA Cloud Native Batch System (Project under CNCF)项目地址: https://gitcode.com/GitHub_Trending/vol/volcanoVolcanoJob 与 Kubernetes 原生batch/v1 Job一样支持运行结束后的自动垃圾回收本文围绕 Volcano 的spec.ttlSecondsAfterFinished参数展开讲清其取值语义、完整的 Job 清单写法并结合 gc-controller 源码 剖析底层回收机制、参数校验链路与运维注意事项帮助你在批量任务密集型集群中有效回收已完成的 Job 对象。背景为什么需要 Job 垃圾回收在大规模运行批量任务的集群中持续累积的 Job 对象会占据 etcd 空间并拖慢列表/查询操作。与标准Job资源类似VolcanoJob 可以配置为在完成Completed或失败Failed执行后自动被垃圾回收配置方式就是设置spec.ttlSecondsAfterFinished来限制 Job 的生命周期。Volcano 通过 controller-manager 内置的gc-controller实现该能力。该控制器被独立于 Job controller 之外实现——从源码注释看garbagecollector.go这是出于职责分离的考虑且便于将来扩展到处理其他“可完成”的资源类型。核心参数spec.ttlSecondsAfterFinished 的完整语义tTLSecondsAfterFinished是 VolcanoJob 上的一个可选参数在 API 类型中定义为*int32指针默认为nil// staging/src/volcano.sh/apis/pkg/apis/batch/v1alpha1/job.go TTLSecondsAfterFinished *int32 json:ttlSecondsAfterFinished,omitempty protobuf:varint,10,opt,namettlSecondsAfterFinished其取值语义如下取值行为不设置 /nilJob 永久保留不会被 GC 回收0Job 一完成Completed或Failed立即进入可回收状态正整数NJob 在完成N秒后进入可回收状态参数约束为非负整数CRD schema 中声明minimum: 0见 batch.volcano.sh_jobs.yaml。在 Volcano 当前版本中该检查已从 validating webhook 下沉到 CRD schema 与 Volcano Admission PolicyVAPCRD schemattlSecondsAfterFinished: {format: int32, minimum: 0, type: integer}VAP 规则volcano-development-vap.yaml!has(object.spec.ttlSecondsAfterFinished) || object.spec.ttlSecondsAfterFinished 0违规时返回ttlSecondsAfterFinished cannot be less than zero。这也与 webhook 侧的注释一致——admit_job.go 中明确说明TTLSecondsAfterFinished 0这类基础校验已迁移以避免与 CRD schema 重复。完整示例10 分钟后回收的 Job下面这份清单创建一个 Job它在完成或失败 10 分钟600 秒后进入可回收状态。示例中的 Job 使用RestartJob策略处理 Pod 被驱逐事件任务侧使用CompleteJob策略在单个 sleeper 副本执行完 6 次 1 秒睡眠后结束整个 JobapiVersion: batch.volcano.sh/v1alpha1 kind: Job metadata: generateName: test-job- spec: minAvailable: 1 schedulerName: volcano queue: testing ttlSecondsAfterFinished: 600 policies: - event: PodEvicted action: RestartJob tasks: - replicas: 1 name: sleeper policies: - event: TaskCompleted action: CompleteJob template: spec: restartPolicy: Never imagePullPolicy: IfNotPresent containers: - name: sleeper image: debian:buster command: - /bin/bash - -c - | for i in {0..5}; do echo sleeping sleep 1 done需要注意前提queue: testing必须是已存在且处于Open状态的队列webhook 会拒绝向非 Open 队列或 root 队列提交 Job见 admit_job.go。底层实现gc-controller 的回收全流程控制器注册与 Worker 线程gc-controller在包初始化时通过framework.RegisterController(gccontroller{})注册garbagecollector.go#L39-L41。Initialize阶段创建 Job informer并注册AddFunc/UpdateFunc两个事件处理器工作线程数由 controller-manager 启动参数--worker-threads-for-gc决定默认为1options.go#L132。参数描述为回收线程越多Job 回收越快但 CPU 开销越大。事件驱动入队只有“已完成且设置了 TTL”的 Job 才被关注Job 的创建和更新事件都会经过needsCleanup判断// pkg/controllers/garbagecollector/garbagecollector.go func needsCleanup(j *v1alpha1.Job) bool { return j.Spec.TTLSecondsAfterFinished ! nil isJobFinished(j) } func isJobFinished(job *v1alpha1.Job) bool { return job.Status.State.Phase v1alpha1.Completed || job.Status.State.Phase v1alpha1.Failed || job.Status.State.Phase v1alpha1.Terminated }这里有一个值得注意的细节与文档中“Complete or Failed”的表述相比源码中可回收的终态还包括Terminated——即 Job 因外部事件如取消、中止非预期结束时只要设置了 TTL同样会被回收。TTL 计算与延迟入队Worker 从队列取出 Job 后调用processTTLgarbagecollector.go#L245-L264从job.Status.State.LastTransitionTime读取 Job 的完成时刻jobFinishTimeL304-L309计算expireAt finishAt TTLSecondsAfterFinished得出剩余时长remaining若remaining 0判定 TTL 已过期进入删除流程若尚未过期则调用gc.enqueueAfter(job, *t)把 Job 在预计到期时刻重新入队——这是一种“延迟唤醒”机制而不是轮询因此对 API Server 的额外压力很小。源码还对时钟偏差做了防御如果发现 Job 的完成时间在未来time skew会打印警告并推迟回收L295-L297。删除前的最终一致性校验即使缓存判定 TTL 已过期processJob也不会立即删除而是先通过 API Server 拉取最新 Job 再做一次processTTL复检L211-L227防止“在删除检查之前 TTL 被修改”导致的误删。确认过期后删除请求带有两层保护policy : metav1.DeletePropagationForeground options : metav1.DeleteOptions{ PropagationPolicy: policy, Preconditions: metav1.Preconditions{UID: fresh.UID}, }前台传播删除Foreground级联删除 Job 关联的 PodGroup 等依赖资源UID 前置条件只删除与刚校验的 UID 一致的 Job 对象进一步杜绝竞态下的误删。处理过程中出错会走handleErr以AddRateLimited限流重试L174-L182保证回收动作最终会被执行。该逻辑的单元测试覆盖在 garbagecollector_test.go 中。与 Kubernetes 标准 Job TTL 的对比Volcano 的该能力在行为上与标准batch/v1 Job的ttlSecondsAfterFinished几乎一致同样是“完成后计时、到期由专用控制器删除”。不同点在于 Volcano 的回收由gc-controllercontroller-manager 的一部分执行且回收触发范围额外覆盖Terminated状态。一个值得借鉴的进阶技巧可以为“所有 Job 默认设置 TTL”编写 mutating webhook在 Job 创建时若未显式指定ttlSecondsAfterFinished则自动注入默认值从而把默认回收策略集中化、避免在每个 Job 清单中重复书写。运维注意事项与适用前提前提条件集群中运行着 Volcano controller-manager且gc-controller未被--controllers参数禁用该参数支持以-gc-controller形式排除特定控制器见 options.go#L134-L135。不可变更字段Job 创建后除minAvailable、tasks[*].replicas与priorityClassName外的 spec 字段均不允许修改admit_job.go#L272-L304。这意味着提交后无法通过更新来延长或取消 TTL如需保留某个已完成的 Job只能在到期前直接删除其ttlSecondsAfterFinished之外的途径不可行——更实际的做法是在 Job 完成且 TTL 未到之前将其处理为不再需要回收或按0之外的大值提交。回收时点实际删除时刻取决于事件处理延迟与限流重试通常略晚于finishAt N秒而非精确到秒。时间偏差节点与控制器间时钟偏差过大时回收会被推迟并输出警告日志可通过集群时钟同步如 NTP/chrony规避。批量场景调优若集群中大量 Job 几乎同时到期可通过--worker-threads-for-gc适当增加回收线程数以加快对象清理速度。【免费下载链接】volcanoA Cloud Native Batch System (Project under CNCF)项目地址: https://gitcode.com/GitHub_Trending/vol/volcano创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表