【问题标题】:kubernetes cronjob only runs once?kubernetes cronjob 只运行一次?
【发布时间】:2020-06-24 17:20:35
【问题描述】:

我创建了一个具有以下时间表的 k8s CronJob(每分钟运行一次):

schedule: "*/1 * * * *"

我看到我的 CronJob 已创建:

NAMESPACE     NAME                   READY   STATUS    RESTARTS   AGE
job-staging   job-1593017820-tt2sn   2/3     Running   0          10m

我的工作只是对日志执行一次 Printf,然后退出。

当我执行kubernetes get cronjob 时,我看到了:

NAMESPACE     NAME                   READY   STATUS    RESTARTS   AGE
job-staging   job   */1 * * * *      False   1         19m        19m

当我查看日志时,它看起来只运行了一次,这是第一次运行。我需要阻止我的程序退出吗?

我认为 k8s 会重新启动我的程序,但也许这是一个错误的假设。

【问题讨论】:

  • 脚本是这个func main() { log.Printf("job: start") log.Printf("job: done") }
  • apiVersion: batch/v1beta1 kind: CronJob metadata: name: {{ .Values.CronJob }} namespace: {{ .Values.CronJob }}-{{ .Values.ServiceStage }} labels: app: {{ .Values.CronJob }}-{{ .Values.ServiceStage }} spec: concurrencyPolicy: Forbid failedJobsHistoryLimit: 20 successfulJobsHistoryLimit: 20 schedule: "*/1 * * * *" jobTemplate: spec: template: metadata: name: scheduler-cron spec:

标签: kubernetes


【解决方案1】:

您对 Kubernetes 行为(“重启程序”)的假设是正确的。

您可能知道,Job 基本上是一个 Kubernetes Pod,它执行某个进程并在它以零退出代码退出时成功完成。 CronJob 的“Cron”部分最为明显,将 Job 安排在特定的时间模式中执行。

CronJobs 的大多数 YAML 对象都包含 restartPolicy: OnFailure 键,该键可防止 Kubernetes 为 非零退出代码重新安排作业(Kubernetes 文档中的 hello-world YAML file 使用此标志)。

根据我在您的 kubectl 指令获得的日志中看到的内容,您的作业似乎失败了 - 因为 Status 1。我建议您使用 kubectl logs -f -n default job-1593017820-tt2sn 检查 CronJob 的日志,以了解脚本执行中是否存在任何可能的错误(如果您的脚本以退出代码显式退出,请检查可能的非零代码)。

[更新]

CronJobs 也有限制:

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

我认为这些是非常罕见的情况,但也许您已经发现自己处于这些罕见的情况中。文档是here

【讨论】:

  • 我有restartPolicy: OnFailure。我的脚本执行没有问题。即使在我的脚本中添加os.Exit(0) 作为最后一行也没有什么不同,作业仍然不会重新启动。
  • 我在 pod 中运行了其他容器。他们可能会保留 pod,导致它不会终止,因此不会重新安排下一个作业。
  • 如果脚本没有问题,图像是最新的,并且 YAML 定义是正确的我会说你可能会达到 CronJob 的限制。我将更新我的答案以反映这些限制。
  • 既然您已经提到它,根据您的规范标志 concurrencyPolicy: Forbid 以及您对 Pod 未终止的怀疑,CronJob 控制器不会在最后一个尚未完成时重新安排作业。要验证这一点,请将标志更改为“允许”,提交 CronJob 并运行kubect get jobs --watch,您可能会看到多个作业正在生成(每分钟一个),状态为Running 而没有终止。然后,您可以尝试从 pod 或 kubernetes(使用 kubectl describe job/{name})读取日志以了解有关原因的更多信息。
  • 这个thread 可以帮助你,据我所知(我从未有过这个用例)人们通常使用文件(存储在卷中)来传达状态更改。在与 sidecar 通信时,我喜欢在容器之间使用 ZeroMQ 消费者模式。我希望我能帮助你!干杯!
猜你喜欢
  • 2021-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-15
  • 1970-01-01
  • 1970-01-01
  • 2017-01-03
  • 2012-08-26
相关资源
最近更新 更多