Русский
Русский
English
Статистика
Реклама

Перевод Jobы и Cronjobы Kubernetes

CronJobы полезны для создания периодических и повторяющихся задач, таких как создание бэкапов или отправка электронных писем. CronJobы также могут планировать отдельные Jobы (задачи, задания - здесь и далее используется английский термин, чтобы избежать путаницы) на конкретное время, например, запланировать Job на то время, когда ваш кластер, скорее всего, будет простаивать. Jobы Kubernetes в первую очередь предназначены для краткосрочных и пакетных рабочих нагрузок (workloads).

В Kubernetes есть несколько контроллеров для управления подами: ReplicaSets, DaemonSets, Deployments и StatefulSets. У каждого из них есть свой сценарий использования. Однако их всех объединяет гарантия того, что их поды всегда работают. В случае сбоя пода контроллер перезапускает его или переключает его на другой узел (node), чтобы гарантировать постоянную работу программы, которая размещена на подах.

Что, если мы не хотим, чтобы под работал постоянно? Есть сценарии, когда вы не хотите, чтобы процесс продолжался непрерывно. Резервное копирование (backup, создание бэкапа) - это создание копии данных на отдельном носителе, предназначенной для восстановления данных в случае их потери. Данный процесс не должен выполняться постоянно. Напротив, он запускается на выполнение, и после завершения возвращает соответствующий код завершения (exit status), который сообщает, является ли результат успешным или неудачным.

Варианты использования Jobов Kubernetes

Наиболее подходящие варианты использования Jobов Kubernetes:

1. Пакетная обработка данных: допустим вы запускаете пакетную задачу с периодичностью один раз в день/неделю/месяц или по определенному расписанию. Примером этого может служить чтение файлов из хранилища или базы данных и передача их в сервис для обработки файлов.

2. Команды/специфические задачи: например, запуск скрипта/кода, который выполняет очистку базы данных.

Jobы Kubernetes гарантируют, что один или несколько подов выполнят свои команды и успешно завершатся. После завершения всех подов без ошибок, Job завершается. Когда Job удаляется, все созданные поды также удаляются.

Ваш первый Kubernetes Job

Создание Jobа Kubernetes, как и других ресурсов Kubernetes, осуществляется с помощью файла определения (definition file). Откройте новый файл, вы можете назвать его job.yaml. Добавьте в файл следующее:

apiVersion: batch/v1kind: Jobmetadata:name: hello-worldspec:template:  metadata:    name: hello-world  spec:    containers:    - name: hello-world      image: busybox      command: ["echo", "Running a hello-world job"]    restartPolicy: OnFailure

Как и в случае с другими ресурсами Kubernetes, мы можем применить это определение к работающему кластеру Kubernetes с помощью kubectl. Выглядит это следующим образом:

$ kubectl apply -f job.yamljob.batch/hello-world created

Давайте посмотрим, какие поды были созданы:

$ kubectl get podsNAME              READY    STATUS          RESTARTS      AGEhello-world-mstmc        0/1 ContainerCreating   0          1s

Проверим статус jobа с помощью kubectl:

kubectl get jobs hello-world-mstmcNAME      COMPLETIONS   DURATION   AGEhello-world-mstmc  1/1      21s    27s

Подождем несколько секунд и снова запустить ту же команду:

$ kubectl get podsNAME              READY   STATUS  RESTARTS       AGEhello-world-mstmc       0/1 Completed          0           25s

Статус пода говорит, что он не запущен. Статус Completed, поскольку job был запущен и выполнен успешно. Job, который мы только что определили, имел простую задачу :) - echo Running a hello-world job в стандартный вывод.

Прежде чем двигаться дальше, давайте убедимся, что job действительно выполнил то, что мы от него хотели:

kubectl logs -f hello-world-mstmcRunning a hello-world job

В логах отображается то, что мы задали, т.е. вывести Running a hello-world job. Job успешно выполнен.

Запуск CronJob вручную

Бывают ситуации, когда вам нужно выполнить cronjob на разовой основе. Вы можете сделать это, создав job из существующего cronjobа.

Например, если вы хотите, чтобы cronjob запускался вручную, вы должны сделать следующее.

kubectl create job --from=cronjob/kubernetes-cron-job manual-cron-job

--from=cronjob/kubernetes-cron-job скопируйте шаблон cronjobа и создайте job с именем manual-cron-job

Удаление Jobа Kubernetes и очистка (Cleanup)

Когда Job Kubernetes завершается, ни Job, ни созданные им поды не удаляются автоматически. Вы должны удалить их вручную. Эта особенность гарантирует, что вы по-прежнему сможете просматривать логи, Job и его поды в завершенном статусе.

Job можно удалить с помощью kubectl следующим образом:

kubectl delete jobs job_name

Приведенная выше команда удаляет конкретный Job и все его дочерние поды. Как и в случае с другими контроллерами Kubernetes, вы можете удалить Job, только покидая его поды, используя флаг cascade=false. Например:

kubectl delete jobs job_name cascade=false

Есть еще несколько ключевых параметров, которые вы можете использовать с jobами/cronjobами kubernetes в зависимости от ваших потребностей. Давайте рассмотрим каждый из них.

1. failedJobHistoryLimit и successfulJobsHistoryLimit: Удаления истории успешных и неудавшихся jobов основано на заданном Вами количестве сохранений. Это очень удобно для отбрасывания всех вхождений, завершенных неудачей, когда вы пытаетесь вывести список jobов. Например,

failedJobHistoryLimit: 5successfulJobsHistoryLimit: 10

2. backoffLimit: общее количество повторных попыток в случае сбоя пода.

RestartPolicy Jobа Kubernetes

В параметре restartPolicy (политика перезапуска) нельзя установить политику always (всегда). Job не должен перезапускать под после успешного завершения по определению. Таким образом, для параметра restartPolicy доступны варианты Never (никогда) и OnFailure (в случае неудачи).

Ограничение выполнения Jobа Kubernetes по времени

Если вы заинтересованы в выполнении Jobа в течение определенного периода времени, независимо от того, успешно ли завершился процесс, то у Jobов Kubernetes есть параметр spec.activeDeadlineSeconds. Установка для этого параметра приведет к немедленному прекращению работы Jobа по истечении заданного количества секунд.

Обратите внимание, что этот параметр переопределяет .spec.backoffLimit, т.е. если под завершается неудачей и Job достигает своего временного ограничения, неудавшийся под не перезапускается. Все сразу же останавливается.

В следующем примере мы создаем Job как с параметром backoff limit, так и с deadline:

apiVersion: batch/v1kind: Jobmetadata: name: data-consumerspec: backoffLimit: 5 activeDeadlineSeconds: 20 template:spec:    containers:    - name: consumer        image: busybox        command: ["/bin/sh", "-c"]        args: ["echo 'Consuming data'; sleep 1; exit 1"]    restartPolicy: OnFailure

Завершения Jobов и параллелизм

Мы рассмотрели, как можно выполнить одну задачу, определенную внутри объекта Job, что более известно как шаблон run-once. Однако в реальных сценариях используются и другие шаблоны.

Несколько одиночных Jobов

Например, у нас может быть очередь сообщений, которая требует обработки. Мы должны порождать пользовательские jobы, которые извлекают сообщения из очереди, пока она не опустеет. Чтобы реализовать этот шаблон с помощью Jobов Kubernetes, мы устанавливаем в параметр .spec.completions какое-либо число (должно быть ненулевым, а положительным числом). Job начинает создавать поды пока не достигнет заданного числа завершений (completions). Job считается завершенным, когда все поды завершаются с успешным с кодом завершения. Приведем пример. Измените наш файл определения, чтобы он выглядел следующим образом:

apiVersion: batch/v1kind: Jobmetadata:name: data-consumerspec:completions: 5template: metadata:   name: data-consumer spec:   containers:   - name: data-consumer     image: busybox     command: ["/bin/sh","-c"]     args: ["echo 'consuming a message from queue'; sleep 5"]   restartPolicy: OnFailure
  • Мы указываем параметр completions равным 5.

Несколько параллельно запущенных Jobов (Work Queue)

Другой шаблон может включать в себя необходимость запуска нескольких jobов, но вместо того, чтобы запускать их один за другим, нам нужно запускать несколько из них параллельно. Параллельная обработка сокращает общее время выполнения и находит применение во многих областях, например в data science и искусственном интеллекте.

Измените файл определения, чтобы он выглядел следующим образом:

apiVersion: batch/v1kind: Jobmetadata:name: data-consumerspec:parallelism: 5template: metadata:   name: data-consumer spec:   containers:   - name: data-consumer     image: busybox     command: ["/bin/sh","-c"]     args: ["echo 'consuming a message from queue'; sleep $(shuf -i 5-10 -n 1)"]   restartPolicy: OnFailure

В этом примере мы не задали параметр .spec.completions. Вместо этого мы указали параметр parallelism. Параметр completions в нашем случае по умолчанию равен parallelism (5). Теперь Job делает следующее:

Одновременно будут запущены 5 подов, все они будут выполнять один и то же Job. Когда один из подов завершается успехом, это будет означать, что весь Job готов. Поды больше не создаются, и Job в конечном итоге завершается.

В этом сценарии Kubernetes Job одновременно порождает 5 подов. Знать, завершили ли остальные поды свои задачи, в компетенции самих подов. В нашем примере мы предполагаем, что получаем сообщения из очереди сообщений (например, AWS SQS). Когда сообщений для обработки больше нет, Job получает уведомление о том, что он должен завершиться. После успешного завершения первого пода:

  • Поды больше не создаются.

  • Существующие поды завершают свою работу и тоже завершаются.

В приведенном выше примере мы изменили команду, которую выполняет под, чтобы перевести его в спящий режим на случайное количество секунд (от 5 до 10), прежде чем он завершится. Таким образом, мы примерно моделируем, как несколько подов могут работать вместе с внешним источником данных, таким как очередь сообщений или API.

Ограничения CronJobов

Cronjob создает объект job примерно по одному разу за сеанс выполнения своего расписания (schedule). Мы говорим примерно, потому что при определенных обстоятельствах могут быть созданы два jobа или ни одного. Мы пытаемся сделать подобные случаи как можно более редкими, но не можем предотвратить их полностью. Следовательно, jobы должны быть идемпотентными.

Если параметр startingDeadlineSeconds установлен на большое значение или не задан (по умолчанию) и параметр concurrencyPolicy установлен на Allow, job всегда будут запускаться как минимум один раз.

Для каждого CronJobа контроллер CronJob проверяет, сколько расписаний он пропустил за период с последнего запланированного времени до настоящего момента. Если пропущенных расписаний больше 100, то job не запускается и в логи вносится сообщение об ошибке.

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

Важно отметить, что если параметр startingDeadlineSeconds установлен (т.е. не nil), то контроллер считает сколько произошло пропущенных jobов исходя из значения параметра startingDeadlineSeconds, начиная с последнего заданного времени до сих пор. Например, если параметр startDeadlineSeconds установлен на 200, контроллер подсчитывает, сколько пропущенных jobов произошло за последние 200 секунд.

CronJob считается пропущенным, если его не удалось создать в установленное время. Например, если для параметра concurrencyPolicy задано значение Forbid и была предпринята попытка запланировать CronJob во время выполнения предыдущего расписания, оно будет считаться пропущенным.

Например, предположим, что CronJob настроен запускать новый Job каждую минуту начиная с 08:30:00, а его параметр startingDeadlineSeconds не установлен. Если контроллер CronJob не работал с 08:29:00 до 10:21:00, job не запустится, так как количество пропущенных jobов в расписании превышает 100.

Чтобы проиллюстрировать эту концепцию с другой стороны, предположим, что CronJob запрограммирован планировать новый Job в расписании каждую минуту начиная с 08:30:00 и его параметр startingDeadlineSeconds устанавливается на 200 секунд. Если контроллер CronJob не работает в течение того же периода, что и в предыдущем примере (с 08:29:00 до 10:21:00), Job все равно запустится в 10:22:00. Это происходит, поскольку контроллер теперь проверяет, сколько пропущенных расписаний было за последние 200 секунд (т. е. 3 пропущенных расписания), вместо того, чтобы считать с последнего заданного времени до настоящего момента.

CronJob отвечает только за создание Jobов, соответствующих его расписанию, а Job, в свою очередь, отвечает за управление представляемыми им подами.

TL;DR (Too Long; Didnt Read)

  • Jobы Kubernetes используются, когда вы хотите создать поды, которые будут выполнять определенную задачу, а затем завершать работу.

  • Jobы Kubernetes по умолчанию не нуждаются в селекторах подов; Job автоматически обрабатывает их лейблы и селекторы.

  • Параметр restartPolicy для Job принимает значения Never или OnFailure

  • Jobы используют параметры completions и parallelism для управления шаблонами, которые определяют порядок работы подов. Поды Jobов могут выполняться как одна задача, несколько последовательных задач или несколько параллельных задач, в которых первая завершенная задача дает указание остальным подам завершиться.

  • Вы можете контролировать количество попыток Jobа перезапустить неудавшиеся поды, используя параметр .spec.backoffLimit. По умолчанию этот лимит равен шести.

  • Вы можете контролировать время работы jobа, используя параметр .spec.activeDeadlineSeconds. Этот лимит отменяет backoffLimit. Таким образом, Job не пытается перезапустить неудавшийся под, если дедлайн достигнут.

  • Jobы и их поды не удаляются автоматически после завершения. Вы должны удалить их вручную или использовать контроллер ttlSecondsAfterFinished, который на момент написания этой статьи все еще находится в статусе alpha.


Перевод статьи подготовлен в преддверии старта курса "Инфраструктурная платформа на основе Kubernetes". Также приглашаем всех желающих записаться на бесплатный демо-урок по теме: "Работа с NoSQL базами в k8s (на примере Apache Cassandra)"

Источник: habr.com
К списку статей
Опубликовано: 10.03.2021 18:12:48
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Блог компании otus

Devops

Kubernetes

Cron

Cronjob

Sre

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru