Проблемы в production-кластере Kubernetes в большинстве случаев вызваны не ошибками в коде, а расхождениями в окружении: конфигурации, трафике, зависимостях или данных. Метрики мониторинга - CPU, память, сеть, диск - это прямой срез состояния вашей инфраструктуры, который позволяет локализовать корневую причину аварии за минуты, а не часы.
Общий алгоритм диагностики состоит из трёх шагов. Сначала проверяется статус подов и узлов через kubectl. Затем анализируются метрики потребления ресурсов. Наконец, круг поиска сужается до конкретного компонента - утекающего по памяти контейнера, перегруженного CPU узла или сетевого узкого места. Этот материал даёт готовые критерии и PromQL-запросы для каждого этапа.
Инструментарий, который потребуется: Prometheus для сбора и хранения метрик, Grafana для визуализации, встроенная связка kubectl top и metrics-server для мгновенной оценки потребления. Все инструкции проверены на кластерах Kubernetes 2026 года и ориентированы на практикующих DevOps-инженеров и системных администраторов, которым нужно сократить время простоя.
Введение: почему метрики - ключ к быстрой диагностике
Логи показывают, что произошло. Метрики показывают, в каком состоянии находится система прямо сейчас и как она пришла к этому состоянию. Когда пользователи жалуются на медленную работу сервиса, а поды уходят в CrashLoopBackOff, логи приложения могут молчать или выдавать неспецифичные ошибки. Метрики же сразу указывают на аномалию: потребление памяти растёт без снижения, задержки сети между сервисами увеличились втрое, load average на узле превысил количество ядер.
Для эффективного troubleshooting в Kubernetes используются четыре группы метрик:
- CPU - container_cpu_usage_seconds_total, node_load1/5/15;
- Память - container_memory_working_set_bytes, container_memory_usage_bytes;
- Сеть - container_network_receive_bytes_total, container_network_transmit_bytes_total, метрики latency и packet loss из сервис-мешей;
- Диск - node_disk_io_time_seconds_total, node_disk_read_bytes_total, node_disk_written_bytes_total.
Эти метрики собираются с kubelet, cAdvisor и node-exporter, агрегируются Prometheus и отображаются в Grafana. Для быстрой проверки без дашбордов используется связка metrics-server и kubectl top. Детальнее о развёртывании полного стека мониторинга - в руководстве по настройке Prometheus, Grafana и Alertmanager.
Инструментарий: что использовать для сбора и анализа метрик
Стек диагностики Kubernetes строится на трёх компонентах: сборщик метрик, визуализатор и утилита командной строки. Каждый решает свою задачу и дополняет остальные.
Prometheus и Grafana: основа мониторинга
Prometheus забирает метрики с экспортеров по pull-модели. В стандартную поставку для Kubernetes входят: node-exporter на каждом узле для системных метрик, kube-state-metrics для объектных метрик кластера (статусы подов, деплойментов, PVC) и cAdvisor, встроенный в kubelet, для контейнерных метрик. Prometheus server хранит временные ряды и предоставляет язык запросов PromQL.
Grafana подключается к Prometheus как к data source и отображает дашборды. Для диагностики обязателен дашборд Kubernetes cluster monitoring, который агрегирует метрики по узлам и неймспейсам. Ключевые метрики для начала анализа:
container_cpu_usage_seconds_total- процессорное время, потреблённое контейнером;container_memory_working_set_bytes- реально используемая память, включая кеш, который не может быть вытеснен;container_network_receive_bytes_totalиcontainer_network_transmit_bytes_total- входящий и исходящий сетевой трафик.
Для продакшен-сред с высокими требованиями к отказоустойчивости мониторинга подойдёт архитектура, описанная в материале по наблюдаемости высоконагруженных систем.
kubectl top и metrics-server: быстрая проверка ресурсов
Metrics-server собирает метрики CPU и памяти с kubelet и предоставляет их через Metrics API. Без него kubectl top не работает. Установка выполняется одной командой:
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yamlПосле установки становятся доступны команды:
kubectl top pods- потребление CPU и памяти всеми подами в текущем неймспейсе;kubectl top pods -A- по всем неймспейсам;kubectl top nodes- потребление ресурсов на каждом узле.
Ограничение metrics-server - отсутствие исторических данных. Он показывает только текущий снимок. Для анализа трендов и ретроспективной диагностики Prometheus обязателен.
Диагностика проблем с подами: CPU и память
Поды - самая подвижная и проблемная часть кластера. Два основных симптома: под не запускается (Pending, CrashLoopBackOff) или работает нестабильно (медленный ответ, периодические рестарты). Метрики CPU и памяти локализуют причину за несколько минут.
Утечка памяти: как обнаружить и подтвердить
Утечка памяти характеризуется монотонным ростом потребления без освобождения после пиковых нагрузок. На графике Grafana это выглядит как восходящая пила: память растёт, затем под рестартует по OOMKilled, и цикл повторяется.
PromQL-запрос для выявления утечки:
rate(container_memory_working_set_bytes{pod=~"my-app.*"}[30m])Если значение стабильно положительное в течение нескольких часов при отсутствии роста трафика - это утечка. Для приложений на Java или Go дополнительно анализируется heap-дамп, но метрики мониторинга дают первичный сигнал.
Нехватка ресурсов: когда подам не хватает CPU или памяти
Нехватка ресурсов отличается от утечки стабильно высоким потреблением, близким к лимитам, без выраженного тренда на повышение. Поды могут оставаться в статусе Running, но отвечать с задержками из-за троттлинга CPU. Диагностика начинается с команды:
kubectl describe pod <pod-name>В секции Events ищите записи вида «insufficient cpu» или «insufficient memory». Если под в Pending - узлам не хватает ресурсов для его размещения. Решение: пересмотреть requests/limits в сторону увеличения, добавить узлы в кластер или настроить Horizontal Pod Autoscaler.
Проверка текущих лимитов:
kubectl get pod <pod-name> -o jsonpath='{.spec.containers[*].resources}'OOMKilled: анализ причин и предотвращение
OOMKilled - событие, при котором ядро Linux принудительно завершает контейнер, превысивший лимит памяти. В выводе kubectl describe pod это отображается как «OOMKilled» с кодом завершения 137. Метрика для анализа:
container_memory_working_set_bytes / container_spec_memory_limit_bytesPromQL для алерта за 5 минут до прогнозируемого превышения:
predict_linear(container_memory_working_set_bytes[1h], 300) > container_spec_memory_limit_bytesТакой алерт даёт время на реакцию: увеличить лимит, масштабировать поды или перезапустить контейнер до того, как OOM-killer вмешается.
Сетевые проблемы: поиск узких мест между сервисами
Сетевые проблемы маскируются под медленную работу приложения. Пользователи жалуются на таймауты, а метрики CPU и памяти в норме. В этом случае проверяются сетевые метрики.
Метрики сети в Kubernetes: что смотреть
Базовые метрики сетевого трафика доступны через cAdvisor и не требуют дополнительных экспортеров:
container_network_receive_bytes_total- входящий трафик;container_network_transmit_bytes_total- исходящий трафик;container_network_receive_packets_dropped_total- потерянные входящие пакеты;container_network_transmit_packets_dropped_total- потерянные исходящие пакеты.
PromQL для просмотра пропускной способности на уровне пода:
rate(container_network_receive_bytes_total{pod=~"my-app.*"}[5m])Резкое падение графика при стабильном трафике указывает на проблему с CNI-плагином или сетевыми политиками.
Анализ задержек и потерь пакетов
Для измерения latency между сервисами используется сервис-меш (Istio, Linkerd) или отдельный экспортер, например k8s-net-latency-exporter. На дашборде Grafana выводится тепловая карта задержек: каждый квадрат - пара сервисов, цвет - медианная задержка за интервал. Если latency между конкретными сервисами выросла втрое за последний час - проблема локализована.
Потери пакетов выше 0.1% уже ощутимы для приложений с частыми запросами. При обнаружении потерь последовательно проверяются: сетевые политики (kubectl get networkpolicies), загрузка сетевых интерфейсов узлов (node_network_receive_bytes_total), MTU-несоответствия между подами и физической сетью. Подробный алгоритм сетевой диагностики разобран в руководстве по устранению сетевых неполадок в Docker и Kubernetes.
Деградация узлов: когда проблема на уровне инфраструктуры
Если метрики подов в норме, но приложение тормозит, проблема может быть на уровне узла. Деградация узла влияет на все поды, которые на нём работают, и часто остаётся незамеченной, пока не приводит к массовым сбоям.
Высокий Load Average: причины и диагностика
Load average - это среднее количество процессов, ожидающих CPU или завершения I/O, за 1, 5 и 15 минут. Значение выше количества ядер CPU на узле указывает на перегрузку. Метрики node-exporter:
node_load1node_load5node_load15
PromQL для выявления перегруженных узлов:
node_load1 / count without (cpu, mode) (node_cpu_seconds_total{mode="idle"}) > 1.5Значение больше 1.5 означает, что очередь задач в полтора раза превышает вычислительные мощности. Причины: слишком много подов на узле, отсутствие requests/limits у подов, фоновые процессы kubelet или container runtime.
Дисковые I/O: когда диск становится узким местом
Высокий I/O wait замедляет все операции чтения и записи на узле. Метрики node-exporter для диагностики:
node_disk_io_time_seconds_total- время, затраченное на I/O;rate(node_disk_io_time_seconds_total[5m])- доля времени, занятая I/O за 5 минут.
Значение выше 0.9 означает, что диск занят обработкой запросов 90% времени. Причины: интенсивная запись логов, активная работа PVC без storage-классов с гарантированным IOPS, фрагментация файловой системы. Решение: перенос подов на другие узлы, увеличение IOPS у томов, настройка мониторинга дискового пространства по инструкции по мониторингу дисков в Docker и Kubernetes.
Практический кейс: от симптома к корневой причине
Рассмотрим реальный сценарий. Пользователи жалуются, что сервис отвечает с задержкой 5–10 секунд вместо обычных 200 мс. Действуем по алгоритму.
Шаг 1. kubectl top pods -n production показывает, что под api-gateway-7d94f8b9c-xk2lm потребляет 1.8 CPU при лимите 2.0. Остальные поды в норме.
Шаг 2. Открываем Grafana, дашборд Kubernetes cluster monitoring, фильтруем по поду api-gateway. График CPU - плато на уровне 90% от лимита. График памяти - монотонный рост с 400 MB до 1.8 GB за последние 6 часов без снижения. Это утечка памяти.
Шаг 3. kubectl describe pod api-gateway-7d94f8b9c-xk2lm подтверждает: последнее состояние - OOMKilled, контейнер перезапускался 4 раза за последние 2 часа.
Шаг 4. Проверяем сетевые метрики: latency между api-gateway и backend-сервисами стабильна - 5–10 мс. Потери пакетов - 0%.
Шаг 5. Проверяем узлы: load average на всех узлах в пределах нормы, I/O wait - менее 0.1.
Вывод: корневая причина - утечка памяти в api-gateway. Временное решение: увеличить лимит памяти до 3 GB через kubectl edit deployment api-gateway, чтобы выиграть время. Постоянное решение: передать разработчикам график потребления памяти за 6 часов и указание на утечку для исправления в коде.
Проактивный мониторинг: настройка алертов для предотвращения аварий
Реактивная диагностика сокращает время восстановления, но не предотвращает инциденты. Проактивный мониторинг с алертами выявляет проблемы до того, как они затронут пользователей.
Алерты на ресурсы подов
Базовый набор правил Prometheus для алертов на поды:
groups:
- name: pod-resources
rules:
- alert: PodMemoryUsageHigh
expr: container_memory_working_set_bytes / container_spec_memory_limit_bytes > 0.9
for: 5m
labels:
severity: warning
annotations:
summary: "Под {{ $labels.pod }} использует более 90% лимита памяти"
- alert: PodCPUThrottling
expr: rate(container_cpu_cfs_throttled_seconds_total[5m]) > 0.1
for: 5m
labels:
severity: warning
annotations:
summary: "Под {{ $labels.pod }} испытывает троттлинг CPU"Параметр for: 5m исключает ложные срабатывания при кратковременных всплесках.
Алерты на состояние узлов
Алерты на деградацию узлов критичны, потому что отказ узла затрагивает десятки подов:
groups:
- name: node-health
rules:
- alert: NodeHighLoad
expr: node_load1 / count without (cpu, mode) (node_cpu_seconds_total{mode="idle"}) > 1.5
for: 10m
labels:
severity: critical
annotations:
summary: "Узел {{ $labels.node }} перегружен, load average превышает количество ядер в 1.5 раза"
- alert: NodeHighIOWait
expr: rate(node_disk_io_time_seconds_total[5m]) > 0.9
for: 10m
labels:
severity: warning
annotations:
summary: "Дисковая подсистема узла {{ $labels.node }} перегружена"Алерты интегрируются с Alertmanager для маршрутизации в Telegram, Slack или PagerDuty. Пороги настраиваются на основе исторических данных конкретного кластера. Методика оценки эффективности инфраструктуры после внедрения мониторинга описана в материале по оценке эффективности инфраструктуры и кода.
Систематический подход к диагностике через метрики мониторинга сокращает среднее время восстановления (MTTR) с часов до минут. Ключевое правило: сначала проверяем метрики ресурсов, затем сетевые задержки, потом состояние узлов. Такой порядок покрывает 90% инцидентов в production-кластерах Kubernetes.