Kubernetes 设计模式笔记 —— Job & CronJ

2023-06-18  本文已影响0人  rollingstarky

Batch Job

Batch Job 模式适合处理隔离的原子化的工作任务,能够在分布式的环境中,可靠地运行 short-lived Pods,直到工作任务成功地结束。

在 Kubernetes 中,可以通过不同的方式创建 Pod:

上述 Pod 有一个共同点,它们都代表着长时间运行的进程,并不是在一段时间后就需要被关掉。但是在某些场景下,仍需要执行一类预先定义好的、有限的工作流,当该工作流程可靠地完成后,再关闭对应的容器。

Kubernetes Job 类似于 ReplicaSet,它也会创建 1 个或者多个 Pods 并确保它们成功运行。区别在于,当特定数量的 Pods 成功终止后,Job 就变为完成状态,不会再有额外的 Pod 被启动。

apiVersion: batch/v1
kind: Job
metadata:
  name: random-generator
spec:
  completions: 5
  parallelism: 2
  template:
    metadata:
      name: random-generator
    spec:
      restartPolicy: OnFailure
      containers:
      - image: k8spatterns/random-generator:1.0
        name: random-generator
        command: [ "java", "-cp", "/", "RandomRunner", "/numbers.txt", "10000" ]

比如上面配置的 Job,会确保有 5 个 Pod 成功执行完毕,可以有两个 Pod 同时运行。此外,Job 配置文件中的 restartPolicy 是必需的,且其值只能是 OnFailureNever,不能是 Always

为什么不通过 bare Pods 来执行 Job 对应的任务呢?因为 Job 相比于 bare Pods,能够提供更多可靠性和扩展性方面的好处。

两个字段对控制 Job 的行为发挥着关键作用:

Parallel Batch Job with a fixed completion count

基于上述两个参数,Job 可以分为如下几种类型:

总结

Job 帮助我们将隔离的工作单元变成一个可靠的、可扩展的执行单元。并不是所有的服务都需要一直运行,比如某些服务可能需要按需运行,某些必须在特定的时间窗口运行,某些必须按照计划重复执行。
通过 Job 可以只在需要的时候运行 Pod,且任务完成后就退出。使用 Job 处理 short-lived 任务可以节约系统资源。

Periodic Job

Periodic Job 是对 Batch Job 的扩展,为其添加了时间维度,同时允许临时的事件触发工作流的执行。
在分布式系统的世界里,有一种比较清晰的倾向,借助 HTTP 和轻量的消息系统实现实时、事件驱动的应用。不考虑软件开发中的此类倾向,计划任务仍然是一种历史悠久且至今常用的手段。
它们通常用于自动化的系统维护工作或者管理员任务,在商业应用方面的场景比如文件同步、发送邮件、清理和归档旧文件等。

传统的处理 Periodic Job 的方式是借助专门的计划任务软件比如 Cron。但是 Cron jobs 运行在单一的服务器上,难以维护且有发生单点故障的风险。
这也是为什么很多开发者会尝试实现自己的方案,比如 Java 中的 Quartz、Spring Batch 等。但是类似于 Cron,它们也会遇到弹性和高可用性方面的挑战,导致较高的资源使消耗。此外在这类方案里,Job 调度器是应用的一部分,为了获得高可用,通常就需要运行多个应用实例,同时还需要确保同一时刻下只有一个实例是活跃的。从而引入 leader election 等分布式系统问题。

面对以上的一些问题,Kubernetes 实现了 CronJob,允许开发者以广为熟知的 Cron 格式将 Job 设置为计划任务。

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: random-generator
spec:
  # Every three minutes
  schedule: "*/3 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - image: k8spatterns/random-generator:1.0
            name: random-generator
            command: [ "java", "-cp", "/", "RandomRunner", "/numbers.txt", "10000" ]
restartPolicy: OnFailure

与 Job 相比,CronJob 有一些额外的字段:

总结

CronJob 其实是一个非常简单的原语,在现有的 Job 定义中添加类似 Cron 的行为。但是当它与 Kubernetes 提供的其他原语比如 Pods、资源隔离结合起来时,就成为一个非常强大的任务调度系统。
它的调度行为是平台的一部分,实现在应用的外部,使得开发者能够专注于应用的业务逻辑,无需在应用内部额外设计一套调度逻辑。同时提供了高可用、高弹性、高容积以及由策略驱动的 Pod 部署等特性。
当然,和 Job 一样,CronJob 容器在部署时,也需要考虑所有的特殊情况,比如重复执行、未触发、并发执行和任务取消等。

参考资料

Kubernetes Patterns

上一篇 下一篇

猜你喜欢

热点阅读