kubernetes 如何让CronJob遵守夏令时?

tvmytwxo  于 2023-03-07  发布在  Kubernetes
关注(0)|答案(4)|浏览(151)

假设我和我正在合作的伙伴公司生活在一个雇佣Daylight Saving Time的国家。
我在Kubernetes集群中有一个CronJob,它每天在4:00、10:00、16:00和22:00向合作伙伴公司上传文件,例如0 4,10,16,22 * * *
Kubernetes SIG决定CronJob对象将不支持本地时区,并将始终以默认时区(UTC)运行。
我可以更改计划,使其反映上面指定的UTC本地时间,并为CronJob提供该计划。但是,每次夏令时开始(每年两次),我都需要以某种方式修改所有CronJob以使用新时间,* 并且 * 我需要修改我的部署管道以使用新时间创建新版本的CronJob。
我不能保持cronjob在夏令时更改后按相同的时间表运行,因为该作业将不在合作伙伴预期的时间内上载文件。
最简单的管理方法是什么?

    • 备选案文1**

有人建议写一个新的kubernetes控制器可以做到,但似乎没有人提出了这个挑战,并公布了工作解决方案。

    • 备选案文2**

我考虑过的另一个选择是改变整个集群的时区,但如果你使用google it,这似乎不是一个很受欢迎的解决方案,有些人强烈认为kubernetes作为一个云应用程序应该在UTC下运行。
据我所知,cron使用本地时区,在kubernetes的情况下,它将是控制器管理器的时区,而不一定是运行它的节点的时区。另一方面,更改控制器管理器容器的时区听起来很危险,因为不清楚它将如何与kubernetes的其他组件(如etcd和kubelets)交互。

    • 备选案文3**

一年手动操作两次。由于组织中的人员来来去去,因此很难保留有关时间和方式的信息。我不希望我们的合作伙伴一年抱怨两次。此外,由于日期每年都在变化,因此设置通知可能会很棘手。

    • 备选案文4**

编写一些自主开发的自动化程序,一年运行两次,希望到时候它能像预期的那样工作。这实际上是触发器,在正确的时间触发,做它应该做的一切。(后者更容易测试,但前者更难)。
所有这些选项都让人觉得不太满意。我搜索了很多,但我没有找到很多,我觉得这应该是一个很常见的问题,但在搜索中什么也没有出现。我忽略了什么吗?有没有一个简单自然的方法来解决它?

ewm0tg9j

ewm0tg9j1#

时区被添加到Kubernetes 1.22的CronJob中。
澄清一下,它在1.22版本中可用。
它是以一种非常奇怪的方式实现的,虽然没有在模式中暴露出来。我不知道为什么要这样做的任何解释,而且它忽略了Kubernetes背后的核心概念。我认为这仍然需要改进。
这可以通过CRON_TZ变量来完成,如下所述。

#      ┌────────────────── timezone (optional)
#      |      ┌───────────── minute (0 - 59)
#      |      │ ┌───────────── hour (0 - 23)
#      |      │ │ ┌───────────── day of the month (1 - 31)
#      |      │ │ │ ┌───────────── month (1 - 12)
#      |      │ │ │ │ ┌───────────── day of the week (0 - 6) (Sunday to Saturday;
#      |      │ │ │ │ │                                   7 is also Sunday on some systems)
#      |      │ │ │ │ │
#      |      │ │ │ │ │
# CRON_TZ=UTC * * * * *
    • 更新**

此功能将标记为不受支持

xjreopfe

xjreopfe2#

我知道这是一个老问题,但argo工作流有一个支持时区和夏令时的Cron工作流CRDhttps://argoproj.github.io/argo-workflows/cron-workflows/#daylight-saving。

jhdbpxl9

jhdbpxl93#

也许我来得有点晚,但我相信最简单的方法是让两个cronjob与tz-check一起运行,当时区与预期值匹配时,才运行command
关于Daylight Saving Time的一个很好的帖子,可以在here中找到,复制它的例子,我们可以看到对于时区 *TZ=Europe/斯德哥尔摩 *,时区根据日期的不同而改变为夏令时:

$ TZ=Europe/Stockholm date +%Z # CET or CEST depending of when its run
$ TZ=Europe/Stockholm date --date=20170101 +%Z # CET
$ TZ=Europe/Stockholm date --date=20170601 +%Z # CEST
$ TZ=CET date --date=20170101 +%Z # CET
$ TZ=CET date --date=20170601 +%Z # CEST, note that its auto adjusted to CEST

因此,在本例中,假设OP希望根据我们是否处于DST在不同的时间运行他的cron,我们可以编写以下crontab:

# Example of job definition:
# .--------------------- minute (0 - 59)
# |    .---------------- hour (0 - 23)
# |    |     .---------- day of month (1 - 31)
# |    |     |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |    |     |  |  .---- day of week (0 - 6) (Sunday=0 or 7)
# |    |     |  |  |
# command only runs in Europe/Stockholm Winter time
  0  4-23/6  *  *  *   tz-test "Europe/Stockholm" "CET"  && command
# command only runs in Europe/Stockholm Summer time
  0  3-23/6  *  *  *   tz-test "Europe/Stockholm" "CEST" && command

这里,crontab定义中的时间以UTC为单位(因为cron以UTC为单位运行),tz-test命令类似于:

#!/usr/bin/env bash
tz=$(TZ="$1" date "+%Z")
[ "$tz" == "$2" ]

**注意:**在这里您仍然需要小心。由于时间选择的原因,您的crontab可能会在更改小时的当天运行两次甚至更多次。在上面的示例中,情况并非如此。
**注:**虽然这个问题是针对Kubernetes的,但我相信在该框架内可以实现类似的实施。

t1rydlwq

t1rydlwq4#

从kubernetes 1.24/1.25开始,有一个功能门CronJobTimeZone,允许您将.spec.timeZone设置为有效time zone的名称。“Etc/UTC”指示Kubernetes解释相对于协调世界时的计划。功能门在版本1.24中默认禁用,在版本1.25中默认启用

相关问题