【重识云原生】第六章容器基础6.4.7.2节——CronJob

【重识云原生】第六章容器基础6.4.7.2节——CronJob_第1张图片

 

  《重识云原生系列》专题索引:

  1. 第一章——不谋全局不足以谋一域
  2. 第二章计算第1节——计算虚拟化技术总述
  3. 第二章计算第2节——主流虚拟化技术之VMare ESXi
  4. 第二章计算第3节——主流虚拟化技术之Xen
  5. 第二章计算第4节——主流虚拟化技术之KVM
  6. 第二章计算第5节——商用云主机方案
  7. 第二章计算第6节——裸金属方案
  8. 第三章云存储第1节——分布式云存储总述
  9. 第三章云存储第2节——SPDK方案综述
  10. 第三章云存储第3节——Ceph统一存储方案
  11. 第三章云存储第4节——OpenStack Swift 对象存储方案
  12. 第三章云存储第5节——商用分布式云存储方案
  13. 第四章云网络第一节——云网络技术发展简述
  14. 第四章云网络4.2节——相关基础知识准备
  15. 第四章云网络4.3节——重要网络协议
  16. 第四章云网络4.3.1节——路由技术简述
  17. 第四章云网络4.3.2节——VLAN技术
  18. 第四章云网络4.3.3节——RIP协议
  19. 第四章云网络4.3.4节——OSPF协议
  20. 第四章云网络4.3.5节——EIGRP协议
  21. 第四章云网络4.3.6节——IS-IS协议
  22. 第四章云网络4.3.7节——BGP协议
  23. 第四章云网络4.3.7.2节——BGP协议概述
  24. 第四章云网络4.3.7.3节——BGP协议实现原理
  25. 第四章云网络4.3.7.4节——高级特性
  26. 第四章云网络4.3.7.5节——实操
  27. 第四章云网络4.3.7.6节——MP-BGP协议
  28. 第四章云网络4.3.8节——策略路由
  29. 第四章云网络4.3.9节——Graceful Restart(平滑重启)技术
  30. 第四章云网络4.3.10节——VXLAN技术
  31. 第四章云网络4.3.10.2节——VXLAN Overlay网络方案设计
  32. 第四章云网络4.3.10.3节——VXLAN隧道机制
  33. 第四章云网络4.3.10.4节——VXLAN报文转发过程
  34. 第四章云网络4.3.10.5节——VXlan组网架构
  35. 第四章云网络4.3.10.6节——VXLAN应用部署方案
  36. 第四章云网络4.4节——Spine-Leaf网络架构
  37. 第四章云网络4.5节——大二层网络
  38. 第四章云网络4.6节——Underlay 和 Overlay概念
  39. 第四章云网络4.7.1节——网络虚拟化与卸载加速技术的演进简述
  40. 第四章云网络4.7.2节——virtio网络半虚拟化简介
  41. 第四章云网络4.7.3节——Vhost-net方案
  42. 第四章云网络4.7.4节vhost-user方案——virtio的DPDK卸载方案
  43. 第四章云网络4.7.5节vDPA方案——virtio的半硬件虚拟化实现
  44. 第四章云网络4.7.6节——virtio-blk存储虚拟化方案
  45. 第四章云网络4.7.8节——SR-IOV方案
  46. 第四章云网络4.7.9节——NFV
  47. 第四章云网络4.8.1节——SDN总述
  48. 第四章云网络4.8.2.1节——OpenFlow概述
  49. 第四章云网络4.8.2.2节——OpenFlow协议详解
  50. 第四章云网络4.8.2.3节——OpenFlow运行机制
  51. 第四章云网络4.8.3.1节——Open vSwitch简介
  52. 第四章云网络4.8.3.2节——Open vSwitch工作原理详解
  53. 第四章云网络4.8.4节——OpenStack与SDN的集成
  54. 第四章云网络4.8.5节——OpenDayLight
  55. 第四章云网络4.8.6节——Dragonflow
  56.  第四章云网络4.9.1节——网络卸载加速技术综述

  57. 第四章云网络4.9.2节——传统网络卸载技术

  58. 第四章云网络4.9.3.1节——DPDK技术综述

  59. 第四章云网络4.9.3.2节——DPDK原理详解

  60. 第四章云网络4.9.4.1节——智能网卡SmartNIC方案综述

  61. 第四章云网络4.9.4.2节——智能网卡实现

  62. 第六章容器6.1.1节——容器综述

  63. 第六章容器6.1.2节——容器安装部署

  64. 第六章容器6.1.3节——Docker常用命令

  65. 第六章容器6.1.4节——Docker核心技术LXC

  66. 第六章容器6.1.5节——Docker核心技术Namespace

  67. 第六章容器6.1.6节—— Docker核心技术Chroot

  68. 第六章容器6.1.7.1节——Docker核心技术cgroups综述

  69. 第六章容器6.1.7.2节——cgroups原理剖析

  70. 第六章容器6.1.7.3节——cgroups数据结构剖析

  71. 第六章容器6.1.7.4节——cgroups使用

  72. 第六章容器6.1.8节——Docker核心技术UnionFS

  73. 第六章容器6.1.9节——Docker镜像技术剖析

  74. 第六章容器6.1.10节——DockerFile解析

  75. 第六章容器6.1.11节——docker-compose容器编排

  76. 第六章容器6.1.12节——Docker网络模型设计

  77. 第六章容器6.2.1节——Kubernetes概述

  78. 第六章容器6.2.2节——K8S架构剖析

  79. 第六章容器6.3.1节——K8S核心组件总述

  80. 第六章容器6.3.2节——API Server组件

  81. 第六章容器6.3.3节——Kube-Scheduler使用篇

  82. 第六章容器6.3.4节——etcd组件

  83. 第六章容器6.3.5节——Controller Manager概述

  84. 第六章容器6.3.6节——kubelet组件

  85. 第六章容器6.3.7节——命令行工具kubectl

  86. 第六章容器6.3.8节——kube-proxy

  87. 第六章容器6.4.1节——K8S资源对象总览

  88. 第六章容器6.4.2.1节——pod详解

  89. 第六章容器6.4.2.2节——Pod使用(上)

  90. 第六章容器6.4.2.3节——Pod使用(下)

  91. 第六章容器6.4.3节——ReplicationController

  92. 第六章容器6.4.4节——ReplicaSet组件

  93. 第六章容器基础6.4.5.1节——Deployment概述

  94. 第六章容器基础6.4.5.2节——Deployment配置详细说明

  95. 第六章容器基础6.4.5.3节——Deployment实现原理解析

  96. 第六章容器基础6.4.6节——Daemonset

  97. 第六章容器基础6.4.7节——Job

  98. 第六章容器基础6.4.8节——CronJob

1 CronJob概述

        CronJob 创建基于时隔重复调度的 Jobs。

        一个 CronJob 对象就像 crontab (cron table) 文件中的一行。 它用 Cron 格式进行编写, 并周期性地在给定的调度时间执行 Job。

1.1 介绍

        CronJob控制器以Job控制器资源为其管控对象,并借助它管理pod资源对象,Job控制器定义的作业任务在其控制器资源创建之后便会立即执行,但CronJob可以以类似于Linux操作系统的周期性任务作业计划的方式控制其运行时间点及重复运行的方式。也就是说,CronJob可以在特定的时间点(反复的)去运行job任务。

【重识云原生】第六章容器基础6.4.7.2节——CronJob_第2张图片

Cron Job 管理基于时间的 Job,即:

  • 在给定时间点只运行一次
  • 周期性地在给定时间点运行

        使用条件:当前使用的 Kubernetes 集群,版本 >= 1.8(对 CronJob)

典型的用法如下所示:

  • 在给定的时间点调度 Job 运行
  • 创建周期性运行的 Job,例如:数据库备份、发送邮件

注意:所有 CronJob 的 schedule: 时间都是基于 kube-controller-manager. 的时区。

        如果你的控制平面在 Pod 或是裸容器中运行了 kube-controller-manager, 那么为该容器所设置的时区将会决定 Cron Job 的控制器所使用的时区。

1.2 使用示例

        下面的 CronJob 示例清单会在每分钟打印出当前时间和问候消息:application/job/cronjob.yaml 

apiVersion: batch/v1 
kind: CronJob 
metadata: 
  name: hello 
  spec: 
    schedule: "* * * * *" 
    jobTemplate: 
      spec: 
        template: 
          spec: 
            containers: 
              - name: hello 
                image: busybox:1.28 
                imagePullPolicy: IfNotPresent 
                command: 
                  - /bin/sh 
                  - -c 
                  - date; echo Hello from the Kubernetes cluster 
            restartPolicy: OnFailure

使用 CronJob 运行自动化任务 一文会为你详细讲解此例。

1.3 Cron 时间表语法

# ┌───────────── 分钟 (0 - 59)

# │ ┌───────────── 小时 (0 - 23)

# │ │ ┌───────────── 月的某天 (1 - 31)

# │ │ │ ┌───────────── 月份 (1 - 12)

# │ │ │ │ ┌───────────── 周的某天 (0 - 6)(周日到周一;在某些系统上,7 也是星期日)

# │ │ │ │ │                或者是 sun,mon,tue,web,thu,fri,sat

# │ │ │ │ │

# │ │ │ │ │

# * * * * *

输入

描述

相当于

@yearly (or @annually)

每年 1 月 1 日的午夜运行一次

0 0 1 1 *

@monthly

每月第一天的午夜运行一次

0 0 1 * *

@weekly

每周的周日午夜运行一次

0 0 * * 0

@daily (or @midnight)

每天午夜运行一次

0 0 * * *

@hourly

每小时的开始一次

0 * * * *

        例如,下面这行指出必须在每个星期五的午夜以及每个月 13 号的午夜开始任务:

0 0 13 * 5

        要生成 CronJob 时间表表达式,你还可以使用 crontab.guru 之类的 Web 工具。

1.4 时区

        对于没有指定时区的 CronJob,kube-controller-manager 基于本地时区解释排期表(Schedule)。

特性状态: Kubernetes v1.25 [beta]

        如果启用了 CronJobTimeZone 特性门控, 你可以为 CronJob 指定一个时区(如果你没有启用该特性门控,或者你使用的是不支持试验性时区功能的 Kubernetes 版本,集群中所有 CronJob 的时区都是未指定的)。

        启用该特性后,你可以将 spec.timeZone 设置为有效时区名称。 例如,设置 spec.timeZone: "Etc/UTC" 指示 Kubernetes 采用 UTC 来解释排期表。

        Go 标准库中的时区数据库包含在二进制文件中,并用作备用数据库,以防系统上没有可用的外部数据库。

1.5 CronJob 限制

        CronJob 根据其计划编排,在每次该执行任务的时候大约会创建一个 Job。 我们之所以说 "大约",是因为在某些情况下,可能会创建两个 Job,或者不会创建任何 Job。 我们试图使这些情况尽量少发生,但不能完全杜绝。因此,Job 应该是 幂等的。

        如果 startingDeadlineSeconds 设置为很大的数值或未设置(默认),并且 concurrencyPolicy 设置为 Allow,则作业将始终至少运行一次。注意:

        如果 startingDeadlineSeconds 的设置值低于 10 秒钟,CronJob 可能无法被调度。 这是因为 CronJob 控制器每 10 秒钟执行一次检查。

        对于每个 CronJob,CronJob 控制器(Controller) 检查从上一次调度的时间点到现在所错过了调度次数。如果错过的调度次数超过 100 次, 那么它就不会启动这个任务,并记录这个错误:

Cannot determine if job needs to be started. Too many missed start time (> 100). Set or decrease .spec.startingDeadlineSeconds or check clock skew.

        需要注意的是,如果 startingDeadlineSeconds 字段非空,则控制器会统计从 startingDeadlineSeconds 设置的值到现在而不是从上一个计划时间到现在错过了多少次 Job。 例如,如果 startingDeadlineSeconds 是 200,则控制器会统计在过去 200 秒中错过了多少次 Job。

        如果未能在调度时间内创建 CronJob,则计为错过。 例如,如果 concurrencyPolicy 被设置为 Forbid,并且当前有一个调度仍在运行的情况下, 试图调度的 CronJob 将被计算为错过。

        例如,假设一个 CronJob 被设置为从 08:30:00 开始每隔一分钟创建一个新的 Job, 并且它的 startingDeadlineSeconds 字段未被设置。如果 CronJob 控制器从 08:29:00 到 10:21:00 终止运行,则该 Job 将不会启动,因为其错过的调度 次数超过了 100。

        为了进一步阐述这个概念,假设将 CronJob 设置为从 08:30:00 开始每隔一分钟创建一个新的 Job, 并将其 startingDeadlineSeconds 字段设置为 200 秒。 如果 CronJob 控制器恰好在与上一个示例相同的时间段(08:29:00 到 10:21:00)终止运行, 则 Job 仍将从 10:22:00 开始。 造成这种情况的原因是控制器现在检查在最近 200 秒(即 3 个错过的调度)中发生了多少次错过的 Job 调度,而不是从现在为止的最后一个调度时间开始。

        CronJob 仅负责创建与其调度时间相匹配的 Job,而 Job 又负责管理其代表的 Pod。

2 CronJob使用

2.1 yaml文件字段简述

apiVersion: batch/v1beta1 # batch/v1beta1 #1.21+ batch/v1 
kind: CronJob 
metadata: 
  labels: 
    run: hello 
    name: hello 
    namespace: default 
spec: 
  concurrencyPolicy: Allow # 并发调度策略。可选参数如下 
  # Allow:允许同时运行多个任务。 
  # Forbid:不允许并发运行,如果之前的任务尚未完成,新的任务不会被创建。 
  # Replace:如果之前的任务尚未完成,新的任务会替换的之前的任务。 
  failedJobsHistoryLimit: 1 # 保留多少失败的任务 
  jobTemplate: 
    metadata: 
      spec: 
        template: 
          metadata: 
            labels: 
              run: hello 
          spec: 
            containers: 
              - args: 
                - /bin/sh 
                - -c 
                - date; echo Hello from the Kubernetes cluster 
              image: registry.cn-beijing.aliyuncs.com/dotbalo/busybox 
              imagePullPolicy: Always 
              name: hello 
            resources: {} 
            restartPolicy: OnFailure # 重启策略,和Pod一致 
            securityContext: {} 
  schedule: '*/1 * * * *' # 调度周期,和Linux一致,分别是分时日月周。 
  successfulJobsHistoryLimit: 3 # 保留多少已完成的任务,按需配置 
  suspend: false # 如果设置为true,则暂停后续的任务,默认为false。

2.2 CronJob Spec字段说明

  • .spec.schedule:调度,必需字段,指定任务运行周期,格式同 Cron
  • .spec.jobTemplate:Job 模板,必需字段,指定需要运行的任务,格式同 Job
  • .spec.startingDeadlineSeconds :启动 Job 的期限(秒级别),该字段是可选的。如果因为任何原因而错过了被调度的时间,那么错过执行时间的 Job 将被认为是失败的。如果没有指定,则没有期限
  • .spec.concurrencyPolicy:并发策略,该字段也是可选的。它指定了如何处理被 Cron Job 创建的 Job 的并发执行。只允许指定下面策略中的一种:
    • Allow(默认):允许并发运行 Job
    • Forbid:禁止并发运行,如果前一个还没有完成,则直接跳过下一个
    • Replace:取消当前正在运行的 Job,用一个新的来替换

注意,当前策略只能应用于同一个 Cron Job 创建的 Job。如果存在多个 Cron Job,它们创建的 Job 之间总是允许并发运行。

  • .spec.suspend :挂起,该字段也是可选的。如果设置为 true,后续所有执行都会被挂起。它对已经开始执行的 Job 不起作用。默认值为 false。
  • .spec.successfulJobsHistoryLimit 和 .spec.failedJobsHistoryLimit :历史限制,是可选的字段。它们指定了可以保留多少完成和失败的 Job。默认情况下,它们分别设置为 3 和 1。设置限制的值为 0,相关类型的 Job 完成后将不会被保留。

2.3 常规操作

2.3.1 运行CronJob

$ kubectl create -f ./cronjob.yaml

cronjob "hello" created

或者通过祈使命令行方式:

$ kubectl run hello --schedule="*/1 * * * *" --restart=OnFailure --image=busybox -- /bin/sh -c "date; echo Hello from the Kubernetes cluster"

cronjob "hello" created

2.3.2 查看CronJob状态

$ kubectl get cronjob hello

NAME   SCHEDULE  SUSPEND ACTIVE LAST-SCHEDULE

hello   */1****  False    0         
  • NAME:CronJob名称。
  • SCHEDULE:基于时间的调度规则。
  • SUSPEND:如果其值为True表示此CronJob暂时失效,不变成False之前不再创建新任务。对于已经创建的任务没有影响。
  • ACTIVE:表示当前活动的任务数,0表示当前没有活动任务。1表示有一个活动任务。此值可能大于1,原因如下:

1.任务允许重复启动,如前一次启动后还没有退出,下一次已经启动。

2.允许延后启动,当CronJob Controller发现因为某种原因错误启动,并且任务允许延后启动,则会启动任务。

  • LAST-SCHEDULE:表示最后一次调度时间,表示未曾调度过任务。

        从CronJob状态可以看出,其输出中并没有相关字段指示其所创建的JOB是否运行成功,运行如上命令查看JOB的详细信息:

2.3.3 查看CronJob创建的Job

$ kubectl get jobs --watch

NAME             DESIRED SUCCESSFUL AGE

hello-4111706356    1        1       2s
  • NAME:表示CronJob创建的Job名称,后边的数字由系统自动生成,保证不重复。
  • DESIRED:表示CronJob只创建的是最简单的一次Job,只创建一个pod。
  • SUCCESSFUL:表示pod成功个数。
  • AGE:表示上JOB生存时间。

再次查看CronJob:

$ kubectl get cronjob hello

NAME  SCHEDULE SUSPEND ACTIVE LAST-SCHEDULE

hello */1****   False    0     Mon, 29 Aug 2016 14:34:00 -0700

        LAST-SCHEDULE表示最近一次调度时间,ACTIVE为0表示实例已经运行结束。

        CronJob创建Job,Job创建pod,已经获知CronJob创建的Job名称:hello-4111706356,查看pod方法如下:

# Replace "hello-4111706356" with the job name in your system

$ pods=$(kubectl get pods --show-all --selector=job-name=hello-4111706356 --output=jsonpath={.items..metadata.name})

$ echo $pods

hello-4111706356-o9qcm

$ kubectl logs $pods

Mon Aug 29 21:34:09 UTC 2016

Hello from the Kubernetes cluster

2.3.4 删除CronJob

$ kubectl delete cronjob hello

cronjob "hello" deleted

        删除CronJob会导致其创建的Job、pod一起被删除。

 参考链接

CronJob · Kubernetes指南

CronJob | Kubernetes

Kubernetes JobCronJob 控制器_疯子@123的博客-CSDN博客

深入K8S Job(三):cronJob controller源码分析 - UCloud云社区

Kubernetes(十)Kubernetes Job 和 CronJob 的实现原理_liu_weiliang10405的博客-CSDN博客

Kubernetes实战(八)-定时任务(Cronjob)_张志翔 ̮的博客-CSDN博客

Kubernetes K8S之资源控制器Job和CronJob详解 - 踏歌行666 - 博客园

7.深入k8s:任务调用Job与CronJob及源码分析

Kubernetes(k8s)计划任务Job&CronJob

K8s ❉ Job 与 CronJob控制器详解_wangjie722703的博客-CSDN博客

你可能感兴趣的:(云原生-IaaS专栏,kubernetes,云原生,容器,CronJob,Pod,1024程序员节)