Гид по технологиям

Очистка старых Jobs в Kubernetes: стратегии и практические рекомендации

8 min read Kubernetes Обновлено 19 Dec 2025
Очистка старых Jobs в Kubernetes
Очистка старых Jobs в Kubernetes

Графика с логотипом Kubernetes

Быстрые ссылки

  • CronJob History Retention Limits

  • Finished Job TTLs

  • Ручное удаление Jobs

  • Резюме

Введение

Kubernetes Jobs запускают Pod’ы пока не выполнится заданное количество успешных контейнеров. Jobs часто создаются автоматически через CronJob по расписанию. По умолчанию Kubernetes сохраняет объекты Jobs и их Pods после завершения, чтобы вы могли просмотреть статус и логи позже. Однако большое количество завершённых Jobs захламляет вывод kubectl и может привести к нагрузке на управляющие компоненты кластера.

В этой статье мы подробно рассмотрим основные способы очистки старых Jobs: встроенные механизмы CronJob, TTL для Job, ручные и пакетные удаления, а также практические советы по внедрению и отладке. Для каждого подхода приведены примеры команд, чеклисты и рекомендации по миграции.

Важно: автоматическое удаление освобождает пространство и упрощает наблюдение, но удалённые Jobs нельзя будет использовать для постфактумного анализа. Оцените потребности в логах и артефактах перед агрессивной очисткой.

CronJob: ограничения истории (History Retention Limits)

CronJob поддерживает автоматическое удаление Jobs, созданных самим CronJob. Это работает с Kubernetes начиная с v1.6 и позволяет настроить отдельные лимиты для успешных и неуспешных запусков.

Задайте поля

spec.successfulJobsHistoryLimit

и

spec.failedJobsHistoryLimit

в манифесте CronJob. Пример:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: demo-cron
spec:
  schedule: "* * * * *"
  successfulJobsHistoryLimit: 5
  failedJobsHistoryLimit: 10
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: demo-cron
            image: busybox:latest
            command: ["/bin/sh", "-c", "Job complete!"]

В примере выше CronJob будет сохранять 10 последних неуспешных и 5 последних успешных Job’ов — максимум 15 объектов одновременно. Job’ы удаляются только когда появляются более новые Job’ы с тем же статусом и превышается лимит.

По умолчанию (когда поля отсутствуют) Kubernetes обычно хранит 3 успешных Job’а и 1 неуспешный. Значение

0

означает удалять Job сразу после завершения — не хранить историю.

Когда использовать

  • Для регулярных Cron-рабочих нагрузок, где нужна только недавняя история запусков.
  • Когда вы хотите разделять политику для успешных и неуспешных запусков.

Когда это не подойдёт

  • Если Jobs создаются не через CronJob (например, ad-hoc Jobs), эти лимиты не применимы.
  • Если требуется более гибкая логика удаления (по времени, по аннотациям, по внешним событиям).

TTL для завершённых Jobs (Finished Job TTLs)

Механизм TTL для Job стал стабильным в Kubernetes v1.23. TTL задаётся прямо на объекте Job и позволяет автоматически удалять Job и связанные Pods через фиксированное время после завершения.

Поле для настройки:

spec.ttlSecondsAfterFinished

Пример Job с TTL 300 секунд (5 минут):

apiVersion: batch/v1
kind: Job
metadata:
  name: demo-job
spec:
  ttlSecondsAfterFinished: 300
  template:
    spec:
      containers:
      - name: demo-cron
        image: busybox:latest
        command: ["/bin/sh", "-c", "Job complete!"]

Если Job определяется внутри CronJob, поле нужно вложить в jobTemplate:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: demo-cron
spec:
  schedule: "* * * * *"
  jobTemplate:
    spec:
      ttlSecondsAfterFinished: 300
      template:
        spec:
          containers:
          - name: demo-cron
            image: busybox:latest
            command: ["/bin/sh", "-c", "Job complete!"]

Контроллер TTL в кластере отслеживает объекты Job, определяет истёкшее время и удаляет Job вместе с зависимыми ресурсами. Может быть небольшая задержка от истечения TTL до удаления.

Значение

0

делает Job доступным для удаления сразу после завершения.

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

Преимущества и ограничения

  • Преимущество: четкое поведение по времени, применимо ко всем Jobs независимо от источника (CronJob или ручной Job).
  • Ограничение: удаление по TTL не даёт гибкости условной логики (например, очищать только если артефакты загружены в S3).

Ручное удаление Jobs

Вы всегда можете удалить Job вручную через kubectl.

Сначала получите список:

$ kubectl get jobs

Пример вывода:

NAME                      COMPLETIONS   DURATION   AGE
demo-cron-27549499        1/1           2s         36s

Чтобы удалить конкретный Job:

$ kubectl delete job demo-cron-27549499

Вы увидите:

job.batch "demo-cron-27549499" deleted

Это удалит Job и связанные Pods.

Пакетные удаления по полям

Можно удалять множество Job’ов одним вызовом, применяя fieldSelector. Например, удалить все успешные Job’ы в текущем namespace:

$ kubectl delete jobs --field-selector status.successful=1

Удаление по меткам

Чтобы упростить удаление Job’ов, создаваемых конкретным CronJob, задайте метку в jobTemplate.metadata.labels:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: demo-cron
spec:
  schedule: "* * * * *"
  jobTemplate:
    metadata:
      labels:
        cron-job: demo-cron
    spec:
      template:
        spec:
          containers:
          - name: demo-cron
            image: busybox:latest
            command: ["/bin/sh", "-c", "Job complete!"]

Затем удалить все Job’ы с этой меткой:

$ kubectl delete jobs -l cron-job=demo-cron

Можно комбинировать метки и fieldSelector, чтобы, например, удалить только неуспешные Job’ы конкретного CronJob:

$ kubectl delete jobs -l cron-job=demo-cron --field-selector status.successful=0

Стратегии автоматизации и скрипты

Если встроенные средства не покрывают ваши требования, используйте один из подходов:

  • Лёгкий CronJob в Kubernetes, который периодически вызывает kubectl delete jobs по определённым селекторам.
  • Kubernetes Operator, который реализует пользовательскую логику удаления (по аннотациям, по возрасту, по размеру логов и т.д.).
  • CI/CD-пайплайн, который после успешной загрузки артефактов в хранилище пометит Job аннотацией и запустит его очистку.

Пример простого bash-скрипта для удаления Job’ов старше N дней (использует jq и kubectl):

#!/usr/bin/env bash
# Удалить Job'ы старше 7 дней
THRESHOLD_DAYS=7
kubectl get jobs -o json | jq -r '.items[] | select(.status.completionTime != null) | select((now - ((.status.completionTime|fromdateiso8601))) > (env.THRESHOLD_DAYS|tonumber*86400)) | .metadata.name' | xargs -r kubectl delete job

Такой скрипт можно упаковать в контейнер и запустить как CronJob в кластере.

Лучшие практики

  • Предпочтительнее использовать TTL для Jobs там, где важен срок хранения. Это простая и надёжная политика.
  • Для CronJob используйте successfulJobsHistoryLimit и failedJobsHistoryLimit для управления количеством сохранённых запусков.
  • Если вам нужны логи длительное время — централизуйте логи (Fluentd/Logstash/Cloud Logging) и удаляйте Job’ы агрессивнее.
  • Помечайте Jobs метками и аннотациями, чтобы потом удалять по селекторам.
  • Не устанавливайте ttlSecondsAfterFinished=0 для важных задач, пока не уверены, что логи и артефакты доступны в другом месте.

Чеклист ролей

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

  • Внедрить политику по умолчанию для новых namespace (директивы, GitOps манифесты).
  • Мониторить метрики контроллера API (latency, etcd size) для раннего обнаружения проблем с количеством объектов.
  • Обеспечить систему централизованных логов и артефактов.

Разработчик / Владелец задания:

  • Оценить, нужны ли логи Job’а после выполнения.
  • Добавить ttlSecondsAfterFinished или установить историю в CronJob.
  • Добавлять метки и аннотации, описывающие назначение и владельца.

SRE / Операции:

  • Настроить мониторинг количества Job’ов и Pods, созданных Job’ами.
  • Запланировать задачи по чистке для существующих исторических Job’ов.
  • Тестировать восстановление сценариев, где истории нет (проверить, что логирование работает).

План миграции для существующих кластеров

  1. Инвентаризация: собрать список namespace и CronJob/Job с количеством завершённых Job’ов.
  2. Анализ: определить, какие Jobs критичны для отладки, какие можно удалить или сократить хранение.
  3. Внедрение: применить CronJob limits и/или добавить ttlSecondsAfterFinished в манифесты через GitOps.
  4. Очистка истории: запустить контролируемые пакетные удаления (kubectl delete jobs -l …) для старых записей.
  5. Мониторинг: наблюдать за влиянием на API-сервер, etсd и процессы отладки.

Критерии приёмки

  • В каждом namespace применены политики хранения для >= 90% CronJob’ов.
  • Общее число завершённых Jobs сократилось по сравнению с базовой линией на X% в течение 7 дней после внедрения (сравнение до/после).
  • Сценарии отладки не нарушены: логи доступны либо в локальном хранилище, либо в централизованной системе.

Отладка и распространённые проблемы

Проблема: Jobs не удаляются после истечения TTL

  • Проверьте, что контроллер TTL включён и работает (проверка логов контроллера kube-controller-manager или соответствующих Pod’ов контроллера).
  • Убедитесь, что поле spec.ttlSecondsAfterFinished действительно задано и содержит корректное число.
  • Есть небольшая задержка между истечением и удалением — подождите 30–60 секунд и проверьте снова.

Проблема: удаляются нужные для отладки Jobs

  • Перед массовой очисткой убедитесь, что логи отправляются в централизованную систему.
  • Используйте метки/аннотации, чтобы исключать критичные Jobs из автоматической очистки.

Проблема: слишком много объектов влияет на API-сервер

  • Установите агрессивные лимиты хранения и/или TTL, чтобы уменьшить количество объектов.
  • Рассмотрите shard-ирование CronJob’ов по namespace, чтобы избегать концентрации в одном namespace.

Набор тестов и критерии успеха

  • Тест 1: Создать Job с ttlSecondsAfterFinished: 10 — убедиться, что Job и Pods удалены в течение 60 секунд после завершения.
  • Тест 2: CronJob с successfulJobsHistoryLimit: 2 — запустить 4 успешных запуска и убедиться, что в списке сохраняются только 2 последних.
  • Тест 3: Метки и пакетное удаление — пометить Job’ы и удалить их селектором, убедиться, что удалены только помеченные объекты.

Decision flowchart

flowchart TD
  A[Начало: есть лишние Job'ы?] --> B{Job создаётся через CronJob?}
  B -- Да --> C{Нужна история успешных запусков?}
  C -- Да --> D[Настроить successfulJobsHistoryLimit]
  C -- Нет --> E[Настроить ttlSecondsAfterFinished или successfulJobsHistoryLimit=0]
  B -- Нет --> F{Нужно удалять по времени?}
  F -- Да --> E
  F -- Нет --> G[Добавить метки + ручная очистка или скрипт]
  D --> H[Мониторинг и проверка]
  E --> H
  G --> H
  H --> I[Готово]

Сравнение подходов (кратко)

  • CronJob history limits: просты в настройке, управляют количеством экземпляров, подходят только для CronJob.
  • TTL (ttlSecondsAfterFinished): применим ко всем Jobs, детерминирован по времени, требует работающего контроллера.
  • Ручные и скриптовые удаления: гибкость, но оперативная нагрузка и риск ошибок.

Безопасность и приватность

  • Убедитесь, что централизованная система логирования защищена и соответствует требованиям приватности — удаление Job’ов не должно означать потерю критичных данных.
  • При автоматической очистке используйте RBAC и ограничьте права на массовое удаление.

Резюме

Kubernetes по умолчанию сохраняет завершённые Jobs и их Pods, что упрощает отладку, но может привести к накоплению объектов и нагрузке на управляющие компоненты. Для управления хранением используйте:

  • successfulJobsHistoryLimit и failedJobsHistoryLimit для CronJob’ов;
  • spec.ttlSecondsAfterFinished для любых Job’ов;
  • метки и пакетные удаления через kubectl для ручного контроля;
  • автоматические скрипты, CronJob’ы или Operators для нестандартной логики.

Выберите стратегию в зависимости от требований к отладке, объёма логов и отношения к ретенции — и автоматизируйте этот процесс, чтобы поддерживать кластер в здравом состоянии.


Ключевые документы и команды

kubectl get jobs kubectl delete job kubectl delete jobs -l –field-selector

Шаблон SOP для включения TTL в GitOps

  1. Добавить поле spec.ttlSecondsAfterFinished во все Job- и CronJob-манифесты в репозитории.
  2. Открыть MR/PR с описанием влияния и тестовым планом.
  3. Применить в staging, запустить тесты по приёмке.
  4. Применить в production поэтапно.

Контрольный список после внедрения

  • TTL/limits добавлены в репозитории
  • Мониторинг количества Job’ов настроен
  • Централизованная система логов проверена
  • Документация для разработчиков обновлена
Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Chrome OS Flex на старом ПК — руководство
ОС

Chrome OS Flex на старом ПК — руководство

VIZ Manga: руководство по использованию
Мобильные приложения

VIZ Manga: руководство по использованию

Чёрный экран в Steam — устранение и проверка
Техподдержка

Чёрный экран в Steam — устранение и проверка

Изменить формат скриншотов в macOS
macOS

Изменить формат скриншотов в macOS

Параллакс-скроллинг в Arcade
Разработка игр

Параллакс-скроллинг в Arcade

Переназначение клавиш в Windows — PowerToys и SharpKeys
Windows

Переназначение клавиш в Windows — PowerToys и SharpKeys