Kubernetes: CronJobs 应该支持时区

创建于 2017-06-09  ·  66评论  ·  资料来源: kubernetes/kubernetes

在搜索“cron timezone”、“cronjob timezone”或“scheduledjob timezone”后,我找不到任何关于此的讨论。

CronJob 规范参考了https://en.wikipedia.org/wiki/Cron。 该页面表明 cron 会尊重给定用户的时区。 控制器管理器在单个用户的单个时区中运行,因此我无法为每个作业使用不同的时区。 我有根据观察夏令时的外部实体的时间表运行的作业。 因此,如果我在 UTC 中定义该 CronJob,我将被迫不时更新该作业(通常不是人们在睡了一小时后才记得要做的事情)。

对于这种支持在 kubernetes 中的工作方式,我看到了两个选项:

  1. CronJobSpec添加一些新字段,例如timezone: "Americas/Chicago"
  2. 使用包含时区的扩展 cron 语法,例如30 6 * * 1 Europe/Stockholm
arebatch areworkload-apcronjob kinfeature siapps

最有用的评论

FWIW,我的每个制作 CronJob 的用户(开发人员和管理员等)都询问“如何设置时区”。

所有66条评论

@iterion在这个问题上没有 sig 标签。 请通过以下方式添加 sig 标签
(1) 提及一个签名: @kubernetes/sig-<team-name>-misc
(2) 手动指定标签: /sig <label>

_注意:方法(1)将触发通知团队。 你可以在这里找到团队列表和标签列表在这里_

/ 签名应用程序

更喜欢第二个选项,因为它对我来说看起来更自然

@soltysh @kubernetes/sig-apps-feature-requests

我也喜欢第二种形式,但似乎最简单的实现途径是去掉这段时间并单独使用它。 此外,可以提出一个论点,因为我们使用的是“标准”cron 模板,所以我们不应该弄乱它。

看起来这应该很容易实现:
目前,我们只是将 time.Now() 传递到syncOne循环中。 k8s 使用的 cron 库似乎只需要使用您关心的区域中的时间即可。 因此,我们可以从 CronJob 中提取时区并将该时间与 zone 传递到 syncOne 函数中。

//init the loc, needs error handling
//perhaps default to local if Timezone was invalid
loc, _ := time.LoadLocation(cronjob.Spec.Timezone)

//set timezone,  
now := time.Now().In(loc)

此外,我很高兴尝试实现这一点。

我不是审查您的 PR 的合适人选,但我确实有一些关于语义的问题。

  • 未指定时区时的语义是什么?
  • 实现是否取决于在控制器主机上正确配置的时区?
  • 我们什么时候验证时区合法性? 在对象创建/更新时,还是稍后?
  • 如果创建 API 对象时时区名称是合法的,但将来不再存在,会发生什么情况? 发生这种情况的原因可能是某个名称被删除(可能某个城市或国家已不复存在),或者因为基础 tzdata 包已更改为旧版本。

如果未定义时区,则默认为当前行为,即使用主机的时区。 我猜在大多数情况下这会被配置为 UTC,但用户真的可以选择任何时区。 因此,由于此 PR,不再依赖于在主机上正确配置的时区。

如果用户指定的内容无效,我目前只是退出并使用主机的时区。 在这里,我依靠 golang 的time.LoadLocation(str)方法。 该函数接受的任何字符串都将被视为有效。 我目前没有在创建/更新时验证这一点,尽管这似乎是一件非常容易的事情。

至于最后一个问题,那个问题有点不确定。 目前,也可能是在未来,它很可能会退回到基于默认时区来安排作业。 我愿意接受有关如何处理此案的建议。

如果创建 API 对象时时区名称是合法的,但将来不再存在,会发生什么情况? 发生这种情况的原因可能是某个名称被删除(可能某个城市或国家已不复存在),或者因为基础 tzdata 包已更改为旧版本。

我对此的建议是通过适当的事件使工作创建失败。 但坦率地说,我怀疑这种情况经常发生。 我会确保在你的实现@iterion 中添加这个。

并且 cron 格式不支持年份归档,如何在指定时间只运行一次作业?

:+1:

@iterion感谢您的问题和拉取请求。 在过去的一周里,我们在 SIG Apps 和 SIG Architecture 中讨论了很多。 虽然用例这可能对有意义的有用,但我们也必须讨论缺点。 例如,每个兼容的 Kubernetes 发行版都需要有一个时区数据库并保持更新。 时区、夏令时以及使这项工作有效的细节,而现实世界的细节可以并且确实很难改变。 对于今天存在的 20 多个发行版,这将是额外的工作。

与此同时,Kubernetes 的开发也发生了变化。 我不确定它的交流有多广泛(交流是 SIG 架构中讨论的另一点)。 这种转变是希望核心 Kubernetes 专注于稳定性和缓慢移动。 现在鼓励人们在生态系统而不是核心中进行创新和解决这类问题。

与其将其放在 Kubernetes 中,不如说是:

  1. 在其他人可以使用的生态系统(例如,控制器)中开发它。 分发它,解决那里的问题,看看更新是什么样的
  2. 如果解决方案被广泛采用并且可以被所有人使用(包括小规模、多集群等),那么可以考虑将其用于核心Kubernetes

如果有帮助,那么这并不是唯一收到相同方向的功能(即使在同一个 SIG 架构会议中)。 我开始以类似于 wordpress 的方式思考这个问题(我使用 wordpress 因为它是一个非常常见的例子)。 它是插件还是 wordpress 本身的一部分是有区别的。 可以这么说,当前的方向是鼓励插件创新。

如果您构建了这样的东西,我们希望在 SIG Apps 上进行演示,以向人们展示它。 它也可以在社区会议上进行演示。

如果您对此有任何疑问,请随时与我联系。

鉴于之前的评论,我觉得我们可以关闭这个问题。 如果您不同意,请随时重新打开。

FWIW,我的每个制作 CronJob 的用户(开发人员和管理员等)都询问“如何设置时区”。

@iterion你最终对此做了什么? 我们正在为我们的用例考虑各种选项,包括

  • 用你的修复从 kubernetes 的一个分支上运行
  • 将 cron 控制器代码复制到外部控制器中,并使用不同的 apiVersion 来区分两者。
  • 在 Ruby 中构建特定于我们的项目的内容,它反映了 kube cronjob 控制器实现,但基于特定于应用程序的配置文件而不是 CronJob 资源。

如果您已经有一些对您有用的东西,我们可以将其用作起点,或者如果我们可以合作开发一些有助于鼓励@mattfarina改变他不允许包含此内容的决定(这极大地损害了此 kube 的采用)功能),那会很棒。

我实际上已经换了一份新工作,所以对我个人来说,原来的问题不再存在了。 据我所知,我以前的同事们只是在处理由此带来的痛苦。

也就是说,如果我有时间专注于此,我可能会编写一个小控制器,根据需要监视和修改 CronJobs。 我可能只是向 CronJobs 添加一个带有所需时间和时区的注释,并让控制器将该时间表转换为 UTC 并修改 CronJobs。 您可以每隔一段时间运行此同步循环以捕捉问题边缘,即夏令时开始或结束的时间。 通过这种方式,控制器只是在现有 CronJob API 之上的一个非常纤薄的包装器。

鼓励@mattfarina改变他不允许包含此内容的决定

明确地说,这个决定是在一次 sig-架构会议期间集体完成的。 在这个问题上,马特只是表达这个决定的人。

在 Linux 世界中,时区问题早已得到解决。 为什么这是 Kubernetes 部署的先决条件?

很难讨论我承认的用例的重要性。 然而(在我看来),能够与服务的用户同步安排服务对我来说似乎足够重要,有资格使用 Kubernetes 核心。

有人愿意用 TimezoneAwareCronjobController 编写一个运算符吗? @iterion编写的大部分代码可能都可以回收。
将 TZ 处理转移到打包的应用程序中将解决在 Kubernetes 中扼杀一流 cronjob 支持的分发论点。

FWIW, https ://gopkg.in/robfig/cron.v2(现有控制器使用的是较旧的子集)确实支持传入 TZ,以及一组稍微丰富的时间定义。
我们内部有一个控制器,可以为我们的一些内部工作负载创建 cron 作业,并且能够为这些工作指定时区是一项出色的功能请求。 我需要弄清楚如何安全地更新现有的 cronjob 定义而不会意外跳过或重新运行作业。 在这一点上,感觉从现有控制器中窃取作业调度并直接创建作业定义(而不是 cronjobs)实际上可能更容易。

自从我开始使用 K8s 以来,我每年都会两次回到这个问题,当时我被迫更改所有 CronJobs 的时间表,希望它终于重新开放。 如果chronoscrontab都有这个功能,那么 K8s 怎么还不支持呢?

长期问题(自我说明)

希望这个问题能重新打开,每天看UTC时间有点奇怪。

我有一个需要在本地时间每个月的第一天运行的 cronjob,但 UTC 时间是上个月最后一天的 16:00。 如何定义上个月的最后一天? Cronjob 不支持 L.

似乎不存在替代解决方案。 在此处此处查看我的问题

对于任何仍在等待这个的人; 我创建了一个源自原生 Kubernetes cronjob 控制器和关闭的原始 PR 的控制器。

https://github.com/hiddeco/cronjobber

编辑(2019-05-12):感谢@mterron ,Cronjobber 现在支持使用 sidecar 的主机独立时区数据库。

@hiddeco使用控制器控制标准 CJ 控制器而不是修改现有控制器会更好吗? 对于后一种方法,需要跟上实际 CJ 控制器的变化,这可能并不总是可行的。 感谢您的工作。

@andrewsav这会更可取,但CronJob的时间表修改为时区的偏移量。 对于所有可能的计划组合,您无法做到这一点。

无论如何,我不希望 CJ 控制器有很多变化,而且我们没有义务与它保持同步以保持它的运行,因为它是独立的(除了对客户端的依赖和Job规范) .

@hiddeco

对于所有可能的计划组合,您无法做到这一点。

你能解释一下吗?

@AndrewSav简单示例:在NZDT (UTC+13) 中运行的0 0 1 * *意味着您需要每个月重新计算它,因为您需要在上个月的最后一天在UTC 时间上午 11 点。

如果您的日程安排的复杂性增加,您需要进行的更改数量也会增加以保持同步。 另外,每次时区区域从 DST 更改为 ST 时,您都需要更改它。

这使得它变得极其复杂,并为在错误的时间甚至更糟的时间运行它开辟了很多空间; 一点也不。

一种解决方案是根据您的时区每隔“可能”的一小时运行一次 cron,如果当前时间不是预期的时间,则跳过它。 我希望我能在 kubernetes 级别做到这一点。

对于 DST,这意味着它将每天运行两次而不是一次,并根据 DST 跳过第一个或第二个。

例如,每个兼容的 Kubernetes 发行版都需要有一个时区数据库并保持更新。 时区、夏令时以及使这项工作有效的细节,而现实世界的细节可以并且确实很难改变。 对于今天存在的 20 多个发行版,这将是额外的工作。

时区数据库,DST,由操作系统发行版维护得很好,kubernetes 发行版应该依赖它。 “发行版很辛苦”的借口在 IMO 是无效的。

如果这个概念被称为PeriodicJobRepeatingJob我不会争论。 但是,它被称为CronJob 。 它与日历和时钟联系在一起。 不可否认,时区意识是实现这一目标的关键要求。

另一种解决方案; 也许这个问题可以通过从 kubernetes 中完全删除 CronJob 来解决。 并不是说它会帮助任何人。

另一种解决方案; 也许这个问题可以通过从 kubernetes 中完全删除 CronJob 来解决。 并不是说它会帮助任何人。

同意,如果他们无法在 k8s 中实施适当的解决方案,他们根本不应该添加解决方案。 Cronjob 被设计用于时区,今天所有的操作系​​统都使用相关的操作系统功能透明地处理时区。

推理似乎并不连贯,如果我们要按照这个逻辑进行,那么 K8s 中应该存在许多不应该存在的特性。

这确实是一个错误。 Cronjob本身具有误导性,因为它不遵循 Cron 规范。 大多数 kubernetes 用户会认为时区支持是开箱即用的。 令人失望的是,核心开发人员选择不包含此内容。 这个问题应该会影响超过 90% 不在 UTC 时间操作的用户。

我很想重新审视这个。 我遇到的一个问题是,我希望某些作业在日本每月第一天的凌晨 1 点运行——这当然是一个合理/标准的用例。 鉴于 cron 是在 UTC 中定义的,我无法指定这一点; 0 0 1 * *将在日本时间上午 9 点运行。 (在某些 cron 实现中使用的每月最后一天添加0 0 L * *也很好)

@johnnyshields您可能应该要求@soltysh重新打开。

虽然我很想重新考虑这个问题,但我认为可能性很小。 团队聚在一起,讨论并决定这会导致过多的额外工作。 从那以后,这并没有改变,所以这个决定也不太可能改变。

只需看看(并贡献!)到 CronJobber https://github.com/hiddeco/cronjobber。 它做每个人都想做的事。

基于最新版本的 CronJob 控制器的 PR 会很棒,但它可以完美地工作。

虽然我很想重新考虑这个问题,但我认为可能性很小。 团队聚在一起,讨论并决定这会导致过多的额外工作。 从那以后,这并没有改变,所以这个决定也不太可能改变。

然后他们至少应该保持一致并删除当前的 cronjob 实现,因为它非常具有误导性(至少可以说)。

@mterron那个问题,它是不是几乎一年前就被打过补丁并且没有更新过,同时我们有十几个带有改进和安全修复的 kubernetes 点版本。 因此,运行陈旧的控制器无法保证他们正在利用 kubernetes 在这一领域的所有最新变化和功能。

@AndrewSav这就是我寻求帮助的原因。 我已经做了我能做的一切。 我不确定它是否存在任何安全风险,Kubernetes 一直在变化,但这并不意味着这种变化在安全意义上是有意义的。

话虽如此,rebase 会很酷,请随时做出贡献并提供帮助。

@mterron你是那个的作者,不是吗? 因此,即使您找不到时间这样做,人们也不太可能为不再活跃的事物做出贡献。 不过会非常好,我同意。 那个项目刚开始推送的时候,我就简单的考虑过要不要赌一下,放到自己的集群里,然后觉得维护的可能性不大。 现在一年后我明白我没有错。 所以我感谢你的工作,但恐怕以目前的形式它是不可持续的。

如果它起飞并且有人不断地重新调整和维护它,那就太好了。

不,我不是作者。 我只是一个为我使用的项目做出贡献的用户。
我理解你来自哪里,但我认为你对人们在业余时间为社区利益所做的事情的期望有点高。

@mterron我认为我达到了我的期望。 如果有的话,它们很低。 这是我避免在我的集群中使用链接工作的主要原因。

@AndrewSav您应该在 cronjobber 和上游 cronjob 控制器之间做一个差异。 上次我做的时候(1.17)没有区别。 上游 cronjob 控制器实际上不受您的定义维护。

上游控制器也有可怕的性能特征,当然是 cronjobber 继承的。

@benlangfeld

你应该在 cronjobber 和上游的 cronjob 控制器之间做一个差异

这不是关于我,而是关于它对于一般用途的可持续性。 要求每个潜在用户都做一个差异几乎是不合理的。 即使没有变化是事实,我想在下面进一步研究。

上游 cronjob 控制器实际上不受您的定义维护。

这不是对我所说的话的公平解释。

关于差异的主题:你对什么有什么不同? 该 repo 中有 50 多个文件,并非所有名称都与 kubernetes 源中的名称相匹配。 你能解释一下我们如何说服自己没有改变吗? 最好在您之前的评论中更详细一点,因为它并不明显。 特别是,您比较了每一方哪些分支/提交的哪些文件,并且没有检测到任何变化?

鉴于这个问题的广泛参与,我认为要求重新考虑 Kubernetes 核心特性是公平的。

我发现上面的以下声明很重要:“如果该解决方案被广泛采用并且可以被所有人使用(包括小规模、多集群等),那么它可以被考虑用于核心 Kubernetes”。 似乎有解决方案,也许还没有完全准备好。 因此,核心团队声明该用例被确认有资格使用 K8s 核心,这对这些解决方案的开发人员来说是一个很好的信号,让他们为拉取请求做好准备。

@AndrewSav作为“fork”的作者,我必须恭敬地不同意您迄今为止所说的任何内容,作为多个 OSS 项目的维护者,我对您的态度感到惊讶。

首先,cronjobber 只是从 Kubernetes CronJob 控制器派生出来的,因为它是最直接的解决方案,需要最少的时间来获得成熟(并经过验证)的解决方案。 鉴于下面所述的原因,我没想到上游会发生太大变化(也没有)。

其次,在时间Y工作X同时考虑到时区Z不是火箭科学,概念时间的规范多年来没有改变,应该'除了确保它仍然可以在正确的时间生成 Kubernetes 本机作业之外,不需要任何维护(并且时区数据库是最新的,感谢@mterron,为此提供了一个帮助程序)。

只要它能够产生这些工作,我上次检查时它完全有能力,我的时间最好花在其他地方。 如果这不符合您的标准,我建议聘请某人为您编写和维护类似的解决方案。

@hiddeco

我必须恭敬地不同意你到目前为止所说的任何事情

任何事物? 这是一个强有力的声明。

鉴于以下原因,我没想到上游会发生太大变化(也没有)

它可能不会改变_很多_,但也不会保持静态。 kubernetes 团队表示,他们想要一个“广泛采用”的解决方案,然后“可以考虑将其用于核心 Kubernetes”。 根据我的经验,没有得到积极维护(几乎一年没有变化)的解决方案很少被“广泛采用”。 此外,迄今为止没有人证明 Kubernetes CronJob 控制器及其依赖项根本没有改变。 我个人无法找到比较所有受影响文件和所有底层依赖项的好方法。

其次,在时间 Y 生成作业 X 同时考虑到时区 Z 不是火箭科学,概念时间的规范多年来没有改变,除了确保它仍然可以在正确的时间(并且时区数据库是最新的,感谢@mterron,有一个帮助程序可用)。

这对我来说听起来过于乐观。 这很少涉及“规范”更改。 杀死你的都是小事。 错误不断被发现,即使是在“成熟且经过时间验证”的项目中并得到修复。 产生一份工作可能不是一门火箭科学,但找出 kubernetes 代码库中的相关更改如何影响您的更改可能会很快变得棘手。 例如,去年努力将客户端 api (kubectl) 转移到 staging。 它会影响cron jobber吗? 我不知道。 使用的 cron 库版本已在上游更新。 它会影响cron jobber吗? 再说一次,我不知道。

只要它能够产生这些工作,我上次检查时它完全有能力,我的时间最好花在其他地方。

这很好。 你已经做了比你必须做的更多的事情。 您合并了 PR,并发布了您的作品供任何人使用。 谢谢你。

如果这不符合您的标准,我建议聘请某人为您编写和维护类似的解决方案。

同样,这与我无关,正如我在上面的评论中所解释的那样。 这是关于对更广泛的人群有用。 我现在好像在重复自己。 可能关于这个话题的一切都已经说了? 你怎么认为?

这对我来说听起来过于乐观。 这很少涉及“规范”更改。 杀死你的都是小事。 错误不断被发现,即使是在“成熟且经过时间验证”的项目中并得到修复。 产生一份工作可能不是一门火箭科学,但找出 kubernetes 代码库中的相关更改如何影响您的更改可能会很快变得棘手。 例如,去年努力将客户端 api (kubectl) 转移到 staging。 它会影响cron jobber吗? 我不知道。 使用的 cron 库版本已在上游更新。 它会影响cron jobber吗? 再说一次,我不知道。

老实说,这对我来说是造成阻碍的whatabouttism。 这个逻辑可以用来反对任何事情,所以我不知道你在这里想要实现什么。 运行具有时区意识的 cronjobs 并没有那么复杂。 几十年来,任何主流 *nix 系统(运行 k8 的系统)都拥有坚如磐石的时区支持(令人惊讶的是,*nix 系统主要运行在服务器环境中,40 多年来一直存在类似的担忧)。

同样,这与我无关,正如我在上面的评论中所解释的那样。 这是关于对更广泛的人群有用。 我现在好像在重复自己。 可能关于这个话题的一切都已经说了? 你怎么认为?

正如 ad-nauseam 所说,当前的实现几乎没有用,因为它完全忽略了时区,而时区感知的实现对更广泛的人更有用,你在这里有什么意义?

这个逻辑可以用来反驳任何事情

我不认为可以。 如果您愿意,欢迎您演示它,但请坚持所说的内容,而不是可能暗示的内容。

所以我不知道你想在这里实现什么。

哦,我只是在回答 hiddeco 针对我的评论,你可以在上面找到它。

正如 ad-nauseam 所说,当前的实现几乎没有用,因为它完全忽略了时区,而时区感知的实现对更广泛的人更有用

如果我们换个说法,说你和我都喜欢 kubernetes cronjob 支持时区,那是对的。 我发现“接近无用”有点太强了,但我强烈同意支持的时区感知实现会更有用。

你的意思是什么?

关键是没有证据表明我们正在讨论的“分叉”被“广泛采用”,因此 kubernetes 团队不太可能接受它,这真的很遗憾,因为那是我喜欢的参见并入 kubernetes。

错误不断被发现,即使是在“成熟且经过时间验证”的项目中并得到修复。

首先,在关于 kubernetes 或其生态系统的句子中没有“成熟”和“时间证明”这两个词。

其次,从什么时候开始在 kubernetes 中出现 bug? @fejta-bot 只会自动“修复”(关闭)它们。 无需考虑错误。 一切都很好。

我想知道什么时候/是否有维护者会关心/评论?

我同意kubernetes上的“

如果决定核心 k8s 不应该扩展到这个功能,那么我同意上面的评论,即应该删除 cronjob 支持,以便鼓励人们按照他们的选择采用生态系统解决方案。 这在核心 k8s 中确实突出,它没有明确预期的结果,并且会绊倒人们。

由于 Go 1.15 现在在其核心库中有一个time/tzdata包,可能……?

我应该如何在早上 7 点到晚上 7 点过度配置我的集群?
我的用户在哪里,有夏令时和冬令时。
所以我完全不能依赖它。

不使用 cronjobs 管理时区是您做出的一个非常奇怪的决定。

我们找到了解决此问题的好方法:停止使用 K8s CronJobs 并改用 Apache Airflow。

自从我们这样做以来,生活变得更好了。 加入我们!

此问题已在外部解决: https :

@马特法里纳

  1. 如果解决方案被广泛采用并且可以被所有人使用(包括小规模、多集群等),那么可以考虑将其用于核心Kubernetes

如何以及何时衡量社区解决方案的采用情况?

@mattfarina @soltysh现在使用KEP-19:将 CronJob 毕业到 stable ,其中提到时区作为考虑的改进之一,已被批准并合并,并且cronjob 控制器 v2的工作正在进行中,这个问题可以重新打开并重新考虑吗?

它提到这是一种考虑/可能的改进。 它不保证是否或何时会接近。 我可以 100% 保证它不会在 CronJob GA 之前发生,这将需要这个和另外 2 个版本。

@soltysh仍然可以适当讨论。 已经广泛证明这是一个必要的特征。 坚持在这条路上踢球表明维护者和用户之间存在巨大的脱节。

@benlangfeld我对此非常开放,但时间是这里的主要限制因素:失望:

@benlangfeld我对此非常开放,但时间是这里的主要限制因素😞

已经有一个建议的修复程序。 你需要什么输入才能被接受?

控制器正在被重写,这是目前的主要焦点。 只有使用新控制器才能进行更改。 改变要被替换的旧的是没有意义的。

此页面是否有帮助?
0 / 5 - 0 等级