Обробка повторюваних і неповторюваних збоїв Podʼів за допомогою політики збоїв Podʼа

Обробка повторюваних і неповторюваних збоїв Podʼів за допомогою політики збоїв Podʼа

This is a stable feature in Kubernetes, and has been since the 1.31 release. You can no longer toggle this feature (the associated feature gate has been removed).

У цьому документі показано, як використовувати політику збоїв Podʼа разом зі стандартною політикою backoff для збоїв Podʼа, щоб краще контролювати обробку збоїв на рівні контейнера або Podʼа в межах Job.

Визначення політики збоїв Podʼа може допомогти:

Перш ніж ви розпочнете

Ви вже маєте знати основи використання Job.

Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:

Версія вашого Kubernetes сервера має бути не старішою ніж v1.25.

Для перевірки версії введіть kubectl version.

Сценарії використання

Розгляньмо такі сценарії використання для Jobs, які визначають політику збоїв Podʼа:

Використання політики збоїв Podʼа для уникнення непотрібних повторних спроб запуску Podʼів

У наведеному нижче прикладі ви дізнаєтеся, як використовувати політику збоїв Podʼа, щоб уникати непотрібних перезапусків Podʼів, коли збій Podʼа вказує на програмну помилку, яку неможливо усунути повторною спробою.

  1. Перегляньте наведений нижче маніфест:

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: job-pod-failure-policy-failjob
    spec:
      completions: 8
      parallelism: 2
      template:
        spec:
          restartPolicy: Never
          containers:
          - name: main
            image: docker.io/library/bash:5
            command: ["bash"]
            args:
            - -c
            - echo "Hello world! I'm going to exit with 42 to simulate a software bug." && sleep 30 && exit 42
      backoffLimit: 6
      podFailurePolicy:
        rules:
        - action: FailJob
          onExitCodes:
            containerName: main
            operator: In
            values: [42]
    
  2. Застосуйте маніфест:

    kubectl create -f https://k8s.io/examples/controllers/job-pod-failure-policy-failjob.yaml
    
  3. Приблизно через 30 секунд весь Job має завершитися. Перевірте статус Job, виконавши команду:

    kubectl get jobs -l job-name=job-pod-failure-policy-failjob -o yaml
    

    У статусі Job відображаються такі стани:

    • Стан FailureTarget: має поле reason зі значенням PodFailurePolicy і поле message з додатковою інформацією про завершення, наприклад Container main for pod default/job-pod-failure-policy-failjob-8ckj8 failed with exit code 42 matching FailJob rule at index 0. Контролер Job додає цей стан, щойно Job вважається невдалим. Докладніше дивіться Завершення Podʼів Job.
    • Стан Failed: ті самі reason і message, що й у стану FailureTarget. Контролер Job додає цей стан після завершення всіх Podʼів Job.

    Для порівняння: якби політику збоїв Podʼа було вимкнено, Job повторював би спроби до досягнення backoffLimit (6 збоїв). Оскільки повторні спроби використовують експоненційний backoff, а з parallelism: 2 збої відбуваються парами, затримка між спробами зростає з кожною спробою. У результаті в цьому прикладі мало б минути щонайменше 9 хвилин, перш ніж Job зазнає збою.

Очищення

Видаліть створений Job:

kubectl delete jobs/job-pod-failure-policy-failjob

Кластер автоматично очищає Podʼи.

Використання політики збоїв Podʼа для ігнорування порушень роботи Podʼів

У наведеному нижче прикладі ви дізнаєтеся, як за допомогою політики збоїв Podʼа зробити так, щоб порушення роботи Podʼів не збільшували лічильник повторних спроб Podʼа в межах .spec.backoffLimit.

Увага:

У цьому прикладі важливий час, тому варто прочитати кроки перед виконанням. Щоб спричинити порушення роботи Podʼа, важливо виконати drain вузла, поки Pod працює на ньому (протягом 90 секунд після планування Podʼа).
  1. Перегляньте наведений нижче маніфест:

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: job-pod-failure-policy-ignore
    spec:
      completions: 4
      parallelism: 2
      template:
        spec:
          restartPolicy: Never
          containers:
          - name: main
            image: docker.io/library/bash:5
            command: ["bash"]
            args:
            - -c
            - echo "Hello world! I'm going to exit with 0 (success)." && sleep 90 && exit 0
      backoffLimit: 0
      podFailurePolicy:
        rules:
        - action: Ignore
          onPodConditions:
          - type: DisruptionTarget
    
  2. Застосуйте маніфест:

    kubectl create -f https://k8s.io/examples/controllers/job-pod-failure-policy-ignore.yaml
    
  3. Виконайте цю команду, щоб перевірити nodeName, на який заплановано Pod:

    nodeName=$(kubectl get pods -l job-name=job-pod-failure-policy-ignore -o jsonpath='{.items[0].spec.nodeName}')
    
  4. Виконайте drain вузла, щоб виселити Pod до його завершення (протягом 90 секунд):

    kubectl drain nodes/$nodeName --ignore-daemonsets --grace-period=0
    
  5. Перевірте .status.failed, щоб переконатися, що лічильник для Job не збільшено:

    kubectl get jobs -l job-name=job-pod-failure-policy-ignore -o yaml
    
  6. Виконайте uncordon вузла:

    kubectl uncordon nodes/$nodeName
    

Job відновлюється й завершується успішно.

Для порівняння: якби політику збоїв Podʼа було вимкнено, порушення роботи Podʼа призвело б до завершення всього Job (оскільки .spec.backoffLimit дорівнює 0).

Очищення

Видаліть створений Job:

kubectl delete jobs/job-pod-failure-policy-ignore

Кластер автоматично очищає Podʼи.

Використання політики збоїв Podʼа для уникнення непотрібних повторних спроб запуску Podʼів на основі власних станів Podʼа

У наведеному нижче прикладі ви дізнаєтеся, як використовувати політику збоїв Podʼа, щоб уникати непотрібних перезапусків Podʼів на основі власних станів Podʼа.

Примітка:

Наведений нижче приклад працює з версії 1.27, оскільки спирається на перехід видалених Podʼів у фазі Pending до термінальної фази (дивіться Фаза Podʼа).
  1. Перегляньте наведений нижче маніфест:

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: job-pod-failure-policy-config-issue
    spec:
      completions: 8
      parallelism: 2
      template:
        spec:
          restartPolicy: Never
          containers:
          - name: main
            image: "non-existing-repo/non-existing-image:example"
      backoffLimit: 6
      podFailurePolicy:
        rules:
        - action: FailJob
          onPodConditions:
          - type: ConfigIssue
    
  2. Застосуйте маніфест:

    kubectl create -f https://k8s.io/examples/controllers/job-pod-failure-policy-config-issue.yaml
    

    Зверніть увагу, що образ налаштовано неправильно, оскільки його не існує.

  3. Перевірте статус Podʼів Job, виконавши команду:

    kubectl get pods -l job-name=job-pod-failure-policy-config-issue -o yaml
    

    Ви побачите вивід, подібний до такого:

    containerStatuses:
    - image: non-existing-repo/non-existing-image:example
       ...
       state:
       waiting:
          message: Back-off pulling image "non-existing-repo/non-existing-image:example"
          reason: ImagePullBackOff
          ...
    phase: Pending
    

    Зверніть увагу, що Pod лишається у фазі Pending, оскільки не може завантажити неправильно налаштований образ. Це, в принципі, могло б бути тимчасовою проблемою, і образ міг би завантажитися. Однак у цьому випадку образу не існує, тому ми вказуємо на це за допомогою власного стану.

  4. Додайте власний стан. Спочатку підготуйте патч, виконавши команду:

    cat <<EOF > patch.yaml
    status:
      conditions:
      - type: ConfigIssue
        status: "True"
        reason: "NonExistingImage"
        lastTransitionTime: "$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
    EOF
    

    По-друге, виберіть один із Podʼів, створених Job, виконавши команду:

    podName=$(kubectl get pods -l job-name=job-pod-failure-policy-config-issue -o jsonpath='{.items[0].metadata.name}')
    

    Потім застосуйте патч до одного з Podʼів, виконавши таку команду:

    kubectl patch pod $podName --subresource=status --patch-file=patch.yaml
    

    Якщо патч успішно застосовано, ви отримаєте повідомлення такого типу:

    pod/job-pod-failure-policy-config-issue-k6pvp patched
    
  5. Видаліть Pod, щоб перевести його у фазу Failed, виконавши команду:

    kubectl delete pods/$podName
    
  6. Перевірте статус Job, виконавши:

    kubectl get jobs -l job-name=job-pod-failure-policy-config-issue -o yaml
    

    У статусі Job ви побачите стан Failed з полем reason, що дорівнює PodFailurePolicy. Крім того, поле message містить докладнішу інформацію про завершення Job, наприклад Pod default/job-pod-failure-policy-config-issue-k6pvp has condition ConfigIssue matching FailJob rule at index 0.

Примітка:

У промисловому середовищі кроки 3 та 4 має автоматизувати контролер, наданий користувачем.

Очищення

Видаліть створений Job:

kubectl delete jobs/job-pod-failure-policy-config-issue

Кластер автоматично очищає Podʼи.

Використання політики збоїв Podʼа для уникнення непотрібних повторних спроб запуску Podʼів за індексами

Щоб уникнути непотрібних перезапусків Podʼів для кожного індексу, можна використовувати можливості політика збоїв Podʼа й обмеження backoff на індекс. У цьому розділі сторінки показано, як використовувати ці можливості разом.

  1. Перегляньте наведений нижче маніфест:

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: job-backoff-limit-per-index-failindex
    spec:
      completions: 4
      parallelism: 2
      completionMode: Indexed
      backoffLimitPerIndex: 1
      template:
        spec:
          restartPolicy: Never
          containers:
          - name: main
            image: docker.io/library/python:3
            command:
              # The script:
              # - fails the Pod with index 0 with exit code 1, which results in one retry;
              # - fails the Pod with index 1 with exit code 42 which results
              #   in failing the index without retry.
              # - succeeds Pods with any other index.
              - python3
              - -c
              - |
                import os, sys
                index = int(os.environ.get("JOB_COMPLETION_INDEX"))
                if index == 0:
                  sys.exit(1)
                elif index == 1:
                  sys.exit(42)
                else:
                  sys.exit(0)
      backoffLimit: 6
      podFailurePolicy:
        rules:
        - action: FailIndex
          onExitCodes:
            containerName: main
            operator: In
            values: [42]
    
  2. Застосуйте маніфест:

    kubectl create -f https://k8s.io/examples/controllers/job-backoff-limit-per-index-failindex.yaml
    
  3. Приблизно через 15 секунд перевірте стан Podʼів для Job. Ви можете зробити це, виконавши команду:

    kubectl get pods -l job-name=job-backoff-limit-per-index-failindex -o yaml
    

    Ви побачите вивід, подібний до такого:

    NAME                                            READY   STATUS      RESTARTS   AGE
    job-backoff-limit-per-index-failindex-0-4g4cm   0/1     Error       0          4s
    job-backoff-limit-per-index-failindex-0-fkdzq   0/1     Error       0          15s
    job-backoff-limit-per-index-failindex-1-2bgdj   0/1     Error       0          15s
    job-backoff-limit-per-index-failindex-2-vs6lt   0/1     Completed   0          11s
    job-backoff-limit-per-index-failindex-3-s7s47   0/1     Completed   0          6s
    

    Зверніть увагу, що вивід показує таке:

    • Два Podʼи мають індекс 0, оскільки обмеження backoff дозволило одну повторну спробу для індексу.
    • Лише один Pod має індекс 1, оскільки код виходу збійного Podʼа збігся з політикою збоїв Podʼа з дією FailIndex.
  4. Перевірте статус Job, виконавши:

    kubectl get jobs -l job-name=job-backoff-limit-per-index-failindex -o yaml
    

    У статусі Job поле failedIndexes показує "0,1", оскільки обидва індекси зазнали збою. Оскільки індекс 1 не повторювався, кількість збійних Podʼів, вказана в полі статусу "failed", дорівнює 3.

Очищення

Видаліть створений Job:

kubectl delete jobs/job-backoff-limit-per-index-failindex

Кластер автоматично очищає Podʼи.

Альтернативи

Ви можете покладатися лише на політику backoff для збоїв Podʼа, вказавши поле .spec.backoffLimit у Job. Однак у багатьох ситуаціях важко знайти баланс: значення .spec.backoffLimit має бути достатньо низьким, щоб уникати непотрібних повторних спроб Podʼів, але достатньо високим, щоб Job не завершувався через порушення роботи Podʼів.

Змінено November 02, 2026 at 9:44 PM PST: [uk] Add tasks/job: pod-failure-policy (90c2eaf858)