RU localisation of concepts/workloads/controllers/cron-jobs.md
Co-Authored-By: Dmitry Shurupov <dmitry.shurupov@palark.com>pull/44766/head
parent
a66ab77922
commit
0b14d74113
|
@ -0,0 +1,233 @@
|
|||
---
|
||||
title: CronJob
|
||||
content_type: concept
|
||||
description: >-
|
||||
CronJob запускает одноразовые задания по повторяющемуся расписанию
|
||||
weight: 80
|
||||
hide_summary: true # Listed separately in section index
|
||||
---
|
||||
|
||||
<!-- overview -->
|
||||
|
||||
{{< feature-state for_k8s_version="v1.21" state="stable" >}}
|
||||
|
||||
_CronJob_ создает {{< glossary_tooltip term_id="job" text="задания (Jobs)" >}}, которые повторяются по расписанию.
|
||||
|
||||
CronJob предназначен для выполнения регулярных заданий по расписанию, таких как резервное копирование, создание отчетов,
|
||||
и так далее. Один CronJob объект — это как одна строка файла _crontab_ (cron table) в Unix-системе.
|
||||
Он периодически запускает задание по заданному расписанию, составленному в формате формате
|
||||
[Cron](https://ru.wikipedia.org/wiki/Cron).
|
||||
|
||||
У CronJob'a есть свои ограничения и особенности.
|
||||
Например, при определенных обстоятельствах один CronJob может создавать несколько параллельных заданий. См. раздел [Ограничения](#cron-job-limitations) ниже.
|
||||
|
||||
Когда управляющий слой _(control plane)_ создает новые задания и (косвенно) поды для CronJob'а, поле `.metadata.name` в CronJob
|
||||
является частью основы для наименования этих подов. Имя CronJob должно быть действительным
|
||||
значением [поддомена DNS](/ru/docs/concepts/overview/working-with-objects/names#имена-поддоменов-dns), но это может привести к неожиданным результатам для имен хостов подов. Для наилучшей совместимости имя должно соответствовать более строгим правилам
|
||||
[имен меток DNS](/ru/docs/concepts/overview/working-with-objects/names#имена-меток-dns).
|
||||
Даже если имя является поддоменом DNS, оно не должно превышать 52 символов. Это связано с тем, что контроллер CronJob автоматически добавляет
|
||||
11 символов к указанному вами имени и существует ограничение на то, что
|
||||
длина имени задания (Job) не должна превышать 63 символа.
|
||||
|
||||
<!-- body -->
|
||||
## Пример
|
||||
|
||||
Этот пример манифеста CronJob печатает текущее время и сообщение hello каждую минуту:
|
||||
|
||||
{{% code_sample file="application/job/cronjob.yaml" %}}
|
||||
|
||||
([Выполнение автоматических заданий с помощью CronJob](/docs/tasks/job/automated-tasks-with-cron-jobs/)
|
||||
более подробно рассматривает этот пример.)
|
||||
|
||||
## Написание спецификации CronJob'a
|
||||
### Синтаксис расписания
|
||||
Поле `.spec.schedule` является обязательным. Значение этого поля соответствует синтаксису [Cron](https://ru.wikipedia.org/wiki/Cron):
|
||||
|
||||
```
|
||||
# ┌───────────── минута (0 - 59)
|
||||
# │ ┌───────────── час (0 - 23)
|
||||
# │ │ ┌───────────── день месяца (1 - 31)
|
||||
# │ │ │ ┌───────────── месяц (1 - 12)
|
||||
# │ │ │ │ ┌───────────── день недели (0 - 6) (воскресенье - суббота)
|
||||
# │ │ │ │ │ ИЛИ sun, mon, tue, wed, thu, fri, sat
|
||||
# │ │ │ │ │
|
||||
# * * * * *
|
||||
```
|
||||
|
||||
Например, `0 0 13 * 5` указывает, что задание должно запускаться каждую пятницу в полночь, а также 13 числа каждого месяца в полночь.
|
||||
|
||||
Формат также включает расширенные значения шагов "Vixie cron". Как объясняется в
|
||||
[инструкции для FreeBSD](https://www.freebsd.org/cgi/man.cgi?crontab%285%29):
|
||||
|
||||
> Значения шагов можно использовать в сочетании с диапазонами. Если после диапазона указать `/<число>`, то это означает
|
||||
> пропуск значения числа в диапазоне. Например, `0-23/2` можно использовать, чтобы указать выполнение команды
|
||||
> каждый второй час (альтернативой в стандарте V7 является
|
||||
> `0,2,4,6,8,10,12,14,16,18,20,22`). Шаги также разрешены после звездочки, так что если
|
||||
> нужно указать "каждые два часа", можно использовать `*/2`.
|
||||
|
||||
{{< note >}}
|
||||
Вопросительный знак (`?`) в расписании обозначает то же, что и звездочка `*`, то есть любое из доступных значений для данного поля.
|
||||
{{< /note >}}
|
||||
|
||||
Помимо стандартного синтаксиса можно также использовать макросы вроде `@monthly`:
|
||||
|
||||
| Запись | Описание | Эквивалент |
|
||||
| ------------- | ------------- |------------- |
|
||||
| @yearly (или @annually) | Запускается один раз в год в полночь 1 января | 0 0 1 1 * |
|
||||
| @monthly | Запускается раз в месяц в полночь первого дня месяца | 0 0 1 * * |
|
||||
| @weekly | Запускается раз в неделю в полночь в воскресенье утром | 0 0 * * 0 |
|
||||
| @daily (или @midnight) | Запускается один раз в день в полночь | 0 0 * * * |
|
||||
| @hourly | Запускается раз в час в начале часа | 0 * * * * |
|
||||
|
||||
Для создания CronJob-расписания можно также использовать такие веб-инструменты, как [crontab.guru](https://crontab.guru/).
|
||||
|
||||
### Шаблон задания
|
||||
|
||||
Поле `.spec.jobTemplate` определяет шаблон для заданий, которые создает CronJob, и является обязательным.
|
||||
Он имеет точно такой же вид, как и [Job](/docs/concepts/workloads/controllers/job/), за исключением того,
|
||||
что является вложенным и не имеет полей `apiVersion` и `kind`.
|
||||
Можно указать типичные метаданные для шаблонных заданий (Jobs), такие как
|
||||
{{< glossary_tooltip text="метки" term_id="label" >}} или
|
||||
{{< glossary_tooltip text="аннотации" term_id="annotation" >}}.
|
||||
О том, как написать `.spec` для Job, см. [Написание спецификации Job](/docs/concepts/workloads/controllers/job/#writing-a-job-spec).
|
||||
|
||||
### Дедлайн задержки начала задания {#starting-deadline}
|
||||
|
||||
Поле `.spec.startingDeadlineSeconds` является необязательным.
|
||||
В этом поле задается крайний срок (в целых секундах) для запуска задания (Job), если оно по какой-либо причине
|
||||
не успевает к назначенному времени.
|
||||
|
||||
Если дедлайн пропущен, CronJob пропускает этот вызов задания (последующие выполнения по-прежнему запланированы).
|
||||
Например, если задание резервного копирования выполняется дважды в день, можно разрешить ему
|
||||
запускаться с опозданием до 8 часов, но не позже, поскольку резервная копия,
|
||||
сделанная позже, не будет полезной: лучше дождаться следующего запуска по расписанию.
|
||||
|
||||
Задания, которые не успели выполниться в установленный срок, Kubernetes рассматривает как неудачные.
|
||||
Если не указать `startingDeadlineSeconds` для CronJob, то задания не будут иметь дедлайн.
|
||||
|
||||
Если поле `.spec.startingDeadlineSeconds` установлено (не является нулевым), контроллер CronJob
|
||||
измеряет время между моментом, когда задание должно быть создано, и реальным временем.
|
||||
Если разница превышает указанный предел, он пропустит этот вызов задания.
|
||||
|
||||
Например, если установлено значение `200`, задание может быть создано в период до 200 секунд позже фактического расписания.
|
||||
|
||||
### Политика параллелизма (concurrency policy)
|
||||
|
||||
Поле `.spec.concurrencyPolicy` также является необязательным.
|
||||
Оно определяет, как обращаться с одновременным выполнением заданий, созданных этим CronJob.
|
||||
В этой спецификации может быть указана только одна из следующих политик параллелизма:
|
||||
|
||||
* `Allow` (по умолчанию): CronJob разрешает одновременное выполнение заданий.
|
||||
* `Forbid`: CronJob не разрешает одновременное выполнение заданий; если пришло время для выполнения нового задания,
|
||||
а предыдущее еще не завершилось, CronJob пропускает новое задание.
|
||||
* `Replace`: Если пришло время для выполнения нового задания, а предыдущее еще не завершилось,
|
||||
CronJob заменит текущее задание на новое.
|
||||
|
||||
Заметьте, что принцип параллелизма применяется только к заданиям, созданным одним и тем же Cronjob'ом.
|
||||
Если есть несколько CronJob'ов, их соответствующие задания всегда могут выполняться одновременно.
|
||||
|
||||
### Остановка выполнения заданий по расписанию
|
||||
|
||||
Можно приостановить выполнение CronJob-заданий, присвоив необязательному полю `.spec.suspend` значение true.
|
||||
По умолчанию это поле имеет значение false.
|
||||
|
||||
Эта настройка _не_ влияет на задания, которые уже были запущены CronJob'ом.
|
||||
|
||||
Если установить это поле как true, все последующие выполнения будут приостановлены
|
||||
(они остаются запланированными, но CronJob-контроллер не запускает задания для выполнения),
|
||||
пока вы не отмените приостановку CronJob'a.
|
||||
|
||||
{{< caution >}}
|
||||
Работы, приостановленные во время запланированного выполнения, считаются пропущенными.
|
||||
Когда `.spec.suspend` изменяется с `true` на `false` для существующего CronJob'a без
|
||||
[дедлайна задержки начала задания](#starting-deadline), пропущенные задания планируются немедленно.
|
||||
{{< /caution >}}
|
||||
|
||||
### Лимиты на историю заданий
|
||||
|
||||
Поля `.spec.successfulJobsHistoryLimit` и `.spec.failedJobsHistoryLimit` являются необязательными.
|
||||
В этих полях указывается, сколько завершенных и неудачных заданий должно быть сохранено в истории.
|
||||
По умолчанию они установлены на 3 и 1 соответственно. Установка предела в `0` будет означать,
|
||||
что никакие задания соответствующего типа не сохранятся после их завершения.
|
||||
|
||||
Другой способ автоматической очистки заданий см. в разделе [Автоматическая очистка завершенных заданий](/docs/concepts/workloads/controllers/job/#clean-up-finished-jobs-automatically).
|
||||
|
||||
### Часовые пояса
|
||||
|
||||
{{< feature-state for_k8s_version="v1.27" state="stable" >}}
|
||||
|
||||
Для CronJob'a, в которых не указан часовой пояс, {{< glossary_tooltip term_id="kube-controller-manager" text="kube-controller-manager" >}}
|
||||
интерпретирует расписания относительно своего локального часового пояса.
|
||||
|
||||
Можно указать часовой пояс для CronJob'a, присвоив `.spec.timeZone` имя действительного
|
||||
[часового пояса](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
|
||||
Например, установка `.spec.timeZone: "Etc/UTC"` инструктирует Kubernetes интерпретировать расписание
|
||||
относительно всемирного координированного времени.
|
||||
|
||||
База данных часовых поясов из стандартной библиотеки Go включена в бинарные файлы и используется в качестве запасного варианта на случай, если внешняя база данных недоступна в системе.
|
||||
|
||||
## Ограничения CronJob {#cron-job-limitations}
|
||||
|
||||
### Неподдерживаемая спецификация TimeZone
|
||||
|
||||
Установка часового пояса с помощью переменных `CRON_TZ` или `TZ` в `.spec.schedule`
|
||||
**не поддерживается официально** (и никогда не поддерживалась).
|
||||
|
||||
Начиная с Kubernetes 1.29, если попытаться задать расписание,
|
||||
включающее спецификацию часового пояса `TZ` или `CRON_TZ`,
|
||||
Kubernetes не сможет создать ресурс, выдав ошибку валидации.
|
||||
Обновления для CronJobs, уже использующих `TZ` или `CRON_TZ`, будут продолжать выдавать
|
||||
[предупреждение](/blog/2020/09/03/warnings/) клиенту.
|
||||
|
||||
### Модификация задания CronJob
|
||||
|
||||
По своей структуре CronJob содержит шаблон для _новых_ заданий.
|
||||
Если изменить существующее задание CronJob, внесенные изменения будут
|
||||
применены к новым заданиям, которые начнут выполняться после завершения
|
||||
модификации. Задания (и их поды), которые уже были запущены, продолжат выполняться без изменений.
|
||||
То есть CronJob _не_ обновляет существующие задания, даже если они остаются запущенными.
|
||||
|
||||
### Создание заданий
|
||||
|
||||
CronJob создает объект задания (Job) примерно один раз за время выполнения своего расписания.
|
||||
Расписание является приблизительным, поскольку есть определенные обстоятельства,
|
||||
при которых могут быть созданы два задания или не создано ни одного.
|
||||
Kubernetes старается избегать таких ситуаций, но не может полностью предотвратить их. Поэтому
|
||||
задания, которые вы определяете, должны быть _идемпотентными_.
|
||||
|
||||
Если в поле `startingDeadlineSeconds` задано большое значение или оно не определено (по умолчанию),
|
||||
а также при условии, что `concurrencyPolicy` имеет значение `Allow`, задания всегда будут выполняться по крайней мере один раз.
|
||||
|
||||
{{< caution >}}
|
||||
Если `startingDeadlineSeconds` имеет значение меньше 10 секунд, задание CronJob, возможно, не будет запланировано. Это происходит потому, что CronJob выполняет проверку каждые 10 секунд.
|
||||
{{< /caution >}}
|
||||
|
||||
|
||||
Для каждого задания CronJob {{< glossary_tooltip term_id="controller" text="контроллер" >}} проверяет, сколько расписаний он пропустил за время, прошедшее с последнего расписания до настоящего момента. Если пропущено более 100 расписаний, то задание не запускается и фиксируется ошибка.
|
||||
|
||||
```
|
||||
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`), контроллер считает, сколько пропущенных заданий произошло с момента значения `startingDeadlineSeconds` до настоящего момента, а не с момента последнего запланированного задания до настоящего момента. Например, если `startingDeadlineSeconds` равно `200`, контроллер подсчитывает, сколько пропущенных заданий произошло за последние 200 секунд.
|
||||
|
||||
Задание CronJob считается пропущенным, если оно не было создано в запланированное время. Например, если для `concurrencyPolicy` установлено значение `Forbid`, и CronJob пытался быть запланирован, когда предыдущее расписание еще выполнялось, то он будет считаться пропущенным.
|
||||
|
||||
Например, предположим, что задание CronJob настроено на планирование нового задания каждую минуту, начиная с `08:30:00`, а его поле поле `startingDeadlineSeconds` не установлено.
|
||||
Если контроллер CronJob не функционирует с `08:29:00` до `10:21:00`, задание не будет запущено, так как количество пропущенных заданий, которые не успели выполнить свое расписание, больше 100.
|
||||
|
||||
Чтобы подробнее проиллюстрировать эту концепцию, предположим, что задание CronJob настроено на планирование нового задания каждую одну минуту, начиная с `08:30:00`, и его параметр `startingDeadlineSeconds` установлен на 200 секунд. Если контроллер CronJob вдруг не функционирует в течение того же периода, что и в предыдущем примере (с `08:29:00` по `10:21:00`), задание все равно начнется в 10:22:00. Это происходит потому, что контроллер в данном случае проверяет, сколько пропущенных запланированных заданий было за последние 200 секунд (т. е. 3 пропущенных расписания), а не с момента последнего запланированного времени до настоящего момента.
|
||||
|
||||
CronJob отвечает только за создание заданий (Jobs), соответствующих его расписанию, а задание, в свою очередь, отвечает за управление подами, которые оно представляет.
|
||||
|
||||
## {{% heading "whatsnext" %}}
|
||||
|
||||
* Ознакомьтесь с [Подами](/docs/concepts/workloads/pods/) и
|
||||
[Заданиями](/docs/concepts/workloads/controllers/job/) — двумя концепциями, на которые опираются CronJobs.
|
||||
* Ознакомьтесь с подробным [форматом](https://pkg.go.dev/github.com/robfig/cron/v3#hdr-CRON_Expression_Format)
|
||||
полей CronJob `.spec.schedule`.
|
||||
* Для инструкции по созданию и работе с CronJob, а также для примера
|
||||
CronJob-манифеста см. раздел [Выполнение автоматизированных задач с помощью CronJob](/docs/tasks/job/automated-tasks-with-cron-jobs/).
|
||||
* `CronJob` является частью Kubernetes REST API.
|
||||
Для получения более подробной информации прочтите справочник по {{< api-reference page="workload-resources/cron-job-v1" >}} API.
|
||||
|
Loading…
Reference in New Issue