Почему под (Pod) в Kubernetes может находиться в состоянии Pending?

«Почему под (Pod) в Kubernetes может находиться в состоянии Pending?» — вопрос из категории Kubernetes, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Состояние Pending означает, что Pod принят системой, но не может быть запланирован (scheduled) для запуска на какой-либо ноде. Это распространённая проблема, и её диагностика — ключевой навык.

Основные причины и способы диагностики:

  1. Нехватка ресурсов на нодах (CPU, Memory):

    # Проверить доступные ресурсы на нодах
    kubectl describe nodes | grep -A 5 -B 5 "Allocatable"
    # Проверить запросы (requests) и лимиты (limits) пода
    kubectl describe pod <pod-name> | grep -A 5 "Requests"
  2. Несоответствие селекторов нод (Node Selectors / Affinity / Taints):

    • Pod может требовать метку (nodeSelector: disktype: ssd), которой нет ни у одной ноды.
    • Taint ноды (например, node.kubernetes.io/not-ready) может не соответствовать toleration в Pod.
      # Посмотреть taints нод
      kubectl describe node <node-name> | grep Taint
      # Посмотреть спецификацию пода
      kubectl get pod <pod-name> -o yaml | grep -A 10 -B 5 "nodeSelector|affinity|tolerations"
  3. Проблемы с PersistentVolumeClaim (PVC):

    • PVC находится в состоянии Pending, если нет подходящего PV или StorageClass не может динамически его создать.
      kubectl get pvc -n <namespace>
      kubectl describe pvc <pvc-name> -n <namespace>
  4. Ограничения квот (ResourceQuota) в namespace:

    kubectl describe quota -n <namespace>
  5. Невозможно скачать образ контейнера:

    • Неверное имя образа, отсутствие прав на pull из private registry, проблемы с сетью.
      # Смотреть события пода — часто есть сообщение "ErrImagePull" или "ImagePullBackOff"
      kubectl describe pod <pod-name>

Стандартный поток диагностики:

# 1. Получить детальную информацию о поде, особенно секцию Events
kubectl describe pod <pod-name> -n <namespace>

# 2. Проверить общие события в namespace, отсортированные по времени
kubectl get events -n <namespace> --sort-by='.lastTimestamp'

# 3. Если причина неясна, можно попробовать сымитировать планирование
kubectl describe pod <pod-name> -n <namespace> | grep -A 20 "Conditions:"
# Искать сообщения типа "FailedScheduling"

Чаще всего причина видна сразу в выводе kubectl describe pod в секции Events.