使用工作队列进行Kubernetes作业调度

时间:2018-07-22 02:14:44

标签: cron kubernetes scheduled-tasks job-scheduling kubernetes-mesos

我们正在使用Kubernetes / go-lang编写包裹递送跟踪器应用程序。一切都很好,直到我们遇到了有一定调度需求并且无法弄清楚该使用什么的障碍。用例是:

  1. 一旦分配了包裹并将其运送出去,就应该跟踪其位置。
  2. 如果包裹在到达仓库3小时后仍未分配,则应将其标记为“明天交货”。
  3. 一些常见的cron型工作。

对于#1,我们计划安排一个作业,该作业每10秒会轮询一次包裹的位置。但这是一次工作。包装交付后。它应该消失了。

对于#2,我们计划安排一个定时/定时作业,该作业将由我们的API触发。计划在仓库收到包裹后的3个小时内完成这项工作。

我们上面的#3是用于各种内部目的的常规任务。

我们希望使用单个调度平台来满足所有这些类型的需求。

由于我们仅使用Kubernetes,因此我们想利用其作业调度功能。但是我们对此有一定的怀疑。

  1. 我们可以从源代码创建这些作业吗?如here所述。但是我不确定我们的系统管理员是否允许我们这样做。
  2. 我已经阅读了Kubernetes中的工作队列,在这里我们可以将工作推送到工作队列,而使用者将为这些工作项创建工作。

    但是,我不知道如何为该工作队列创建一个永久的使用者守护程序,该守护程序将轮询该队列并为每个工作项创建作业。

    另一个疑问是如何在此处安排简单的cron作业(上面的#3)。

我也听说过Kala,但不确定在Kubernetes世界中如何适应。

任何参考,指针,链接或建议都将受到高度赞赏,因为我通常对Kubernetes / Golang还是陌生的,而且在Google上也找不到任何具体的东西。

1 个答案:

答案 0 :(得分:1)

有多少个包裹?您提到的时间间隔有多重要?我想到了几种方法:

Kubernetes cron jobs 可以按计划运行,并且可以解决您的第三项需求。如果您有“一些”软件包(我不一定会尝试使用“数百”个软件包),则可以为每个软件包创建一个新的cron作业,该作业运行一次,然后将其删除。 Cron作业每分钟最多只能运行一次。如果您可以将“每10秒轮询一次”的要求放宽到“每分钟轮询一次”的要求,并且打包的数量很少,那么您可以通过这种方式进行所有操作。

对于第二个要求,您可以每隔一个间隔检查每个包装的有效期。如果对“ 3小时后”的要求不是特别严格,则效果更好。编写一个查看每个软件包的程序,如果经过了三个小时的延迟,则更改其状态,然后编写一个每15分钟运行一次的cron作业。围绕此问题的扩展问题有所不同,但“查找过期的软件包”听起来像是单个SQL查询;这取决于您的后端技术。

您可以编写一个长期运行的程序,该程序可以执行所有基于间隔的检查。您暗示使用Go,可以设置一个time.Timer每10秒触发一次(整个程序一次或每个程序包一次)。我可能会让程序在内存中知道每个程序包ID,其当前状态以及何时需要将状态更改为“明天交货”,然后在一个进程中运行所有这些程序。一个普通的部署可以解决这个问题。您还应该将此状态保存在数据库中,这可能会引入一些扩展限制。

最后,您可以使用消息队列系统RabbitMQ是流行的开源选择。您可以安排消息延迟(发送消息以TTL为10秒交换路由到队列package.in的{​​{1}},将该队列的dead-letter exchange设置为{ {1}},将其发送到队列package.wait,并使应用程序从该队列中使用。同样,您将编写一个长期运行的过程;该项目从队列中获取项目,从数据库中检索其状态,轮询其当前位置,并将其标记为“明天交货”,或视情况在package.ready中对其进行排队。这是可扩展性最高的答案(您可以通过Kubernetes部署启动许多工作人员),但也最少使用内置的Kubernetes部件。