- Отладка и мониторинг
Отладка и мониторинг
Представьте ситуацию: ваше приложение в Kubernetes перестало отвечать на запросы. Пользователи жалуются, но вы не знаете, в чем проблема. Pod запущен? Работает ли сеть? Хватает ли ресурсов? Без правильных инструментов вы работаете вслепую.
В этом уроке вы научитесь диагностировать проблемы в Kubernetes и настраивать мониторинг. Вы узнаете, как использовать kubectl для отладки, как настроить Prometheus и Grafana для мониторинга, и как решать типичные проблемы с Pod.
Когда что-то пошло не так
Первое, что нужно сделать при проблеме — понять, что именно не работает. Начнем с простых проверок.
Задание: проверьте состояние Pod
Когда приложение не работает, первым делом проверьте состояние Pod:
kubectl get pods
Вы увидите список Pod и их статусы. Статус Pod рассказывает о его состоянии. Если Pod в состоянии Pending, значит он еще не размещен на узле — возможно, не хватает ресурсов или есть проблемы с Scheduler. Если Pod в состоянии Running, контейнеры запущены, но это не гарантирует, что приложение работает правильно. Если Pod в состоянии Failed, контейнер завершился с ошибкой — нужно смотреть логи.
Для более детальной информации используйте флаг -o wide:
kubectl get pods -o wide
Это покажет, на каком узле запущен Pod, его IP-адрес и другие детали. Если видите, что Pod постоянно перезапускается (RESTARTS больше 0), это признак проблемы.
Задание: разберитесь, почему Pod не запускается
Создайте проблемный Pod, чтобы попрактиковаться в диагностике:
kubectl run test-pod --image=nginx:wrong-tag
Этот Pod не запустится, потому что образа с таким тегом не существует. Посмотрите подробную информацию:
kubectl describe pod test-pod
Команда describe покажет события, условия, переменные окружения и другую информацию. В секции Events вы увидите, что произошло — например, "Failed to pull image" или "Insufficient memory". Это ключ к пониманию проблемы.
Посмотрите события, связанные с Pod:
kubectl get events --field-selector involvedObject.name=test-pod --sort-by=.metadata.creationTimestamp
События показывают хронологию того, что происходило с Pod. Это помогает понять последовательность проблем.
Задание: посмотрите логи
Логи — основной источник информации о работе приложения. Создайте Pod, который будет писать в логи:
kubectl run log-test --image=busybox --command -- sh -c "while true; do echo 'Hello from pod' $(date); sleep 5; done"
Подождите несколько секунд, затем посмотрите логи:
kubectl logs log-test
Вы увидите сообщения, которые пишет приложение. Для отслеживания логов в реальном времени используйте флаг -f:
kubectl logs -f log-test
Логи будут обновляться по мере появления новых сообщений. Нажмите Ctrl+C, чтобы остановить отслеживание.
Если контейнер перезапустился, вы можете посмотреть логи предыдущего контейнера:
kubectl logs log-test --previous
Это полезно, когда контейнер падает сразу после запуска — логи предыдущего запуска могут содержать информацию об ошибке.
Задание: найдите ошибки в логах
Часто в логах нужно найти конкретные ошибки. Используйте стандартные Unix-инструменты:
kubectl logs log-test | grep -i error
kubectl logs log-test | tail -100
kubectl logs log-test --since=1h | grep ERROR
Эти команды помогут найти проблемные сообщения в большом объеме логов.
Задание: зайдите внутрь контейнера
Иногда нужно исследовать файловую систему или выполнить команды внутри контейнера. Создайте Pod для экспериментов:
kubectl run debug-pod --image=nginx --restart=Never
Подождите, пока Pod запустится, затем выполните команду внутри контейнера:
kubectl exec debug-pod -- ls /usr/share/nginx/html
Для интерактивной сессии используйте флаг -it:
kubectl exec -it debug-pod -- /bin/bash
Теперь вы внутри контейнера и можете выполнять любые команды. Попробуйте посмотреть процессы, проверить сеть, изучить файловую систему. Выйдите из контейнера командой exit.
Проблемы с ресурсами
Часто проблемы связаны с нехваткой ресурсов. Kubernetes может убить Pod, если он превышает лимиты памяти, или не запустить Pod, если на узлах не хватает ресурсов.
Задание: проверьте использование ресурсов
Сначала установите metrics-server, если его еще нет:
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
Подождите минуту, пока metrics-server запустится, затем проверьте использование ресурсов:
kubectl top nodes
kubectl top pods
Вы увидите, сколько CPU и памяти используют узлы и Pod. Если какой-то Pod использует слишком много ресурсов, это может быть причиной проблем.
Посмотрите подробную информацию об узле:
kubectl describe node <node-name>
В секции Allocated resources вы увидите, сколько ресурсов уже выделено и сколько доступно. Если все ресурсы выделены, новые Pod не смогут запуститься.
Задание: создайте Pod, который превышает лимиты
Создайте Pod с лимитом памяти, который будет его превышать:
apiVersion: v1
kind: Pod
metadata:
name: memory-hog
spec:
containers:
- name: test
image: polinux/stress
resources:
limits:
memory: "100Mi"
command: ["stress"]
args: ["--vm", "1", "--vm-bytes", "200M", "--vm-hang", "1"]
Сохраните в memory-hog.yaml и примените:
kubectl apply -f memory-hog.yaml
Подождите несколько секунд, затем проверьте статус:
kubectl get pod memory-hog
kubectl describe pod memory-hog
Вы увидите, что Pod был убит (OOMKilled) из-за превышения лимита памяти. В событиях будет сообщение о том, что контейнер был завершен из-за нехватки памяти.
Сетевые проблемы
Сетевые проблемы — одни из самых сложных для диагностики. Service может не работать из-за неправильной конфигурации или недоступности backend Pod.
Задание: проверьте Service и Endpoints
Создайте Deployment и Service:
kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --port=80
Проверьте Service:
kubectl get service nginx
kubectl describe service nginx
Теперь проверьте Endpoints — это IP-адреса Pod, на которые Service направляет трафик:
kubectl get endpoints nginx
Если Endpoints пустой, значит нет Pod, которые соответствуют селектору Service. Проверьте метки Pod и селектор Service:
kubectl get pods --show-labels
kubectl get service nginx -o yaml | grep selector
Метки Pod должны совпадать с селектором Service. Если они не совпадают, Service не найдет Pod и Endpoints будет пустым.
Задание: протестируйте сетевую связность
Создайте временный Pod с сетевыми инструментами:
kubectl run test-net --image=nicolaka/netshoot --rm -it --restart=Never -- sh
Внутри Pod протестируйте связность с Service:
nslookup nginx.default.svc.cluster.local
curl http://nginx.default.svc.cluster.local
Если DNS не работает, проверьте CoreDNS:
kubectl get pods -n kube-system | grep coredns
kubectl logs -n kube-system -l k8s-app=kube-dns
Если curl не работает, но DNS работает, проблема может быть в самом Service или в Pod. Проверьте, что Pod действительно слушает на нужном порту:
kubectl exec <nginx-pod-name> -- netstat -tlnp
Мониторинг с Prometheus
Когда у вас много Pod и сервисов, нужен централизованный мониторинг. Prometheus собирает метрики и позволяет настраивать алерты.
Задание: установите Prometheus
Установите Prometheus с помощью Helm. Сначала добавьте репозиторий:
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
Установите kube-prometheus-stack, который включает Prometheus, Grafana и множество экспортеров:
helm install prometheus prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--create-namespace
Подождите несколько минут, пока все компоненты запустятся:
kubectl get pods -n monitoring -w
Когда все Pod будут в состоянии Running, откройте Prometheus UI:
kubectl port-forward -n monitoring svc/prometheus-kube-prometheus-prometheus 9090:9090
Откройте http://localhost:9090 в браузере. В Prometheus UI вы можете выполнять запросы к метрикам. Попробуйте запрос:
kube_pod_status_phase
Это покажет фазы всех Pod в кластере. Вы увидите, сколько Pod в состоянии Running, Pending, Failed и так далее.
Задание: создайте простой алерт
Создайте правило алерта для отслеживания падающих Pod:
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: pod-alerts
namespace: monitoring
spec:
groups:
- name: pod.rules
rules:
- alert: PodCrashLooping
expr: rate(kube_pod_container_status_restarts_total[15m]) > 0
for: 5m
labels:
severity: warning
annotations:
summary: "Pod {{ $labels.pod }} is crash looping"
description: "Pod {{ $labels.pod }} in namespace {{ $labels.namespace }} has restarted {{ $value }} times in the last 15 minutes"
Сохраните в pod-alerts.yaml и примените:
kubectl apply -f pod-alerts.yaml
Теперь Prometheus будет отслеживать Pod, которые постоянно перезапускаются, и создавать алерты. Вы можете посмотреть активные алерты в Prometheus UI на вкладке Alerts.
Визуализация с Grafana
Prometheus собирает метрики, но для их визуализации нужен Grafana. К счастью, kube-prometheus-stack уже включает Grafana.
Задание: откройте Grafana
Получите пароль администратора:
kubectl get secret -n monitoring prometheus-grafana -o jsonpath="{.data.admin-password}" | base64 --decode
Откройте Grafana:
kubectl port-forward -n monitoring svc/prometheus-grafana 3000:80
Откройте http://localhost:3000 в браузере и войдите с логином admin и паролем, который вы получили выше.
Задание: изучите готовые дашборды
kube-prometheus-stack включает множество готовых дашбордов. Перейдите в раздел Dashboards и найдите:
- Kubernetes / Compute Resources / Cluster — общее использование ресурсов в кластере
- Kubernetes / Compute Resources / Pod — использование ресурсов Pod
- Kubernetes / Networking / Cluster — сетевые метрики
Откройте дашборд "Kubernetes / Compute Resources / Pod" и выберите namespace default. Вы увидите графики использования CPU и памяти для всех Pod. Это помогает быстро найти Pod, которые потребляют слишком много ресурсов.
Практический пример: диагностика проблемы
Давайте разберем полный процесс диагностики проблемы. Создайте проблемный Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: broken-app
spec:
replicas: 1
selector:
matchLabels:
app: broken
template:
metadata:
labels:
app: broken
spec:
containers:
- name: app
image: nginx:1.21
resources:
limits:
memory: "50Mi"
command: ["sh", "-c", "while true; do dd if=/dev/zero of=/tmp/test bs=1M count=100; sleep 1; done"]
Этот Deployment создаст Pod, который будет пытаться использовать больше памяти, чем разрешено. Сохраните в broken-app.yaml и примените:
kubectl apply -f broken-app.yaml
Теперь диагностируйте проблему по шагам:
Шаг 1: Проверьте общее состояние
kubectl get pods
kubectl get nodes
Шаг 2: Найдите проблемный Pod
kubectl get pods | grep broken
Шаг 3: Проанализируйте состояние Pod
kubectl describe pod -l app=broken
В событиях вы увидите, что Pod был убит из-за превышения лимита памяти.
Шаг 4: Посмотрите логи
kubectl logs -l app=broken --previous
Шаг 5: Проверьте ресурсы
kubectl top pods
kubectl describe node
Шаг 6: Проверьте события
kubectl get events --sort-by=.metadata.creationTimestamp | tail -20
Этот процесс поможет вам систематически находить и решать проблемы в Kubernetes.
Что дальше
Теперь вы знаете основы отладки и мониторинга в Kubernetes. Вы можете диагностировать проблемы с Pod, проверять использование ресурсов, тестировать сетевую связность и настраивать мониторинг с Prometheus и Grafana.
В production важно настроить мониторинг всех критичных компонентов: API Server, etcd, Scheduler, kubelet. Настройте алерты для важных событий, но не переусердствуйте — слишком много алертов притупляет внимание.
Используйте эти инструменты регулярно, и вы сможете быстро находить и решать проблемы в кластере.
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.