Job: разовая задача до конца
Контроллер для миграций и бэкапов: completions, backoffLimit, restartPolicy и почему Job нельзя чистить удалением Pod.
Что вообще такое Job
Deployment предполагает «приложение работает вечно». Если контейнер вышел, его перезапустят. Job устроен наоборот: «выполни задачу до конца и остановись». Это для миграций БД, бэкапов, разовой конвертации данных, генерации отчёта.
Job это контроллер batch/v1. Создаёт Pod по spec.template, ждёт
exit 0, помечает себя Succeeded. Pod падает с ненулевым кодом, Job
создаст новый Pod и попробует снова, пока не упрётся в
backoffLimit.
Job вычисляет статус из Pod, которые сам же создал. Pod у Job обычно
остаются в кластере после завершения, чтобы можно было посмотреть
логи. Чистка идёт по ttlSecondsAfterFinished (если задано) или
руками.
kubectl delete pod у Job бесполезен: контроллер тут же создаст
замену. Чтобы Job перестал плодить Pod, удаляют сам Job.
Минимальный YAML
apiVersion: batch/v1
kind: Job
metadata:
name: hello-job
spec:
completions: 1
backoffLimit: 2
template:
spec:
restartPolicy: Never
containers:
- name: hello
image: busybox:1.36
command: ["sh", "-c", "echo done; exit 0"]
Разбор полей:
completions: 1. Сколько успешных Pod нужно, чтобы Job считался завершённым. Поставить 5 - контроллер создаст пять Pod по очереди и будет ждать пятого success. Удобно для шардированных задач.parallelism: 1. Сколько Pod можно держать запущенными одновременно. Дефолт 1. Сочетается сcompletions.backoffLimit: 2. Сколько раз подряд Pod может упасть, прежде чем Job станет Failed. Дефолт 6, это много для прода. Сломанный bash за полчаса создаст 7 Pod и потратит alert-бюджет.restartPolicy. В Job толькоOnFailureилиNever.Alwaysapiserver отвергнет. Логика простая: рестартами рулит Job, kubelet не лезет.activeDeadlineSeconds. Жёсткий таймаут на весь Job, не на Pod. Прошло, Job убивает все Pod и становится Failed.ttlSecondsAfterFinished. Удалить Job (и его Pod) через N секунд после завершения. Без него мусор копится.
restartPolicy: Never vs OnFailure
При OnFailure kubelet рестартит сам контейнер на том же Pod. При
Never Job создаёт новый Pod на каждый ретрай. Поведение видно
по-разному: с OnFailure kubectl get pods показывает один Pod с
несколькими рестартами, с Never несколько Pod. На дашбордах
удобнее Never, виден каждый ретрай.
restartPolicy | Кто перезапускает | Что видно в kubectl get pods |
|---|---|---|
Never | Job создаёт новый Pod | несколько Pod, по одному на ретрай |
OnFailure | kubelet рестартит контейнер | один Pod с растущим числом рестартов |
Always | никто, манифест не примут | apiserver отвергает Job |
Связанные команды
kubectl create job hello --image=busybox -- sh -c 'echo done'
kubectl get jobs
kubectl get pods -l job-name=hello
kubectl logs -l job-name=hello
kubectl wait --for=condition=complete job/hello --timeout=60s
kubectl delete job hello
Схему полей всегда можно посмотреть прямо из кластера:
kubectl explain job.spec
kubectl explain job.spec.backoffLimit
kubectl explain job.spec.template.spec.restartPolicy
Что часто ломается
restartPolicy: Alwaysв Job. apiserver откажет, ошибку стоит прочитать внимательно.backoffLimitслишком большой. Глючный скрипт долбит часами.- Забыли
ttlSecondsAfterFinished. Через неделю в namespace тысячи завершённых Job, kubectl тормозит. - Долгая миграция БД в init-контейнере вместо Job. Каждый рестарт Pod запускает её заново. Миграция должна быть Job, который катится один раз.
Домашка
Теорию закрепляет задание на своём кластере: 2 шага с проверкой. Кластер поднимается по треку Kubernetes локально, задания лежат в репозитории k8s-practice.
./run.sh start k8s-first-job # развернуть стартовое состояние
./run.sh verify k8s-first-job # проверить текущий шаг
Коротко
- Job гоняет Pod до успешного завершения и останавливается, в отличие от Deployment.
completionsзадаёт число нужных успехов,parallelism- сколько идут одновременно.backoffLimitограничивает ретраи; дефолт 6 для прода великоват.restartPolicyтолькоNeverилиOnFailure,Alwaysзапрещён.ttlSecondsAfterFinishedизбавляет от кладбища завершённых Job.- Чтобы Job перестал плодить Pod, удаляют сам Job.
Прошли материал до конца? Отметьте урок пройденным.
Прогресс сохранён в этом браузере
Почистишь историю или откроешь с телефона, и отметки пропадут. Оставь почту, они переедут в аккаунт. Пароль придумывать не нужно.
Готово. теперь в аккаунте: прогресс виден с любого устройства. Мой прогресс