Skip to content

فصل ۱۲ — Jobها

تا اینجا روی فرایندهای long-running مثل databaseها و web applicationها تمرکز کردیم. این نوع workloadها تا زمانی که upgrade شوند یا دیگر به سرویس نیاز نباشد اجرا می‌مانند. اگرچه فرایندهای long-running بخش عمده workloadهایی هستند که روی یک cluster Kubernetes اجرا می‌شوند، اغلب نیاز به اجرای taskهای کوتاه‌مدت و one-off هم هست. شیء Job برای مدیریت این نوع taskها ساخته شده است.

یک Job، Podهایی می‌سازد که تا termination موفق (یعنی exit با کد ۰) اجرا می‌شوند. در مقابل، یک Pod معمولی بدون توجه به exit code مداوم restart می‌شود. Jobها برای کارهایی که فقط یک‌بار می‌خواهید انجام دهید مفیدند، مثل database migration یا batch job. اگر به‌صورت Pod معمولی اجرا شود، task migration پایگاه داده در یک loop اجرا می‌شود و بعد از هر exit مداوم پایگاه داده را دوباره populate می‌کند.

در این فصل رایج‌ترین الگوهای Job که Kubernetes فراهم می‌کند را بررسی می‌کنیم. این الگوها را در سناریوهای واقعی هم به کار می‌گیریم.

شیء Job

شیء Job مسئول ساخت و مدیریت Podهایی است که در template داخل specification Job تعریف شده‌اند. این Podها عموماً تا completion موفق اجرا می‌شوند. شیء Job هماهنگی اجرای تعدادی Pod به‌صورت موازی را مدیریت می‌کند.

اگر Pod قبل از termination موفق fail کند، job controller بر اساس Pod template در specification Job یک Pod جدید می‌سازد. از آنجا که Podها باید schedule شوند، احتمال دارد Job اجرا نشود اگر scheduler منابع لازم را پیدا نکند. همچنین به‌خاطر ماهیت سیستم‌های توزیع‌شده، در برخی سناریوهای failure احتمال کمی وجود دارد که Podهای duplicate برای یک task ساخته شوند.

الگوهای Job

Jobها برای مدیریت workloadهای batch-like طراحی شده‌اند که work itemها توسط یک یا چند Pod پردازش می‌شوند. به‌طور پیش‌فرض هر Job یک Pod را یک‌بار تا termination موفق اجرا می‌کند. این الگوی Job با دو attribute اصلی Job تعریف می‌شود: تعداد completionهای Job و تعداد Podهایی که به‌صورت موازی اجرا می‌شوند. در الگوی «یک‌بار تا completion»، پارامترهای completions و parallelism روی ۱ تنظیم می‌شوند.

جدول ۱۲-۱ الگوهای Job را بر اساس ترکیب completions و parallelism در پیکربندی Job نشان می‌دهد.

نوعUse caseرفتارcompletionsparallelism
One shotDatabase migrationهایک Pod که یک‌بار تا termination موفق اجرا می‌شود11
Parallel fixed completionsچند Pod که مجموعه‌ای از کار را به‌صورت موازی پردازش می‌کنندیک یا چند Pod که یک یا چند بار اجرا می‌شوند تا به تعداد completion ثابت برسند1+1+
Work queue: parallel jobsچند Pod که از یک work queue متمرکز پردازش می‌کنندیک یا چند Pod که یک‌بار تا termination موفق اجرا می‌شوند12+

One Shot

Jobهای one-shot راهی برای اجرای یک Pod یک‌بار تا termination موفق فراهم می‌کنند. اگرچه ممکن است ساده به نظر برسد، کارهایی برای انجام درست آن لازم است. اول باید Pod ساخته و به Kubernetes API submit شود. این با Pod template تعریف‌شده در پیکربندی Job انجام می‌شود. وقتی Job up and running است، Pod پشتیبان Job برای termination موفق monitor می‌شود. Job به دلایل مختلفی می‌تواند fail کند، از جمله خطای application، exception uncaught در runtime، یا failure node قبل از اینکه Job فرصت complete شدن داشته باشد. در همه موارد، job controller مسئول recreate کردن Pod تا occurrence termination موفق است.

راه‌های متعددی برای ساخت one-shot Job در Kubernetes وجود دارد. ساده‌ترین استفاده از ابزار خط فرمان kubectl است:

$ kubectl run -i oneshot \
  --image=gcr.io/kuar-demo/kuard-amd64:blue \
  --restart=OnFailure \
  -- --keygen-enable \
     --keygen-exit-on-complete \
     --keygen-num-to-gen 10

...

(ID 0) Workload starting
(ID 0 1/10) Item done: SHA256:nAsUsG54XoKRkJwyN+OShkUPKew3mwq7OCc
(ID 0 2/10) Item done: SHA256:HVKX1ANns6SgF/er1lyo+ZCdnB8geFGt0/8
(ID 0 3/10) Item done: SHA256:irjCLRov3mTT0P0JfsvUyhKRQ1TdGR8H1jg
(ID 0 4/10) Item done: SHA256:nbQAIVY/yrhmEGk3Ui2sAHuxb/o6mYO0qRk
(ID 0 5/10) Item done: SHA256:CCpBoXNlXOMQvR2v38yqimXGAa/w2Tym+aI
(ID 0 6/10) Item done: SHA256:wEY2TTIDz4ATjcr1iimxavCzZzNjRmbOQp8
(ID 0 7/10) Item done: SHA256:t3JSrCt7sQweBgqG5CrbMoBulwk4lfDWiTI
(ID 0 8/10) Item done: SHA256:E84/Vze7KKyjCh9OZh02MkXJGoty9PhaCec
(ID 0 9/10) Item done: SHA256:UOmYex79qqbI1MhcIfG4hDnGKonlsij2k3s
(ID 0 10/10) Item done: SHA256:WCR8wIGOFag84Bsa8f/9QHuKqF+0mEnCADY
(ID 0) Workload exiting

نکاتی که باید توجه کنید:

  • گزینه -i در kubectl نشان می‌دهد این دستور interactive است. kubectl تا وقتی Job running باشد منتظر می‌ماند و سپس log output از اولین (و در این مورد تنها) Pod در Job را نشان می‌دهد.
  • --restart=OnFailure گزینه‌ای است که به kubectl می‌گوید یک شیء Job بسازد.
  • همه گزینه‌ها بعد از -- آرگومان‌های خط فرمان به container image هستند. این‌ها به test server ما (kuard) می‌گویند ۱۰ کلید SSH ۴٬۰۹۶-bit تولید کند و سپس exit کند.
  • خروجی شما ممکن است دقیقاً مطابق این نباشد. kubectl اغلب با گزینه -i چند خط اول output را از دست می‌دهد.

بعد از completion Job، شیء Job و Pod مرتبط هنوز باقی می‌مانند تا بتوانید log output را inspect کنید. توجه کنید این Job در kubectl get jobs دیده نمی‌شود مگر flag -a بدهید. بدون این flag، kubectl Jobهای completed را مخفی می‌کند. قبل از ادامه Job را حذف کنید:

$ kubectl delete jobs oneshot

گزینه دیگر برای ساخت one-shot Job استفاده از فایل پیکربندی است، همان‌طور که در مثال ۱۲-۱ نشان داده شده.

مثال ۱۲-۱. job-oneshot.yaml

yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: oneshot
spec:
  template:
    spec:
      containers:
      - name: kuard
        image: gcr.io/kuar-demo/kuard-amd64:blue
        imagePullPolicy: Always
        args:
        - "--keygen-enable"
        - "--keygen-exit-on-complete"
        - "--keygen-num-to-gen=10"
      restartPolicy: OnFailure

Job را با دستور kubectl apply submit کنید:

$ kubectl apply -f job-oneshot.yaml
job "oneshot" created

سپس Job oneshot را describe کنید:

$ kubectl describe jobs oneshot

Name:           oneshot
Namespace:      default
Image(s):       gcr.io/kuar-demo/kuard-amd64:blue
Selector:       controller-uid=cf87484b-e664-11e6-8222-42010a8a007b
Parallelism:    1
Completions:    1
Start Time:     Sun, 29 Jan 2017 12:52:13 -0800
Labels:         Job=oneshot
Pods Statuses: 0 Running / 1 Succeeded / 0 Failed
No volumes.
Events:
  ... Reason             Message
  ... ------             -------
  ... SuccessfulCreate   Created pod: oneshot-4kfdt

نتایج Job را با نگاه به logهای Pod ساخته‌شده می‌بینید:

$ kubectl logs oneshot-4kfdt

...
Serving on :8080
(ID 0) Workload starting
(ID 0 1/10) Item done: SHA256:+r6b4W81DbEjxMcD3LHjU+EIGnLEzbpxITKn8IqhkPI
(ID 0 2/10) Item done: SHA256:mzHewajaY1KA8VluSLOnNMk9fDE5zdn7vvBS5Ne8AxM
(ID 0 3/10) Item done: SHA256:TRtEQHfflJmwkqnNyGgQm/IvXNykSBIg8c03h0g3onE
(ID 0 4/10) Item done: SHA256:tSwPYH/J347il/mgqTxRRdeZcOazEtgZlA8A3/HWbro
(ID 0 5/10) Item done: SHA256:IP8XtguJ6GbWwLHqjKecVfdS96B17nnO21I/TNc1j9k
(ID 0 6/10) Item done: SHA256:ZfNxdQvuST/6ZzEVkyxdRG98p73c/5TM99SEbPeRWfc
(ID 0 7/10) Item done: SHA256:tH+CNl/IUl/HUuKdMsq2XEmDQ8oAvmhMO6Iwj8ZEOj0
(ID 0 8/10) Item done: SHA256:3GfsUaALVEHQcGNLBOu4Qd1zqqqJ8j738i5r+I5XwVI
(ID 0 9/10) Item done: SHA256:5wV4L/xEiHSJXwLUT2fHf0SCKM2g3XH3sVtNbgskCXw
(ID 0 10/10) Item done: SHA256:bPqqOonwSbjzLqe9ZuVRmZkz+DBjaNTZ9HwmQhbdWLI
(ID 0) Workload exiting

تبریک، Job شما با موفقیت اجرا شد!

ممکن است متوجه شده باشید هنگام ساخت شیء Job هیچ labelی مشخص نکردیم. مثل controllerهای دیگر (DaemonSetها، ReplicaSetها، deploymentها و غیره) که از label برای شناسایی مجموعه‌ای از Podها استفاده می‌کنند، اگر Pod در چند object reuse شود رفتارهای غیرمنتظره رخ می‌دهد. چون Jobها شروع و پایان محدود دارند، رایج است کاربران زیادی از آن‌ها بسازند. این انتخاب labelهای یکتا را سخت‌تر و حیاتی‌تر می‌کند. به همین دلیل، شیء Job به‌طور خودکار یک label یکتا انتخاب می‌کند و از آن برای شناسایی Podهایی که می‌سازد استفاده می‌کند. در سناریوهای پیشرفته (مثل جایگزینی Job در حال اجرا بدون kill کردن Podهای تحت مدیریتش)، کاربران می‌توانند این رفتار خودکار را خاموش کنند و labelها و selectorها را دستی مشخص کنند.

Pod failure

تازه دیدیم Job چطور با موفقیت complete می‌شود. اما اگر چیزی fail شود چه می‌شود؟ بیایید امتحان کنیم.

آرگومان‌های kuard را در فایل پیکربندی تغییر دهید تا بعد از تولید سه کلید با exit code غیرصفر fail کند، همان‌طور که در مثال ۱۲-۲ نشان داده شده.

مثال ۱۲-۲. job-oneshot-failure1.yaml

yaml
...
spec:
  template:
    spec:
      containers:
        ...
        args:
        - "--keygen-enable"
        - "--keygen-exit-on-complete"
        - "--keygen-exit-code=1"
        - "--keygen-num-to-gen=3"
...

حالا با kubectl apply -f job-oneshot-failure1.yaml اجرا کنید. کمی بگذارید run شود و سپس وضعیت Pod را ببینید:

$ kubectl get pod -a -l job-name=oneshot

NAME            READY      STATUS                RESTARTS     AGE
oneshot-3ddk0   0/1        CrashLoopBackOff      4            3m

اینجا می‌بینیم همان Pod چهار بار restart شده. Kubernetes برای این Pod در CrashLoopBackOff است. غیرمعمول نیست باگی جایی باشد که برنامه به محض start crash کند. در آن صورت Kubernetes کمی صبر می‌کند قبل از restart Pod تا crash loop منابع node را نخورد. همه این‌ها local به node توسط kubelet بدون دخالت Job مدیریت می‌شود.

Job را kill کنید (kubectl delete jobs oneshot) و چیز دیگری امتحان کنیم. دوباره فایل config را تغییر دهید و restartPolicy را از OnFailure به Never. با kubectl apply -f jobs-oneshot-failure2.yaml اجرا کنید.

اگر کمی بگذارید run شود و Podهای مرتبط را ببینید، چیز جالبی پیدا می‌کنید:

$ kubectl get pod -l job-name=oneshot -a

NAME                 READY   STATUS    RESTARTS   AGE
oneshot-0wm49        0/1     Error     0          1m
oneshot-6h9s2        0/1     Error     0          39s
oneshot-hkzw0        1/1     Running   0          6s
oneshot-k5swz        0/1     Error     0          28s
oneshot-m1rdw        0/1     Error     0          19s
oneshot-x157b        0/1     Error     0          57s

می‌بینیم چند Pod اینجا error داده‌اند. با restartPolicy: Never به kubelet می‌گوییم Pod را در failure restart نکند، بلکه Pod را failed اعلام کند. سپس شیء Job متوجه می‌شود و Pod جایگزین می‌سازد. اگر دقت نکنید، «junk» زیادی در cluster ایجاد می‌شود. به همین دلیل پیشنهاد می‌کنیم restartPolicy: OnFailure استفاده کنید تا Podهای failed در همان جا دوباره run شوند.

با kubectl delete jobs oneshot پاک کنید.

تا اینجا دیدیم برنامه با exit با exit code غیرصفر fail می‌کند. اما workerها راه‌های دیگر هم fail می‌کنند؛ مثلاً stuck می‌شوند و پیشرفت نمی‌کنند. برای پوشش این حالت می‌توانید liveness probe با Jobها استفاده کنید. اگر policy liveness probe تشخیص دهد Pod مرده است، برایتان restart/replace می‌شود.

Parallelism

تولید کلید می‌تواند کند باشد. بیایید تعداد زیادی worker با هم start کنیم تا تولید کلید سریع‌تر شود. از ترکیب پارامترهای completions و parallelism استفاده می‌کنیم. هدف ما تولید ۱۰۰ کلید با ۱۰ run از kuard است که هر run ۱۰ کلید تولید کند. اما نمی‌خواهیم cluster را غرق کنیم، پس خود را به پنج Pod همزمان محدود می‌کنیم.

این یعنی completions روی ۱۰ و parallelism روی ۵. پیکربندی در مثال ۱۲-۳ نشان داده شده.

مثال ۱۲-۳. job-parallel.yaml

yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: parallel
  labels:
    chapter: jobs
spec:
  parallelism: 5
  completions: 10
  template:
    metadata:
      labels:
        chapter: jobs
    spec:
      containers:
      - name: kuard
        image: gcr.io/kuar-demo/kuard-amd64:blue
        imagePullPolicy: Always
        args:
        - "--keygen-enable"
        - "--keygen-exit-on-complete"
        - "--keygen-num-to-gen=10"
      restartPolicy: OnFailure

start کنید:

$ kubectl apply -f job-parallel.yaml
job "parallel" created

حالا ببینید Podها up می‌شوند، کارشان را انجام می‌دهند و exit می‌کنند. Podهای جدید تا وقتی ۱۰ تا altogether complete شوند ساخته می‌شوند. اینجا flag --watch را استفاده می‌کنیم تا kubectl بماند و تغییرات را list کند:

$ kubectl get pods -w
NAME             READY        STATUS    RESTARTS    AGE
parallel-55tlv   1/1          Running   0           5s
parallel-5s7s9   1/1          Running   0           5s
parallel-jp7bj   1/1          Running   0           5s
parallel-lssmn   1/1          Running   0           5s
parallel-qxcxp   1/1          Running   0           5s
NAME             READY        STATUS      RESTARTS     AGE
parallel-jp7bj   0/1          Completed   0            26s
parallel-tzp9n   0/1          Pending   0          0s
parallel-tzp9n   0/1          Pending   0          0s
parallel-tzp9n   0/1          ContainerCreating    0         1s
parallel-tzp9n   1/1          Running   0          1s
parallel-tzp9n   0/1          Completed   0           48s
parallel-x1kmr   0/1          Pending   0          0s
parallel-x1kmr   0/1          Pending   0          0s
parallel-x1kmr   0/1          ContainerCreating    0         0s
parallel-x1kmr   1/1          Running   0         1s
parallel-5s7s9   0/1          Completed   0         1m
parallel-tprfj   0/1          Pending   0         0s
parallel-tprfj   0/1          Pending   0         0s
parallel-tprfj   0/1          ContainerCreating   0        0s
parallel-tprfj   1/1          Running   0         2s
parallel-x1kmr   0/1          Completed   0          52s
parallel-bgvz5   0/1          Pending   0         0s
parallel-bgvz5   0/1          Pending   0         0s
parallel-bgvz5   0/1          ContainerCreating   0        0s
parallel-bgvz5   1/1          Running   0         2s
parallel-qxcxp   0/1          Completed   0          2m
parallel-xplw2   0/1          Pending   0         1s
parallel-xplw2   0/1          Pending   0         1s
parallel-xplw2   0/1          ContainerCreating   0        1s
parallel-xplw2   1/1          Running   0         3s
parallel-bgvz5   0/1          Completed   0          40s
parallel-55tlv   0/1          Completed   0          2m
parallel-lssmn   0/1          Completed   0          2m

Jobهای completed را study کنید و logهایشان را برای fingerprint کلیدهای تولیدشده ببینید. با kubectl delete job parallel شیء Job تمام‌شده را پاک کنید.

Work Queueها

use case رایج Jobها پردازش کار از یک work queue است. در این سناریو، taskی تعدادی work item می‌سازد و در work queue publish می‌کند. یک worker Job می‌تواند اجرا شود تا هر work item را پردازش کند تا work queue خالی شود (شکل ۱۲-۱).

شکل ۱۲-۱. Jobهای موازی

راه‌اندازی work queue

اول یک سرویس work queue متمرکز launch می‌کنیم. kuard یک سیستم work queue ساده مبتنی بر memory دارد. یک instance از kuard start می‌کنیم تا coordinator همه کارها باشد.

بعد یک ReplicaSet ساده برای مدیریت singleton work queue daemon می‌سازیم. از ReplicaSet استفاده می‌کنیم تا در صورت failure machine، Pod جدید ساخته شود، همان‌طور که در مثال ۱۲-۴ نشان داده شده.

مثال ۱۲-۴. rs-queue.yaml

yaml
apiVersion: extensions/v1beta1
kind: ReplicaSet
metadata:
  labels:
    app: work-queue
    component: queue
    chapter: jobs
  name: queue
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: work-queue
        component: queue
        chapter: jobs
    spec:
      containers:
      - name: queue
        image: "gcr.io/kuar-demo/kuard-amd64:blue"
        imagePullPolicy: Always

work queue را با دستور زیر اجرا کنید:

$ kubectl apply -f rs-queue.yaml

در این نقطه work queue daemon باید up and running باشد. از port forwarding برای اتصال استفاده کنید. این دستور را در یک terminal window running نگه دارید:

$ QUEUE_POD=$(kubectl get pods -l app=work-queue,component=queue \
    -o jsonpath='{.items[0].metadata.name}')
$ kubectl port-forward $QUEUE_POD 8080:8080
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080

مرورگر را به http://localhost:8080 باز کنید و interface kuard را ببینید. به تب «MemQ Server» بروید تا اتفاقات را ببینید.

با work queue server آماده، باید آن را با service expose کنیم. این برای producerها و consumerها پیدا کردن work queue از طریق DNS آسان می‌شود، همان‌طور که مثال ۱۲-۵ نشان می‌دهد.

مثال ۱۲-۵. service-queue.yaml

yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: work-queue
    component: queue
    chapter: jobs
  name: queue
spec:
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    app: work-queue
    component: queue

queue service را با kubectl بسازید:

$ kubectl apply -f service-queue.yaml
service "queue" created

پر کردن queue

حالا آماده‌ایم work itemهای زیادی در queue بگذاریم. برای سادگی فقط از curl برای drive کردن API سرور work queue استفاده می‌کنیم و work itemهای زیادی insert می‌کنیم. curl از طریق kubectl port-forward که قبلاً setup کردیم با work queue ارتباط برقرار می‌کند، همان‌طور که در مثال ۱۲-۶ نشان داده شده.

مثال ۱۲-۶. load-queue.sh

bash
# Create a work queue called 'keygen'
curl -X PUT localhost:8080/memq/server/queues/keygen

# Create 100 work items and load up the queue.
for i in work-item-{0..99}; do
  curl -X POST localhost:8080/memq/server/queues/keygen/enqueue \
     -d "$i"
done

این دستورات را اجرا کنید؛ باید ۱۰۰ شیء JSON با message identifier یکتا برای هر work item در terminal ببینید. وضعیت queue را با تب «MemQ Server» در UI یا مستقیماً از API work queue تأیید کنید:

$ curl 127.0.0.1:8080/memq/server/stats
{
    "kind": "stats",
    "queues": [
        {
            "depth": 100,
            "dequeued": 0,
            "drained": 0,
            "enqueued": 100,
            "name": "keygen"
        }
    ]
}

حالا آماده‌ایم Jobی kick off کنیم که work queue را تا خالی شدن consume کند.

ساخت consumer Job

اینجا جالب می‌شود! kuard می‌تواند در حالت consumer هم عمل کند. می‌توانیم آن را setup کنیم work itemها را از work queue بکشد، کلید بسازد و وقتی queue خالی شد exit کند، همان‌طور که در مثال ۱۲-۷ نشان داده شده.

مثال ۱۲-۷. job-consumers.yaml

yaml
apiVersion: batch/v1
kind: Job
metadata:
  labels:
    app: message-queue
    component: consumer
    chapter: jobs
  name: consumers
spec:
  parallelism: 5
  template:
    metadata:
      labels:
        app: message-queue
        component: consumer
        chapter: jobs
    spec:
      containers:
      - name: worker
        image: "gcr.io/kuar-demo/kuard-amd64:blue"
        imagePullPolicy: Always
        args:
        - "--keygen-enable"
        - "--keygen-exit-on-complete"
        - "--keygen-memq-server=http://queue:8080/memq/server"
        - "--keygen-memq-queue=keygen"
      restartPolicy: OnFailure

اینجا به Job می‌گوییم پنج Pod به‌صورت موازی start کند. چون پارامتر completions تنظیم نشده، Job را در حالت worker pool قرار می‌دهیم. وقتی اولین Pod با exit code صفر exit کند، Job شروع به winding down می‌کند و Pod جدید start نمی‌کند. یعنی هیچ worker نباید exit کند تا کار تمام شود و همه در حال finish up باشند.

consumers Job را بسازید:

$ kubectl apply -f job-consumers.yaml
job "consumers" created

بعد از ساخت Job، Podهای پشتیبان Job را ببینید:

$ kubectl get pods
NAME               READY    STATUS      RESTARTS   AGE
queue-43s87        1/1      Running     0          5m
consumers-6wjxc    1/1      Running     0          2m
consumers-7l5mh    1/1      Running     0          2m
consumers-hvz42    1/1      Running     0          2m
consumers-pc8hr    1/1      Running     0          2m
consumers-w20cc    1/1      Running     0          2m

پنج Pod به‌صورت موازی running هستند. این Podها تا خالی شدن work queue running می‌مانند. در UI روی work queue server می‌توانید ببینید. با خالی شدن queue، consumer Podها cleanly exit می‌کنند و consumers Job complete در نظر گرفته می‌شود.

پاک‌سازی

با labelها همه چیزهایی که در این بخش ساختیم را پاک می‌کنیم:

$ kubectl delete rs,svc,job -l chapter=jobs

CronJobها

گاهی می‌خواهید Job را در interval مشخصی schedule کنید. برای این کار می‌توانید CronJob در Kubernetes declare کنید که مسئول ساخت شیء Job جدید در interval مشخص است. declaration CronJob شبیه این است:

yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: example-cron
spec:
  # Run every fifth hour
  schedule: "0 */5 * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: batch-job
            image: my-batch-image
          restartPolicy: OnFailure

به فیلد spec.schedule توجه کنید که interval CronJob را در فرمت cron استاندارد دارد.

می‌توانید این فایل را cron-job.yaml ذخیره کنید و CronJob را با kubectl create -f cron-job.yaml بسازید. اگر به وضعیت فعلی CronJob علاقه دارید، kubectl describe <cron-job> جزئیات را می‌دهد.

خلاصه

روی یک cluster، Kubernetes هم workloadهای long-running مثل web applicationها و هم workloadهای کوتاه‌مدت مثل batch jobها را handle می‌کند. abstraction Job به شما اجازه می‌دهد الگوهای batch job از taskهای one-time ساده تا Jobهای موازی که تا اتمام کار many item پردازش می‌کنند را model کنید.

Jobها primitive سطح پایین هستند و برای workloadهای ساده مستقیماً قابل استفاده‌اند. اما Kubernetes از پایه extensible با objectهای سطح بالاتر ساخته شده. Jobها هم exception نیستند؛ به‌راحتی توسط سیستم‌های orchestration سطح بالاتر برای taskهای پیچیده‌تر استفاده می‌شوند.