Kubernetes CronJob

2022-05-06 09:29 更新

CronJob

CronJob 用于執(zhí)行周期性的動作,例如備份、報告生成等。 這些任務(wù)中的每一個都應(yīng)該配置為周期性重復的(例如:每天/每周/每月一次); 你可以定義任務(wù)開始執(zhí)行的時間間隔。

FEATURE STATE: Kubernetes v1.21 [stable]

CronJob 創(chuàng)建基于時隔重復調(diào)度的 Jobs。

一個 CronJob 對象就像 crontab (cron table) 文件中的一行。 它用 Cron 格式進行編寫, 并周期性地在給定的調(diào)度時間執(zhí)行 Job。

所有 CronJob 的 ?schedule?: 時間都是基于 kube-controller-manager. 的時區(qū)。
如果你的控制平面在 Pod 或是裸容器中運行了 kube-controller-manager, 那么為該容器所設(shè)置的時區(qū)將會決定 Cron Job 的控制器所使用的時區(qū)。

Kubernetes 項目官方并不支持設(shè)置如 ?CRON_TZ ?或者 ?TZ ?等變量。 ?CRON_TZ ?或者 ?TZ ?是用于解析和計算下一個 Job 創(chuàng)建時間所使用的內(nèi)部庫中一個實現(xiàn)細節(jié)。 不建議在生產(chǎn)集群中使用它。

為 CronJob 資源創(chuàng)建清單時,請確保所提供的名稱是一個合法的 DNS 子域名. 名稱不能超過 52 個字符。 這是因為 CronJob 控制器將自動在提供的 Job 名稱后附加 11 個字符,并且存在一個限制, 即 Job 名稱的最大長度不能超過 63 個字符。

示例

下面的 CronJob 示例清單會在每分鐘打印出當前時間和問候消息:

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

Cron 時間表語法

# ┌───────────── 分鐘 (0 - 59)
# │ ┌───────────── 小時 (0 - 23)
# │ │ ┌───────────── 月的某天 (1 - 31)
# │ │ │ ┌───────────── 月份 (1 - 12)
# │ │ │ │ ┌───────────── 周的某天 (0 - 6)(周日到周一;在某些系統(tǒng)上,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 號的午夜開始任務(wù):

?0 0 13 * 5 ?

要生成 CronJob 時間表表達式,你還可以使用 crontab.guru 之類的 Web 工具。

CronJob 限制 

CronJob 根據(jù)其計劃編排,在每次該執(zhí)行任務(wù)的時候大約會創(chuàng)建一個 Job。 我們之所以說 "大約",是因為在某些情況下,可能會創(chuàng)建兩個 Job,或者不會創(chuàng)建任何 Job。 我們試圖使這些情況盡量少發(fā)生,但不能完全杜絕。因此,Job 應(yīng)該是 冪等的。

如果 ?startingDeadlineSeconds ?設(shè)置為很大的數(shù)值或未設(shè)置(默認),并且 ?concurrencyPolicy ?設(shè)置為 ?Allow?,則作業(yè)將始終至少運行一次。

如果 ?startingDeadlineSeconds ?的設(shè)置值低于 10 秒鐘,CronJob 可能無法被調(diào)度。 這是因為 CronJob 控制器每 10 秒鐘執(zhí)行一次檢查。

對于每個 CronJob,CronJob 控制器(Controller) 檢查從上一次調(diào)度的時間點到現(xiàn)在所錯過了調(diào)度次數(shù)。如果錯過的調(diào)度次數(shù)超過 100 次, 那么它就不會啟動這個任務(wù),并記錄這個錯誤:

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

需要注意的是,如果 ?startingDeadlineSeconds ?字段非空,則控制器會統(tǒng)計從 ?startingDeadlineSeconds ?設(shè)置的值到現(xiàn)在而不是從上一個計劃時間到現(xiàn)在錯過了多少次 Job。 例如,如果 ?startingDeadlineSeconds ?是 ?200?,則控制器會統(tǒng)計在過去 200 秒中錯過了多少次 Job。

如果未能在調(diào)度時間內(nèi)創(chuàng)建 CronJob,則計為錯過。 例如,如果 ?concurrencyPolicy ?被設(shè)置為 ?Forbid?,并且當前有一個調(diào)度仍在運行的情況下, 試圖調(diào)度的 CronJob 將被計算為錯過。

例如,假設(shè)一個 CronJob 被設(shè)置為從 ?08:30:00? 開始每隔一分鐘創(chuàng)建一個新的 Job, 并且它的 ?startingDeadlineSeconds ?字段未被設(shè)置。如果 CronJob 控制器從 ?08:29:00? 到 ?10:21:00? 終止運行,則該 Job 將不會啟動,因為其錯過的調(diào)度 次數(shù)超過了 100。

為了進一步闡述這個概念,假設(shè)將 CronJob 設(shè)置為從 ?08:30:00? 開始每隔一分鐘創(chuàng)建一個新的 Job, 并將其 ?startingDeadlineSeconds ?字段設(shè)置為 200 秒。 如果 CronJob 控制器恰好在與上一個示例相同的時間段(?08:29:00? 到 ?10:21:00?)終止運行, 則 Job 仍將從 ?10:22:00? 開始。 造成這種情況的原因是控制器現(xiàn)在檢查在最近 200 秒(即 3 個錯過的調(diào)度)中發(fā)生了多少次錯過的 Job 調(diào)度,而不是從現(xiàn)在為止的最后一個調(diào)度時間開始。

CronJob 僅負責創(chuàng)建與其調(diào)度時間相匹配的 Job,而 Job 又負責管理其代表的 Pod。

控制器版本 

從 Kubernetes v1.21 版本開始,CronJob 控制器的第二個版本被用作默認實現(xiàn)。 要禁用此默認 CronJob 控制器而使用原來的 CronJob 控制器,請在 kube-controller-manager 中設(shè)置特性門控 ?CronJobControllerV2?,將此標志設(shè)置為 ?false?。例如:

--feature-gates="CronJobControllerV2=false"


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號