Це завдання демонструє запуск кількох Jobs на основі спільного шаблону. Цей підхід можна використовувати для паралельної обробки пакетів роботи.
У цьому прикладі є лише три елементи: apple, banana та cherry. Приклади Jobs обробляють кожен елемент, виводячи рядок, а потім роблячи паузу.
Дивіться використання Jobs у реальних робочих навантаженнях, щоб дізнатися, як цей шаблон підходить для реалістичніших сценаріїв.
Ви маєте знати базове, непаралельне використання Job.
Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:
Для базового шаблонування вам потрібна утиліта командного рядка sed.
Для виконання прикладу з розширеним шаблонуванням потрібен робочий Python і бібліотека шаблонів Jinja2 для Python.
Після налаштування Python ви можете встановити Jinja2, виконавши:
pip install --user jinja2
Спочатку завантажте наведений нижче шаблон Job у файл job-tmpl.yaml. Ось що ви завантажите:
apiVersion: batch/v1
kind: Job
metadata:
name: process-item-$ITEM
labels:
jobgroup: jobexample
spec:
template:
metadata:
name: jobexample
labels:
jobgroup: jobexample
spec:
containers:
- name: c
image: busybox:1.28
command: ["sh", "-c", "echo Processing item $ITEM && sleep 5"]
restartPolicy: Never
# Використайте curl для завантаження job-tmpl.yaml
curl -L -s -O https://k8s.io/examples/application/job/job-tmpl.yaml
Завантажений файл ще не є чинним маніфестом Kubernetes. Натомість цей шаблон є поданням обʼєкта Job у YAML із заповнювачами, які потрібно заповнити перед використанням. Синтаксис $ITEM нічого не означає для Kubernetes.
Наведений нижче фрагмент оболонки використовує sed, щоб замінити рядок $ITEM змінною циклу, записуючи результат у тимчасову теку jobs. Виконайте його зараз:
# Розгорніть шаблон у кілька файлів, по одному для кожного елемента, який потрібно обробити.
mkdir ./jobs
for i in apple banana cherry
do
cat job-tmpl.yaml | sed "s/\$ITEM/$i/" > ./jobs/job-$i.yaml
done
Перевірте, чи це спрацювало:
ls jobs/
Вивід подібний до такого:
job-apple.yaml
job-banana.yaml
job-cherry.yaml
Ви можете використовувати будь-яку мову шаблонів (наприклад, Jinja2 або ERB) або написати програму для генерації маніфестів Job.
Далі створіть усі Jobs однією командою kubectl:
kubectl create -f ./jobs
Вивід подібний до такого:
job.batch/process-item-apple created
job.batch/process-item-banana created
job.batch/process-item-cherry created
Тепер перевірте Jobs:
kubectl get jobs -l jobgroup=jobexample
Вивід подібний до такого:
NAME COMPLETIONS DURATION AGE
process-item-apple 1/1 14s 22s
process-item-banana 1/1 12s 21s
process-item-cherry 1/1 12s 20s
Параметр -l для kubectl вибирає лише Jobs, що належать до цієї групи Jobs (у системі можуть бути інші, не повʼязані Jobs).
Ви також можете перевірити стан Podʼів, використовуючи той самий селектор міток:
kubectl get pods -l jobgroup=jobexample
Вивід подібний до такого:
NAME READY STATUS RESTARTS AGE
process-item-apple-kixwv 0/1 Completed 0 4m
process-item-banana-wrsf7 0/1 Completed 0 4m
process-item-cherry-dnfu9 0/1 Completed 0 4m
Цією однією командою можна переглянути вивід усіх Jobs одразу:
kubectl logs -f -l jobgroup=jobexample
Вивід має бути таким:
Processing item apple
Processing item banana
Processing item cherry
# Видаліть створені вами Jobs
# Ваш кластер автоматично очищає їхні Podʼи
kubectl delete job -l jobgroup=jobexample
У першому прикладі кожен екземпляр шаблону мав один параметр, і цей параметр також використовувався в назві Job. Однак назви можуть містити лише певні символи.
Цей трохи складніший приклад використовує мову шаблонів Jinja, щоб згенерувати маніфести, а потім обʼєкти з цих маніфестів, із кількома параметрами для кожного Job.
У цій частині завдання ви використаєте однорядковий скрипт Python, щоб перетворити шаблон на набір маніфестів.
Спочатку скопіюйте й вставте наведений нижче шаблон обʼєкта Job у файл job.yaml.jinja2:
{% set params = [{ "name": "apple", "url": "http://dbpedia.org/resource/Apple", },
{ "name": "banana", "url": "http://dbpedia.org/resource/Banana", },
{ "name": "cherry", "url": "http://dbpedia.org/resource/Cherry" }]
%}
{% for p in params %}
{% set name = p["name"] %}
{% set url = p["url"] %}
---
apiVersion: batch/v1
kind: Job
metadata:
name: jobexample-{{ name }}
labels:
jobgroup: jobexample
spec:
template:
metadata:
name: jobexample
labels:
jobgroup: jobexample
spec:
containers:
- name: c
image: busybox:1.28
command: ["sh", "-c", "echo Processing URL {{ url }} && sleep 5"]
restartPolicy: Never
{% endfor %}
Наведений вище шаблон визначає два параметри для кожного обʼєкта Job за допомогою списку словників Python (рядки 1-4). Цикл for генерує один маніфест Job для кожного набору параметрів (решта рядків).
Цей приклад спирається на можливість YAML. Один файл YAML може містити кілька документів (у цьому випадку маніфестів Kubernetes), розділених рядком ---. Ви можете передати вивід безпосередньо до kubectl, щоб створити Jobs.
Далі використайте цю однорядкову програму Python, щоб розгорнути шаблон:
alias render_template='python -c "from jinja2 import Template; import sys; print(Template(sys.stdin.read()).render());"'
Використайте render_template, щоб перетворити параметри й шаблон на один файл YAML із маніфестами Kubernetes:
# Це потребує визначеного раніше псевдоніма
cat job.yaml.jinja2 | render_template > jobs.yaml
Ви можете переглянути jobs.yaml, щоб переконатися, що скрипт render_template спрацював правильно.
Коли ви переконаєтеся, що render_template працює так, як задумано, можна передати його вивід до kubectl:
cat job.yaml.jinja2 | render_template | kubectl apply -f -
Kubernetes приймає та запускає створені вами Jobs.
# Видаліть створені вами Jobs
# Ваш кластер автоматично очищає їхні Podʼи
kubectl delete job -l jobgroup=jobexample
У реальному сценарії кожен Job виконує значні обчислення, наприклад рендеринг кадру фільму або обробку діапазону рядків у базі даних. Якщо ви рендерите фільм, $ITEM слід задати як номер кадру. Якщо ви обробляєте рядки таблиці бази даних, $ITEM має представляти діапазон рядків для обробки.
У цьому завданні ви виконали команду, щоб зібрати вивід Podʼів, отримавши їхні логи. У реальному сценарії кожен Pod Job записує свій вивід у надійне сховище перед завершенням. Можна використовувати PersistentVolume для кожного Job або зовнішній сервіс зберігання. Наприклад, якщо ви рендерите кадри фільму, надсилайте дані готового кадру за допомогою HTTP PUT на URL, використовуючи окрему URL-адресу для кожного кадру.
Після створення Job Kubernetes автоматично додає мітки, які відрізняють Podʼи одного Job від Podʼів іншого Job.
У цьому прикладі кожен Job та його шаблон Pod мають мітку: jobgroup=jobexample.
Сам Kubernetes не звертає уваги на мітки з назвою jobgroup. Мітка на всіх Jobs, створених із шаблону, дає змогу зручно працювати з усіма цими Jobs одразу. У першому прикладі ви використали шаблон для створення кількох Jobs. Шаблон гарантує, що кожен Pod також отримує ту саму мітку, тож ви можете перевірити всі Podʼи цих Jobs однією командою.
jobgroup не є особливим чи зарезервованим. Ви можете обрати власну схему міток. За бажання можна використовувати рекомендовані мітки.Якщо ви плануєте створити велику кількість обʼєктів Job, ви можете виявити, що:
Існують інші шаблони Job, які можна використовувати для обробки великих обсягів роботи без створення дуже великої кількості обʼєктів Job.
Ви також можете розглянути можливість написання власного контролера, щоб автоматично керувати обʼєктами Job.