Как ищешь причину зависания кода в состоянии Pending в Kubernetes

Ответ

Когда под зависает в состоянии Pending, я выполняю системную диагностику в следующем порядке:

  1. Анализ событий и описания пода:

    kubectl describe pod <pod-name> -n <namespace>
    kubectl get events --all-namespaces --sort-by='.lastTimestamp' | grep -i pending

    В выводе describe ищу секцию Events — там часто сразу указана причина (например, FailedScheduling).

  2. Проверка доступности ресурсов кластера:

    • Нехватка ресурсов на нодах: kubectl describe nodes покажет Allocatable CPU/memory. Сравниваю с запрошенными ресурсами пода (kubectl get pod <pod> -o yaml | grep -A 5 resources).
    • Ограничения по лимитам (ResourceQuota) в namespace: kubectl describe namespace <namespace>.
  3. Верификация зависимостей пода:

    • PersistentVolumeClaim (PVC): Проверяю, находится ли PVC в статусе Bound.
      kubectl get pvc -n <namespace>
      kubectl describe pvc <pvc-name> -n <namespace>
    • Node Selector / Affinity / Tolerations: Сверяю требования пода (nodeSelector, affinity, tolerations) с метками (labels) и taints нод.
      kubectl get nodes --show-labels
      kubectl describe node <node-name> | grep -i taint
  4. Проверка доступности образа (Image): В событиях ищу ошибки типа ErrImagePull или ImagePullBackOff. Проверяю корректность имени образа и доступность в registry.

Типичные причины: нехватка CPU/RAM на нодах, PVC в статусе Pending, несовпадение nodeSelector с метками нод, отсутствие ноды с подходящим toleration для taint, исчерпание квот namespace или лимитов на количество подов.

Ответ 18+ 🔞

Э, слушай, история классическая, как грязь в подъезде. Сидит твой под в статусе Pending, и нихуя не происходит. Ну, я в таких случаях действую по проверенному алгоритму, чтобы не гадать на кофейной гуще.

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

kubectl describe pod <pod-name> -n <namespace>

А ещё гляну события по всему кластеру, отфильтровав по нашему любимому слову:

kubectl get events --all-namespaces --sort-by='.lastTimestamp' | grep -i pending

В выводе describe сразу лезу в секцию Events. Часто там всё как на ладони — например, FailedScheduling. Уже полдела сделано, если причина всплыла.

Дальше иду проверять, хватает ли в кластере ресурсов вообще. Это как в магазин за колбасой прийти — а её нет.

  • Ноды все забиты? Смотрю, что kubectl describe nodes показывает в Allocatable. А потом сравниваю с аппетитами самого пода: kubectl get pod <pod> -o yaml | grep -A 5 resources. Бывает, под заказал памяти овердохуища, а свободной — кот наплакал.
  • А может, в неймспейсе квоты исчерпаны? Тоже частый геморрой. kubectl describe namespace <namespace> — и ищу блок про ResourceQuota. Вдруг лимит на количество подов или CPU упёрся в потолок.

Потом копаюсь в зависимостях пода. Он же не в вакууме висит.

  • PersistentVolumeClaim (PVC) привязался? Если под ждёт диск, а его нет — будет висеть вечно. Проверяю:
    kubectl get pvc -n <namespace>
    kubectl describe pvc <pvc-name> -n <namespace>

    Если PVC не в статусе Bound — вот тебе и причина, ёпта. Диска нет, под ждёт.

  • А нода подходящая есть? Тут целая наука: nodeSelector, affinity, tolerations. Под мог заказать себе ноду с конкретной меткой, а такой в кластере нет. Или на нодах стоят taints (защитные ограничения), а у пода нет нужного toleration, чтобы их проигнорировать. Проверяю:
    kubectl get nodes --show-labels
    kubectl describe node <node-name> | grep -i taint

    Не совпало — сиди и жди у моря погоды, чувак.

Ну и наконец, образ контейнера. Может, он криво называется или registry недоступен? В тех же событиях ищу ErrImagePull или ImagePullBackOff. Такое бывает, если в спешке опечатался в имени образа или забыл логин-пароль в приватный репозиторий прописать.

Короче, типичные причины — как пять пальцев:

  1. На нодах не хватило CPU или памяти — жрёт твой под как не в себя.
  2. PVC болтается в Pending, диск не выделили.
  3. Под просит ноду с меткой super-gpu, а таких у тебя нет — манда с ушами получается.
  4. На нодах taint, а у пода нет toleration — взаимное непонимание, блядь.
  5. В неймспейсе квоты все выжрали или лимит на поды упёрся.

Вот так, шаг за шагом, и находишь эту хитрожопую причину. Главное — не паниковать и читать, что система тебе говорит. Часто она сама намекает, в чём дело.