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

СТАН ФУНКЦІОНАЛУ: Kubernetes v1.31 [stable] (стандартно увімкнено: true)

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

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

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

Ви повинні вже бути знайомі з основним використанням Job.

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

Версія вашого Kubernetes сервера має бути не старішою ніж v1.25. Для перевірки версії введіть kubectl version.

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

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

Спочатку створіть Job на основі конфігурації:

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]

виконавши команду:

kubectl create -f job-pod-failure-policy-failjob.yaml

Через приблизно 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 вважається невдалим. Для отримання деталей дивіться Завершення Job Podʼів.
  • Умова Failed: те ж саме значення для reason і message, що й в умови FailureTarget. Контролер Job додає цю умову після того, як усі Podʼи Job завершено.

Для порівняння, якщо політика збоїв Pod була вимкнена, це б зайняло 6 спроб повторного запуску Pod, на що треба щонайменше 2 хвилини.

Прибирання

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

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

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

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

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

  1. Створіть Job на основі конфігурації:

    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
    

    виконавши команду:

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

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

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

    kubectl get jobs -l job-name=job-pod-failure-policy-ignore -o yaml
    
  5. Зніміть блокування з вузла:

    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. Спочатку створіть Job на основі конфігурації:

    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
    

    виконавши команду:

    kubectl create -f job-pod-failure-policy-config-issue.yaml
    

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

  2. Перевірте статус 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, оскільки йому не вдається завантажити неправильно налаштований образ. Це, в принципі, може бути тимчасовою проблемою, і образ може бути завантажений. Однак у цьому випадку образу не існує, тому ми вказуємо на цей факт за допомогою власної умови.

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

    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
    
  4. Видаліть Pod для переходу його до фази Failed, виконавши команду:

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

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

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

Очищення

Видаліть створене вами завдання:

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

Кластер автоматично очищує поди.

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

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

Змінено August 15, 2024 at 4:40 PM PST: upstream sync (6ec9cfeefc)