Введение / Зачем это нужно
В Kubernetes под (pod) — это минимальная единица развертывания, и когда что-то идет не так, отладка становится критической. Команда kubectl debug позволяет запустить временный отладочный контейнер (ephemeral container) внутри проблемного пода, чтобы inspect файловую систему, процессы и сетевые настройки без изменения конфигурации пода. Этот гайд покажет, как эффективно использовать kubectl debug для диагностики, начиная с проверки статуса пода и заканчивая сбором ключевых данных.
Требования / Подготовка
Перед началом убедитесь, что:
- Установлен
kubectl(версия 1.20+) и настроен доступ к кластеру Kubernetes (kubectl cluster-info). - У вашего аккаунта есть права на создание ephemeral containers в целевом namespace (роль
pods/execили аналогичная). - Вы знаете имя пода и namespace, который нужно отладить.
- Рекомендуется familiarity с базовыми командами
kubectl(get, describe, logs).
Пошаговая инструкция
Шаг 1: Проверка статуса пода и сбор информации
Первым делом получите общую информацию о поде, чтобы понять его состояние:
kubectl get pods -n <namespace>
Обратите внимание на поле STATUS (например, Running, CrashLoopBackOff, Error) и RESTARTS.
Затем опишите под для деталей о событиях, контейнерах и условиях:
kubectl describe pod <pod-name> -n <namespace>
В выводе ищите разделы Events, Containers и Conditions. Частые проблемы: Failed события, ImagePullBackOff, OOMKilled.
Наконец, посмотрите логи контейнеров. Если в поде несколько контейнеров, используйте --all-containers:
kubectl logs <pod-name> -n <namespace> --all-containers=true
Если под перезапускается, добавьте --previous, чтобы увидеть логи с предыдущего экземпляра контейнера:
kubectl logs <pod-name> -n <namespace> --previous --all-containers=true
Шаг 2: Запуск отладочного контейнера с kubectl debug
Команда kubectl debug добавляет ephemeral container в существующий pod. Ephemeral container — это временный контейнер, который разделяет Namespace сети и IPC с основными контейнерами, но имеет отдельное PID namespace (если не указано иное).
Используйте образ с инструментами для диагностики. busybox подходит для базовых команд (sh, ps, netstat). Для сетевой отладки можно использовать nicolaka/netshoot.
kubectl debug -it <pod-name> -n <namespace> --image=busybox
Опции:
-it— интерактивный режим с TTY.--image— образ для отладочного контейнера.--target=<container-name>— если нужно прикрепиться к конкретному контейнеру в pod (разделяет его Namespace).--share-processes— чтобы отладочный контейнер видел процессы основного контейнера (разделяет PID namespace).
Пример с целевым контейнером и общим PID namespace:
kubectl debug -it <pod-name> -n <namespace> --image=busybox --target=app-container --share-processes
После выполнения команды вы окажетесь внутри оболочки отладочного контейнера.
Шаг 3: Диагностика внутри отладочного контейнера
В отладочном контейнере у вас есть доступ к файловой системе и (опционально) процессам основного контейнера. Выполните следующие команды для сбора информации:
- Процессы: проверьте, какие процессы запущены. Если использовали
--share-processes, вы увидите процессы основного контейнера.ps aux top # если установлен - Файловая система: осмотрите структуру, права доступа и наличие критических файлов.
df -h # использование диска ls -la / # корневая файловая система ls -la /app # например, директория приложения cat /etc/os-release # информация об ОС в контейнере - Сеть: проверьте сетевые подключения и доступность портов.
netstat -tuln # слушающие порты curl http://localhost:8080 # если приложение слушает порт 8080 ip addr # сетевые интерфейсы - Переменные окружения: посмотрите, какие переменные установлены.
env - Логи приложения: если логи пишутся в файл, прочитайте его.
tail -f /var/log/app.log - Дополнительно: если образ содержит утилиты (например,
strace,lsof), используйте их для углубленной диагностики.
Шаг 4: Анализ логов и событий кластера
Помимо логов контейнеров, проверьте события кластера, связанные с подом. События могут указать на проблемы с планированием, отказами в ресурсах или ошибками безопасности.
kubectl get events -n <namespace> --field-selector involvedObject.name=<pod-name> --sort-by='.lastTimestamp'
Обратите внимание на события с типом Warning и сообщениями вроде Failed или Unhealthy.
Если под crashed, убедитесь, что вы просмотрели логи с предыдущего запуска (как в Шаге 1). Также проверьте логи kubelet на ноде, где запущен pod (требует доступа к ноде).
Шаг 5: Завершение отладки и очистка
После сбора необходимых данных выйдите из отладочного контейнера:
exit
# или Ctrl+D
Ephemeral container автоматически удалится при следующем перезапуске пода (например, если pod управляется Deployment и происходит rolling update). Вручную удалять ephemeral container не требуется, так как они не отображаются в kubectl get pods как отдельные контейнеры.
Если вы хотите немедленно удалить весь под (например, после тестовой отладки, когда проблема исправлена), выполните:
kubectl delete pod <pod-name> -n <namespace>
Но будьте осторожны: если pod управляется контроллером (Deployment, StatefulSet), он будет пересоздан. Убедитесь, что изменения (например, исправление образа) уже применены.
Проверка результата
Успешная отладка означает, что вы определили причину проблемы. Например:
- Нашли ошибку в логах приложения (например,
Connection refused). - Обнаружили, что контейнер не имеет доступа к файлу из-за wrong permissions.
- Увидели, что процесс падает из-за нехватки памяти (OOM).
- Выявили, что конфигурация приложения отсутствует или некорректна.
После исправления (обновление Deployment, изменение ConfigMap, увеличение ресурсов) перезапустите под и убедитесь, что он переходит в состояние Running без перезапусков. Мониторьте логи в реальном времени:
kubectl logs -f <pod-name> -n <namespace>
Возможные проблемы
Ошибка доступа (Forbidden)
Если вы получаете Error from server (Forbidden): pods "<pod-name>" is forbidden, у вашего пользователя или service account недостаточно прав. Ephemeral containers требуют разрешения pods/ephemeralcontainers. Обратитесь к администратору кластера, чтобы добавить роль, например:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: <namespace>
name: pod-debugger
rules:
- apiGroups: [""]
resources: ["pods/ephemeralcontainers"]
verbs: ["create", "get", "list"]
Затем привяжите роль к вашему аккаунту.
Образ отладки недоступен
Если образ busybox или другой не может быть загружен, проверьте:
- Доступность образа:
docker pull busyboxлокально. - Настройки imagePullSecret в namespace или pod, если используется приватный registry.
- Используйте полное имя образа, включая registry:
kubectl debug -it <pod-name> --image=registry.example.com/busybox:latest.
Под не поддерживает ephemeral containers
Ephemeral containers требуют Kubernetes 1.20+ и включенной фичи (обычно включена по умолчанию). Проверьте версию кластера:
kubectl version --short
Если версия ниже 1.20, kubectl debug может не работать. Альтернативы:
- Временно изменить Deployment, добавив sidecar-контейнер с отладочными инструментами.
- Использовать
kubectl execв работающий контейнер (если он еще жив). - Запустить новый pod с тем же volumes и namespace для диагностики.
Конфликт имен контейнеров
Если в pod уже есть контейнер с именем "debug" (стандартное имя для отладочного контейнера), команда завершится ошибкой. Укажите уникальное имя:
kubectl debug -it <pod-name> --image=busybox --name=debugger
Отладочный контейнер не видит процессы основного контейнера
По умолчанию ephemeral container имеет отдельный PID namespace и не видит процессы основного контейнера. Чтобы поделиться PID namespace, используйте --share-processes. Однако, это работает только если основной контейнер также делит PID namespace (часто по умолчанию). Проверьте конфигурацию пода:
kubectl get pod <pod-name> -o yaml --template='{{.spec.containers[*].securityContext}}'
Если shareProcessNamespace не установлен в true, --share-processes может не сработать. В этом случае, для просмотра процессов основного контейнера используйте kubectl exec напрямую, если контейнер еще работает.