Освоение kubectl logs и describe для эффективной отладки подов

Это руководство предоставляет экспертные методы освоения основных команд отладки Kubernetes: `kubectl logs` и `kubectl describe`. Изучите критические флаги, такие как `-f`, `--tail`, `-c` и `--previous`, необходимые для эффективного устранения неполадок. Мы подробно рассказываем, как интерпретировать важнейший раздел 'События' в `describe` для диагностики проблем планирования и конфигурации, а также как использовать `logs` для извлечения ошибок времени выполнения из падающих или многоконтейнерных подов, ускоряя ваш рабочий процесс отладки.

Освоение kubectl logs и describe для эффективной отладки подов

Когда под Kubernetes выходит из строя, kubectl describe и kubectl logs обычно подсказывают, где искать дальше. describe объясняет, что пытался сделать Kubernetes. logs показывает, что контейнер записал до, во время или после сбоя.

Эти команды предоставляют разные, но взаимодополняющие представления о состоянии и истории пода Kubernetes. kubectl describe предоставляет метаданные пода, статус, переменные окружения и, что критически важно, историю системных событий. kubectl logs предоставляет потоки стандартного вывода (stdout) и стандартной ошибки (stderr), сгенерированные самим контейнеризированным приложением.

Хитрость заключается в том, чтобы использовать их в правильном порядке. Если под никогда не был запланирован, логи не помогут. Если под запускается и завершает работу, события могут только сообщить, что он аварийно завершился; логи приложения обычно объясняют, почему.


Трехэтапный рабочий процесс отладки подов

Прежде чем углубляться в команды, полезно понять типичный рабочий процесс отладки:

  1. Проверка статуса: Используйте kubectl get pods для определения состояния сбоя (Pending, CrashLoopBackOff, ImagePullBackOff и т.д.).
  2. Получение контекста и событий: Используйте kubectl describe pod, чтобы понять, почему произошел переход состояния (например, сбой планировщика, сбой проверки активности, сбой монтирования тома).
  3. Проверка вывода приложения: Используйте kubectl logs для изучения поведения приложения во время выполнения (например, ошибки конфигурации, сбои подключения к базе данных, трассировки стека).

1. kubectl describe: Инструмент системной триаж

kubectl describe — это первая команда, которую следует запускать, когда под ведет себя плохо. Она не показывает вывод приложения, но предоставляет критически важные метаданные и историю, которые сам Kubernetes записал о поде.

Базовое использование

Для базового использования требуется только имя пода:

kubectl describe pod my-failing-app-xyz789

Явно указывайте пространства имен, если вы не находитесь в пространстве имен по умолчанию:

kubectl describe pod my-failing-app-xyz789 -n payments

Если вы знаете только развертывание или метку, сначала найдите под:

kubectl get pods -n payments -l app=checkout -o wide

Ключевые разделы в выводе

При просмотре вывода describe сосредоточьтесь на этих критических разделах:

A. Статус и состояние

Посмотрите на поле Status вверху, а затем просмотрите состояния отдельных контейнеров внутри пода. Это говорит вам, находится ли контейнер в состоянии Running, Waiting или Terminated, и указывает причину этого состояния.

Поле Статус/Причина Значение
Status Pending Под ожидает планирования или ему не хватает ресурсов.
Reason ContainerCreating Среда выполнения контейнера извлекает образ или выполняет настройку.
State Waiting / Reason: CrashLoopBackOff Контейнер запускался и многократно завершал работу.
State Terminated / Exit Code Контейнер завершил выполнение. Ненулевые коды выхода обычно указывают на ошибки.

B. Конфигурация контейнера

Этот раздел проверяет, что ваши переменные окружения, запросы/лимиты ресурсов, монтирования томов и проверки активности/готовности определены корректно и соответствуют примененному манифесту.

C. Раздел Events (Критически важно)

Раздел Events, расположенный внизу вывода, является, пожалуй, самой ценной частью. Он предоставляет хронологический журнал того, что плоскость управления Kubernetes сделала для пода и с подом, включая предупреждения и ошибки.

Распространенные ошибки, выявляемые Events:

  • Проблемы планирования: Warning FailedScheduling: Указывает, что планировщик не смог найти подходящий узел (например, из-за ограничений ресурсов, меток узлов или правил сродства).
  • Сбои извлечения образа: Warning Failed: ImagePullBackOff: Указывает, что имя образа неверно, тег не существует или у Kubernetes нет учетных данных для извлечения из частного реестра.
  • Ошибки томов: Warning FailedAttachVolume: Указывает на проблемы с подключением внешнего хранилища.

Совет: Если раздел Events чист и контейнер запустился, проблема часто связана с приложением: неверная переменная окружения, неудачная миграция, отсутствующий секрет, недоступная зависимость или процесс, который завершается немедленно.

2. kubectl logs: Проверка вывода приложения

Если describe показывает, что под был успешно запланирован и контейнеры пытались запуститься, следующим шагом будет проверка потоков стандартного вывода с помощью kubectl logs.

Базовое получение логов и потоковая передача в реальном времени

Чтобы просмотреть текущие логи для основного контейнера в поде:

# Получить все логи до текущего момента
kubectl logs my-failing-app-xyz789

# Потоковая передача логов в реальном времени (полезно для мониторинга запуска)
kubectl logs -f my-failing-app-xyz789

Работа с многоконтейнерными подами

Для подов, использующих шаблон Sidecar или другие многоконтейнерные конструкции, вы должны указать, логи какого контейнера вы хотите просмотреть, используя флаг -c или --container.

# Просмотр логов для контейнера 'sidecar-proxy' внутри пода
kubectl logs my-multi-container-pod -c sidecar-proxy

# Потоковая передача логов для основного контейнера приложения
kubectl logs -f my-multi-container-pod -c main-app

Отладка перезапускающихся контейнеров (--previous)

Один из наиболее распространенных сценариев отладки — состояние CrashLoopBackOff. Когда контейнер перезапускается, kubectl logs показывает только вывод текущей (неудачной) попытки, который часто содержит только сообщение о запуске перед сбоем.

Чтобы просмотреть логи предыдущего, завершенного экземпляра, который содержит фактическую ошибку, вызвавшую завершение, используйте флаг --previous (-p):

# Просмотр логов предыдущего, аварийно завершившегося экземпляра контейнера
kubectl logs my-crashloop-pod --previous

# Комбинируйте с указанием контейнера при необходимости
kubectl logs my-crashloop-pod -c worker --previous

Ограничение вывода

Для логов с высоким объемом получение всей истории может быть медленным или перегружающим. Используйте --tail, чтобы ограничить вывод последними N строками.

# Показать только последние 50 строк логов контейнера
kubectl logs my-high-traffic-app --tail=50

Вы также можете добавить временные метки и временное окно:

kubectl logs my-high-traffic-app --tail=100 --timestamps
kubectl logs my-high-traffic-app --since=10m

Для развертывания последние версии kubectl могут получать логи по имени рабочей нагрузки:

kubectl logs deploy/checkout-api -n payments --tail=100

Когда это слишком широко, используйте селектор меток:

kubectl logs -n payments -l app=checkout --all-containers=true --tail=50

3. Комбинирование методов для продвинутой диагностики

Эффективная отладка часто включает быстрое переключение между describe и конкретными командами logs.

Пример: Диагностика сбоя проверки активности (Liveness Probe)

Представьте, что под застрял в состоянии Running, но периодически перезапускается, вызывая сбои.

Шаг 1: Проверьте describe для системного представления.

kubectl describe pod web-server-dpl-abc

Вывод показывает в разделе Events:

Type     Reason      Age   From               Message
----     ------      ----  ----               -------
Warning  Unhealthy   2s    kubelet, node-a01  Liveness probe failed: HTTP GET http://10.42.0.5:8080/health failed: 503 Service Unavailable

Вывод из Шага 1: Контейнер работает, но проверка активности (Liveness probe) не проходит с ошибкой 503, что заставляет Kubernetes перезапускать контейнер.

Шаг 2: Проверьте logs для контекста приложения.

Теперь выясните, почему приложение возвращает статус 503, что является сбоем на уровне приложения.

kubectl logs web-server-dpl-abc --tail=200

Вывод логов показывает:

2023-10-26 14:01:15 ERROR Database connection failure: Timeout connecting to DB instance 192.168.1.10

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

Пример: Ожидающий под без логов

Под в состоянии Pending часто не имеет полезных логов контейнера, потому что ни один контейнер еще не запустился.

kubectl get pod report-worker-6f9c7b9b7d-f2q8m -n analytics

Вывод:

NAME                                  READY   STATUS    RESTARTS   AGE
report-worker-6f9c7b9b7d-f2q8m        0/1     Pending   0          4m

Сразу переходите к describe:

kubectl describe pod report-worker-6f9c7b9b7d-f2q8m -n analytics

События могут показать:

Warning  FailedScheduling  default-scheduler  0/6 nodes are available: 6 Insufficient memory.

Это не ошибка приложения. Под запрашивает больше памяти, чем может выделить планировщик. Следующий шаг — проверить запросы развертывания, емкость кластера, метки узлов и поведение автомасштабирования:

kubectl get deploy report-worker -n analytics -o yaml
kubectl top nodes

Пример: ImagePullBackOff

Для ImagePullBackOff логи обычно пусты, потому что образ контейнера так и не запустился. describe дает полезную ошибку:

kubectl describe pod api-7dfb9c8b7f-bd2p9 -n staging

Распространенные сообщения событий включают тег образа, который не существует, ошибку аутентификации в частном реестре или проблему DNS/сети при достижении реестра. Исправление может быть таким же простым, как исправление тега:

kubectl set image deploy/api api=registry.example.com/api:2026-05-24 -n staging

Или может потребоваться проверка секрета для извлечения образа:

kubectl get secret regcred -n staging
kubectl describe serviceaccount default -n staging

Пример: Многоконтейнерный под с тихим приложением

Сайдбары могут скрыть сигнал, если вы смотрите на неправильный контейнер. Сначала перечислите имена контейнеров:

kubectl get pod checkout-84f7c9d7bf-px5mx -n payments \
  -o jsonpath='{.spec.containers[*].name}{"\n"}'

Затем целенаправленно проверьте каждый:

kubectl logs checkout-84f7c9d7bf-px5mx -n payments -c checkout --tail=100
kubectl logs checkout-84f7c9d7bf-px5mx -n payments -c envoy --tail=100

Если логи приложения тихие, но логи прокси показывают сбои подключения к вышестоящим сервисам, под может быть здоров с точки зрения Kubernetes, в то время как трафик все еще не проходит из-за конфигурации сервисной сетки или прокси.

Лучшие практики и предупреждения

Практика Команда Обоснование
Всегда проверяйте предыдущие логи kubectl logs --previous Необходимо для диагностики CrashLoopBackOff. Критическая ошибка почти всегда находится в предыдущем запуске.
Указывайте контейнеры kubectl logs -c <name> Избегает двусмысленности в многоконтейнерных подах и предотвращает получение логов от непредназначенных сайдбаров.
Используйте метки для массовых операций kubectl logs -l app=frontend -f Позволяет потоковую передачу логов из нескольких подов, соответствующих селектору, одновременно (полезно для rolling updates).
Предупреждение: Ротация логов N/A Узлы Kubernetes выполняют ротацию логов. Логи старше настроенной политики хранения узла (часто несколько дней или на основе размера) будут удалены и недоступны через kubectl logs. Используйте внешнее централизованное решение для ведения логов (например, Fluentd, Loki, Elastic Stack) для долгосрочного хранения.

Что эти команды не могут вам сказать

kubectl logs показывает только stdout и stderr контейнера, сохраненные узлом. Если приложение пишет в файл внутри контейнера, kubectl logs может ничего не показать. Это проблема дизайна ведения логов, а не проблема kubectl.

kubectl describe показывает состояние объекта Kubernetes и недавние события, но события не являются постоянными журналами аудита. Старые события удаляются. Для длительных расследований копируйте соответствующий вывод в заметки об инциденте.

Ни одна из этих команд не заменяет метрики. Под может работать и вести логи нормально, в то время как троттлинг CPU, давление памяти или задержки нижестоящих сервисов вызывают видимые пользователем проблемы. После describe и logs следующими командами часто являются:

kubectl top pod -n payments
kubectl top node
kubectl get events -n payments --sort-by=.lastTimestamp

Используйте describe в первую очередь, когда Kubernetes не смог создать или поддерживать работу пода. Используйте logs в первую очередь, когда под работает, но приложение ведет себя неправильно. Переключайтесь между ними, пока не сможете отделить симптомы платформы от симптомов приложения.

Рабочий процесс отладки, который можно использовать повторно

Когда вы находитесь под давлением, используйте один и тот же процесс каждый раз:

kubectl get pod <pod> -n <namespace> -o wide
kubectl describe pod <pod> -n <namespace>
kubectl logs <pod> -n <namespace> --all-containers=true --tail=100
kubectl logs <pod> -n <namespace> --all-containers=true --previous --tail=100
kubectl get events -n <namespace> --sort-by=.lastTimestamp

Порядок имеет значение. get pod -o wide сообщает вам узел, IP пода, количество перезапусков и возраст. describe сообщает вам детали планирования, образа, тома, проверки и состояния контейнера. Текущие логи показывают, что делает работающий контейнер сейчас. Предыдущие логи фиксируют сбой, который уже произошел. События показывают, происходит ли та же проблема во всем пространстве имен.

Для развертываний добавьте проверку развертывания (rollout):

kubectl rollout status deploy/<name> -n <namespace>
kubectl describe deploy/<name> -n <namespace>
kubectl get rs -n <namespace> -l app=<label>

Иногда под, который вы отлаживаете, принадлежит старому ReplicaSet во время развертывания. Если вы исправите развертывание, но продолжите читать логи из старого завершающегося пода, вы можете полчаса гоняться за неправильной проблемой.

Правильное чтение перезапусков

Столбец RESTARTS — это подсказка, а не диагноз. Количество перезапусков, равное 1 после осушения узла, может быть безвредным. Количество перезапусков, которое увеличивается каждую минуту, является активным сбоем. Используйте describe, чтобы проверить последнее состояние:

Last State:     Terminated
  Reason:       Error
  Exit Code:    1
  Started:      Sun, 24 May 2026 10:14:02 +0800
  Finished:     Sun, 24 May 2026 10:14:07 +0800

Код выхода 1 обычно означает, что процесс завершился с общей ошибкой приложения. 137 часто означает, что процесс был убит, обычно из-за превышения лимитов памяти, хотя вы должны подтвердить это с помощью поля Reason и контекста узла/среды выполнения контейнера. 143 часто появляется, когда процесс получает SIGTERM во время нормального завершения. Не относитесь к каждому ненулевому коду выхода как к одному и тому же типу сбоя.

Когда подозревается нехватка памяти, ищите:

Reason:       OOMKilled
Exit Code:    137

Затем сравните лимит контейнера с фактическим использованием:

kubectl describe pod <pod> -n <namespace> | rg -A5 'Limits|Requests'
kubectl top pod <pod> -n <namespace>

Если metrics-server не установлен, kubectl top не будет работать. В этом случае используйте систему метрик вашей платформы или инструментарий на уровне узла.