为什么在kubernetes cron job中可能会创建两个作业,或者可能没有创建作业?

时间:2017-12-07 09:05:38

标签: cron kubernetes distributed-computing jobs

在k8s Cron Job Limitations中提到,无法保证作业只会执行一次:

  

一个cron作业在每个执行时间创建一个作业对象   时间表。我们说“约”,因为在某些情况下   可能会创建两个作业,或者可能不会创建任何作业。我们试图   使这些罕见,但不要完全阻止它们。因此,工作   应该是幂等的

有人可以解释一下:

  • 为什么会这样?
  • 这可能发生的概率/统计数据是什么?
  • 是否会在k8s的某个合理的未来修复?
  • 是否有任何变通方法可以防止此类行为(如果正在运行的作业无法实现为幂等)?
  • 其他 cron相关的服务遭遇同样的问题吗?也许这是一个核心的cron问题?

1 个答案:

答案 0 :(得分:5)

控制器:

https://github.com/kubernetes/kubernetes/blob/master/pkg/controller/cronjob/cronjob_controller.go

首先发表评论,为解释奠定基础:

I did not use watch or expectations. Those add a lot of corner cases, and we aren't expecting a large volume of jobs or scheduledJobs. (We are favoring correctness over scalability.)  

If we find a single controller thread is too slow because there are a lot of Jobs or CronJobs, we we can parallelize by Namespace. If we find the load on the API server is too high, we can use a watch and UndeltaStore.) 

Just periodically list jobs and SJs, and then reconcile them.

每10秒定期一次:

https://github.com/kubernetes/kubernetes/blob/master/pkg/controller/cronjob/cronjob_controller.go#L105

根据引用限制的文档在某些情况下也有一些有用的颜色,在这些情况下,可以按特定的时间表启动2个工作或无工作:

If startingDeadlineSeconds is set to a large value or left unset (the default) and if concurrentPolicy is set to AllowConcurrent, the jobs will always run at least once.

Jobs may fail to run if the CronJob controller is not running or broken for a span of time from before the start time of the CronJob to start time plus startingDeadlineSeconds, or if the span covers multiple start times and concurrencyPolicy does not allow concurrency. For example, suppose a cron job is set to start at exactly 08:30:00 and its startingDeadlineSeconds is set to 10, if the CronJob controller happens to be down from 08:29:00 to 08:42:00, the job will not start. Set a longer startingDeadlineSeconds if starting later is better than not starting at all.

更高级别,在分布式系统中只解决一次很难:

https://bravenewgeek.com/you-cannot-have-exactly-once-delivery/

分布式系统中的时钟和时间同步也很困难:

https://8thlight.com/blog/rylan-dirksen/2013/10/04/synchronization-in-a-distributed-system.html

问题:

  • 为什么会发生这种情况?

    例如,托管CronJobController的节点在作业运行时失败。

  • 这可能发生的概率/统计数据是什么?

    任何特定跑步都不太可能。对于足够多的运行,不太可能逃避不得不面对这个问题。

  • 是否会在k8s的某个合理的未来修复?

    k8s repo中的区域/批次标签下没有与标准能力相关的问题,所以人们不会猜测。

    https://github.com/kubernetes/kubernetes/issues?q=is%3Aopen+is%3Aissue+label%3Aarea%2Fbatch

  • 是否有任何解决方法可以防止此类行为(如果正在运行的作业无法实现为幂等)?

    更多地考虑idempotent的具体定义,以及提交作业中的特定点。例如,如果将状态保存到临时区域,则可以使作业支持多次执行,然后有一个选举过程来确定谁的工作获胜。

  • 其他与cron相关的服务遭遇同样的问题吗?也许这是一个核心的cron问题?

    是的,它是核心分布式系统问题。

    对于大多数用户来说,k8s文档可能提供了比必要更精确和细致的答案。如果您的预定工作正在控制某些重要的医疗程序,那么计划失败案例非常重要。如果它只是进行一些系统清理,那么错过预定的运行并不重要。根据定义,几乎所有k8s CronJobs的用户都属于后一类。