原文链接:https://mp.weixin.qq.com/s?__biz=MzI0NjI4MDg5MQ==&mid=2715291842&idx=1&sn=e605f9b4099d946f94ca6783a8e4a6f6

背景:

    CronJob是Kubernetes提供的定时任务功能,CronJob可以根据你指定的cron策略来完成任务。我们在使用CronJob的时候,我们发现,当创建一个CronJob的时候,只会创建一个CronJob,当到指定时间时,会创建一个job和一个pod,随着时间的推移,我们会发现,越来越多的job和pod,甚至是满屏的job和pod,我们在调用API删除这个cronjob的时候,发现只会删除cronjob这个资源,而不会删除对应的已有的job和pod,然后,我们尝试删除job,发现删除job,会把对应的pod删除掉,为什么好多的操作不符合心理预期呢?心里冒着十万个为什么?

原作者疑问

1. cronjob是怎么定时创建job的呢?

2. 为什么删除的时候,只是删除了cronjob,而没有删除对应的job和pod呢?

3. cronjob、job和pod之间的关系是怎么样的呢?

4. job和pod的关系是怎么对应上的呢?

原作者答案

Q:cronjob和job是如何维护关系的呢?

A: cronjob和job关系,使用了types.UID,来判断的,每个cronjob拥有唯一的UID,然后列出所有的jobs,使用遍历job的策略来判断job应该属于哪个cronjob。

Q:job和pod的关系是怎么样维护的呢?

A: 先拿到了job中的Selector,然后,根据选择器来获取对应标签的pods

Q:cronjob是怎么定时创建job的呢?

A: 通过代码发现,cronjob会在后台启动一个go程,后台一直在处理cronjob,job和pod,同时也在维护cornjob的Active列表数据的正确性,同时,我们也在syncOne()函数中找到了他后台周期期创建job的操作。job是cronjob-controller创建的,逻辑是,当创建一个cronjob后,会把这个cronjob交接到cronjob-controller下的goroutine,然后就返回了,正在创建任务的是controller下的goroutine。

Q:删除是cronjob,为何没有删除对应的job和pod?

A: 删除的时候,会首先检查并发job的并发策略,如果不为0,会设置为0,并更新这个job的状态,然后找到对应的pod,删除完pod后再删除job本身,如果有一个pod删除失败,会直接退出而不会删除job。删除完job后,再从cronjob的Active列表中移除job。

对于删除cronjob,可能没有立即删除job和pod,是因为删除的时候会有三种策略,即:

DeletionPropagation string="Orphan","Foreground"(默认),"Background"

Orphan:垃圾回收GC自动触发;

Background:垃圾回收器会在后台执行删除(手动触发,立即后台处理)。

Foreground:API调用后会设置删除的过期时间,并把他放入到要删除的队列,在没删除之前,前台一直可见(手动触发,可能不立即处理)。

当真正执行Delete(或者其他操作)的时候,根据资源获取resource,然后重新组装deleteOptions策略,然后删除。

# 注意,删除cronjob的时候不会自动删除job,这些job可以用kubectl delete job来删除

参考链接:

Cronjob源码地址http://github.com/kubernetes/kubernetes/pkg/controller/cronjob/cronjob_controller.go

Cronjob中文文档:https://www.kubernetes.org.cn/cronjob