跳至内容

定时工作流

v2.5及更高版本

CronWorkflows 是按计划运行的workflow。 它们的设计目的是封装一个workflowSpec并模拟Kubernetes CronJobs的选项。 本质上,CronWorkflow = Workflow + 一些特定的定时选项。

CronWorkflow 规范

以下是一个CronWorkflow的示例:

apiVersion: argoproj.io/v1alpha1
kind: CronWorkflow
metadata:
  name: test-cron-wf
spec:
  schedule: "* * * * *"
  concurrencyPolicy: "Replace"
  startingDeadlineSeconds: 0
  workflowSpec:
    entrypoint: date
    templates:
    - name: date
      container:
        image: alpine:3.6
        command: [sh, -c]
        args: ["date; sleep 90"]

workflowSpecworkflowMetadata

CronWorkflow.spec.workflowSpecWorkflow.spec 类型相同。 它是从中创建的 Workflow 对象的模板。

Workflow名称是基于CronWorkflow名称生成的。 在上面的示例中,它类似于test-cron-wf-tj6fe

您可以使用CronWorkflow.spec.workflowMetadata来添加labelsannotations

CronWorkflow 选项

选项名称 默认值 描述
schedule None Cron schedule to run Workflows. Example: 5 4 * * *. Deprecated, use schedules.
schedules None v3.6 and after: List of Cron schedules to run Workflows. Example: 5 4 * * *, 0 1 * * *. Either schedule or schedules must be provided.
timezone Machine timezone IANA Timezone to run Workflows. Example: America/Los_Angeles
suspend false If true Workflow scheduling will not occur. Can be set from the CLI, GitOps, or directly
concurrencyPolicy Allow What to do if multiple Workflows are scheduled at the same time. Allow: allow all, Replace: remove all old before scheduling new, Forbid: do not allow any new while there are old
startingDeadlineSeconds 0 Seconds after the last scheduled time during which a missed Workflow will still be run.
successfulJobsHistoryLimit 3 Number of successful Workflows to persist
failedJobsHistoryLimit 1 Number of failed Workflows to persist
stopStrategy.expression nil v3.6 and after: defines if the CronWorkflow should stop scheduling based on an expression, which if present must evaluate to false for the workflow to be created
when None v3.6 and after: An optional expression which will be evaluated on each cron schedule hit and the workflow will only run if it evaluates to true

Cron 定时语法

cron调度器采用标准cron语法。其实现方式与CronJobs相同,使用robfig/cron库。

崩溃恢复

如果控制器崩溃,您可以确保任何错过的调度仍会运行。

通过设置startingDeadlineSeconds,您可以指定一个最大宽限期,即使超过最后一次计划执行时间,工作流仍会运行。 例如,如果一个每分钟运行的CronWorkflow最后一次执行是在12:05:00,而控制器在12:05:55到12:06:05之间崩溃,那么预期的12:06:00执行时间将被错过。 但如果将startingDeadlineSeconds设置为大于5的值(即从计划执行时间12:06:00到当前时间12:06:05之间的时间差),那么CronWorkflow的一个实例将在12:06:05准时执行。

目前由于设置了startingDeadlineSeconds,只会执行单个实例。

此设置还可以与concurrencyPolicy配合配置,以实现更精细的控制。

夏令时

使用timezone时,会考虑夏令时(DST)因素。 根据预定工作流的本地时间,当时钟向前或向后调整时,工作流可能运行一次、两次或完全不运行。

例如,使用 timezone: America/Los_Angeles

  • 2020-03-08 02:00:00 增加1小时(夏令时开始):

    注意:由于时钟向前调整,3月8日02:00至02:59之间的计划被跳过:

    cron 序列 工作流执行时间
    59 1 ** * 1 2020-03-08 01:59:00 -0800 PST
    2 2020-03-09 01:59:00 -0700 PDT
    3 2020-03-10 01:59:00 -0700 PDT
    0 2 ** * 1 2020-03-09 02:00:00 -0700 PDT
    2 2020-03-10 02:00:00 -0700 PDT
    3 2020-03-11 02:00:00 -0700 PDT
    1 2 ** * 1 2020-03-09 02:01:00 -0700 PDT
    2 2020-03-10 02:01:00 -0700 PDT
    3 2020-03-11 02:01:00 -0700 PDT
  • 2020年11月1日02:00:00夏令时结束前1小时:

    注意:由于时钟回拨,11月1日凌晨01:00至01:59之间的计划任务被触发了两次:

    cron表达式 序列号 工作流执行时间
    59 1 ** * 1 2020-11-01 01:59:00 -0700 PDT
    2 2020-11-01 01:59:00 -0800 PST
    3 2020-11-02 01:59:00 -0800 PST
    0 2 ** * 1 2020-11-01 02:00:00 -0800 PST
    2 2020-11-02 02:00:00 -0800 PST
    3 2020-11-03 02:00:00 -0800 PST
    1 2 ** * 1 2020-11-01 02:01:00 -0800 PST
    2 2020-11-02 02:01:00 -0800 PST
    3 2020-11-03 02:01:00 -0800 PST

跳过前进(缺失计划)

您可以使用when来每天仅调度一次,即使您希望的时间处于夏令时向前跳过的时段(这种情况下通常会调度两次)。

一个示例时间表 02:30:00

schedules:
  - 30 2 * * *
  - 0 3 * * *
when: "{{= cronworkflow.lastScheduledTime == nil || (now() - cronworkflow.lastScheduledTime).Seconds() > 3600 }}"

该计划每天3:00的运行不会在全年每天都执行,除了时钟向前跳过2:30的那天。 when表达式防止此工作流每小时运行超过一次。 在这种情况下,3:00的运行将会执行,因为2:30被跳过了。

可以在3:00运行

如果您在期望时间和3:00之间创建这个CronWorkflow,它将在3:00运行,就像之前从未运行过一样。

向后跳过(重复)

你可以使用when来安排每天执行一次,即使你希望的时间处于夏令时回拨期间(这种情况下通常不会被调度)。

一个示例时间表 01:30:00

schedules:
  - 30 1 * * *
when: "{{= cronworkflow.lastScheduledTime == nil || (now() - cronworkflow.lastScheduledTime).Seconds() > 7200 }}"

这将在第一次01:30时安排一个向后跳过的变更。 由于when表达式的限制,第二个将不会运行,该表达式阻止此工作流运行频率超过每2小时一次。

自动停止CronWorkflow

v3.6 及更高版本

您可以配置CronWorkflow,使其基于表达式通过stopStrategy.expression自动停止。 您可以使用变量cronworkflow.failedcronworkflow.succeeded

例如,如果您希望在成功运行一次后停止调度新的工作流:

stopStrategy:
  expression: "cronworkflow.succeeded >= 1"

你也可以在三次失败后停止调度新的工作流:

stopStrategy:
  expression: "cronworkflow.failed >= 3"

调度与完成情况

根据工作流调度和运行所需的时间,完成次数可能会超过配置的最大值。

例如,如果您将CronWorkflow配置为每分钟调度一次(* * * * *),并在成功一次后停止(cronworkflow.succeeded >= 1)。 如果Workflow需要90秒运行,CronWorkflow实际上会在两次完成后停止。 这是因为当达到停止条件时,已经有另一个Workflow在运行。 因此,建议使用类似cronworkflow.succeeded >= 1的条件,而不是cronworkflow.succeeded == 1

管理 CronWorkflow

命令行界面

您可以通过CLI创建CronWorkflows

$ argo cron create cron.yaml
Name:                          test-cron-wf
Namespace:                     argo
Created:                       Mon Nov 18 10:17:06 -0800 (now)
Schedules:                     * * * * *
Suspended:                     false
StartingDeadlineSeconds:       0
ConcurrencyPolicy:             Forbid

$ argo cron list
NAME           AGE   LAST RUN   SCHEDULES    SUSPENDED
test-cron-wf   49s   N/A        * * * * *   false

# some time passes

$ argo cron list
NAME           AGE   LAST RUN   SCHEDULES    SUSPENDED
test-cron-wf   56s   2s         * * * * *   false

$ argo cron get test-cron-wf
Name:                          test-cron-wf
Namespace:                     argo
Created:                       Wed Oct 28 07:19:02 -0600 (23 hours ago)
Schedules:                      * * * * *
Suspended:                     false
StartingDeadlineSeconds:       0
ConcurrencyPolicy:             Replace
LastScheduledTime:             Thu Oct 29 06:51:00 -0600 (11 minutes ago)
NextScheduledTime:             Thu Oct 29 13:03:00 +0000 (32 seconds from now)
Active Workflows:              test-cron-wf-rt4nf

注意: NextScheduledRun 假设控制器使用UTC作为其时区

kubectl

你可以使用 kubectl apply -fkubectl get cwf

回填天数

参见 cron回填

通过Argo CD实现GitOps

您可以通过使用Argo CD来用GitOps管理CronWorkflow资源

用户界面

您也可以在用户界面中管理CronWorkflow资源


有问题吗?

Search on GitHub Discussions and Slack.