У цьому прикладі ви запустите Job Kubernetes, який використовує кілька паралельних робочих процесів. Кожен робочий процес — це окремий контейнер, що працює у власному Podʼі. Podʼи мають індексний номер, який автоматично встановлює панель управління, і це дозволяє кожному Podʼу визначити, над якою частиною загального завдання працювати.
Індекс Podʼа доступний в анотації batch.kubernetes.io/job-completion-index як рядок із його десятковим значенням. Щоб контейнеризований процес завдання отримав цей індекс, можна опублікувати значення анотації за допомогою механізму downward API. Для зручності панель управління автоматично налаштовує downward API так, щоб індекс був доступний у змінній середовища JOB_COMPLETION_INDEX.
Нижче наведено огляд кроків у цьому прикладі:
Indexed Job на основі цього маніфесту.Ви вже маєте знати базове, непаралельне використання Job.
Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:
Версія вашого Kubernetes сервера має бути не старішою ніж v1.21.Для перевірки версії введіть kubectl version.
Щоб отримати доступ до робочого елемента з програми робочого процесу, є кілька варіантів:
JOB_COMPLETION_INDEX. Контролер Job автоматично повʼязує цю змінну з анотацією, що містить індекс завершення.У цьому прикладі уявіть, що ви обрали варіант 3 і хочете запустити утиліту rev. Ця програма приймає файл як аргумент і виводить його вміст у зворотному порядку.
rev data.txt
Ви використаєте інструмент rev з образу контейнера busybox.
Оскільки це лише приклад, кожен Pod виконує лише дрібну частину роботи (розвертає короткий рядок). У реальному робочому навантаженні ви могли б, наприклад, створити Job, що представляє завдання створення 60 секунд відео на основі даних сцени. Кожним робочим елементом у Job рендерингу відео був би рендеринг певного кадру цього відеокліпу. Індексоване завершення означало б, що кожен Pod у Job знає, який кадр рендерити й публікувати, рахуючи кадри від початку кліпу.
Ось приклад маніфесту Job, який використовує режим завершення Indexed:
apiVersion: batch/v1
kind: Job
metadata:
name: 'indexed-job'
spec:
completions: 5
parallelism: 3
completionMode: Indexed
template:
spec:
restartPolicy: Never
initContainers:
- name: 'input'
image: 'docker.io/library/bash'
command:
- "bash"
- "-c"
- |
items=(foo bar baz qux xyz)
echo ${items[$JOB_COMPLETION_INDEX]} > /input/data.txt
volumeMounts:
- mountPath: /input
name: input
containers:
- name: 'worker'
image: 'docker.io/library/busybox'
command:
- "rev"
- "/input/data.txt"
volumeMounts:
- mountPath: /input
name: input
volumes:
- name: input
emptyDir: {}
У наведеному вище прикладі ви використовуєте вбудовану змінну середовища JOB_COMPLETION_INDEX, яку контролер Job встановлює для всіх контейнерів. Init-контейнер зіставляє індекс зі статичним значенням і записує його у файл, спільний із контейнером робочого процесу через том emptyDir. За бажання можна визначити власну змінну середовища через downward API, щоб публікувати індекс у контейнери. Також можна завантажити список значень із ConfigMap як змінну середовища або файл.
Або ви можете безпосередньо використати downward API для передачі значення анотації як файлу тому, як показано в наведеному нижче прикладі:
apiVersion: batch/v1
kind: Job
metadata:
name: 'indexed-job'
spec:
completions: 5
parallelism: 3
completionMode: Indexed
template:
spec:
restartPolicy: Never
containers:
- name: 'worker'
image: 'docker.io/library/busybox'
command:
- "rev"
- "/input/data.txt"
volumeMounts:
- mountPath: /input
name: input
volumes:
- name: input
downwardAPI:
items:
- path: "data.txt"
fieldRef:
fieldPath: metadata.annotations['batch.kubernetes.io/job-completion-index']Тепер запустіть Job:
# Це використовує перший підхід (покладаючись на $JOB_COMPLETION_INDEX)
kubectl apply -f https://kubernetes.io/examples/application/job/indexed-job.yaml
Коли ви створюєте цей Job, панель управління створює серію Podʼів, по одному для кожного вказаного індексу. Значення .spec.parallelism визначає, скільки їх може працювати одночасно, а .spec.completions визначає, скільки Podʼів Job створює загалом.
Оскільки .spec.parallelism менше за .spec.completions, панель управління чекає завершення деяких перших Podʼів, перш ніж запускати нові.
Ви можете зачекати на успішне завершення Job із тайм-аутом:
# Перевірка назви умови не залежить від регістру
kubectl wait --for=condition=complete --timeout=300s job/indexed-job
Тепер перегляньте опис Job і переконайтеся, що він успішний.
kubectl describe jobs/indexed-job
Вивід подібний до такого:
Name: indexed-job
Namespace: default
Selector: controller-uid=bf865e04-0b67-483b-9a90-74cfc4c3e756
Labels: controller-uid=bf865e04-0b67-483b-9a90-74cfc4c3e756
job-name=indexed-job
Annotations: <none>
Parallelism: 3
Completions: 5
Start Time: Thu, 11 Mar 2021 15:47:34 +0000
Pods Statuses: 2 Running / 3 Succeeded / 0 Failed
Completed Indexes: 0-2
Pod Template:
Labels: controller-uid=bf865e04-0b67-483b-9a90-74cfc4c3e756
job-name=indexed-job
Init Containers:
input:
Image: docker.io/library/bash
Port: <none>
Host Port: <none>
Command:
bash
-c
items=(foo bar baz qux xyz)
echo ${items[$JOB_COMPLETION_INDEX]} > /input/data.txt
Environment: <none>
Mounts:
/input from input (rw)
Containers:
worker:
Image: docker.io/library/busybox
Port: <none>
Host Port: <none>
Command:
rev
/input/data.txt
Environment: <none>
Mounts:
/input from input (rw)
Volumes:
input:
Type: EmptyDir (a temporary directory that shares a pod's lifetime)
Medium:
SizeLimit: <unset>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 4s job-controller Created pod: indexed-job-njkjj
Normal SuccessfulCreate 4s job-controller Created pod: indexed-job-9kd4h
Normal SuccessfulCreate 4s job-controller Created pod: indexed-job-qjwsz
Normal SuccessfulCreate 1s job-controller Created pod: indexed-job-fdhq5
Normal SuccessfulCreate 1s job-controller Created pod: indexed-job-ncslj
У цьому прикладі ви запускаєте Job із власними значеннями для кожного індексу. Ви можете переглянути вивід одного з Podʼів:
kubectl logs indexed-job-fdhq5 # Змініть це на назву Podʼа з цього Job
Вивід подібний до такого:
xuq