Мониторинг ресурсов Kubernetes: сбор метрик CPU, памяти, диска и сети с kube-state-metrics и node-exporter | AdminWiki

Мониторинг ресурсов Kubernetes: сбор метрик CPU, памяти, диска и сети с kube-state-metrics и node-exporter

26 июля 2026 9 мин. чтения

Введение: зачем нужен мониторинг ресурсов в Kubernetes

Поды зависают в статусе Pending из-за нехватки CPU. Узлы уходят в NotReady при заполнении диска на 95%. Сетевые задержки между сервисами растут, а диагностика занимает часы. Это типичные инциденты в кластерах Kubernetes, работающих без мониторинга.

Мониторинг ресурсов - обязательный компонент production-инфраструктуры. Без него вы узнаете о проблеме от пользователей, а не от системы оповещений. Стек Prometheus, kube-state-metrics, node-exporter и Grafana решает эту задачу: собирает метрики CPU, памяти, диска и сети, визуализирует их и отправляет алерты при отклонениях.

В этой статье - пошаговая настройка сбора ключевых метрик производительности. Вы развернете kube-state-metrics и node-exporter через Helm, настроите ServiceMonitor для Prometheus Operator, создадите дашборды в Grafana и сконфигурируете алерты для критических ситуаций. Все конфигурации проверены на кластерах Kubernetes 1.30 и актуальны на июль 2026 года.

Для комплексного подхода к наблюдаемости изучите пошаговую настройку полного стека мониторинга Kubernetes, где разобрана установка Prometheus, Grafana и Alertmanager с нуля.

Архитектура мониторинга: как компоненты собирают метрики

Поток метрик в кластере выглядит так:

  • node-exporter запускается как DaemonSet на каждом узле и отдает метрики CPU, памяти, дискового пространства и сетевых интерфейсов по эндпоинту /metrics.
  • kube-state-metrics слушает API Kubernetes и генерирует метрики состояния объектов: подов, деплойментов, узлов, PVC. Он не смотрит на потребление ресурсов - только на желаемое и текущее состояние.
  • Prometheus забирает метрики с обоих экспортеров через механизм scrape с интервалом 15-30 секунд и сохраняет в своей time-series базе.
  • Grafana подключается к Prometheus как к источнику данных и строит дашборды.
  • Alertmanager получает алерты от Prometheus, группирует их и отправляет в Slack, Telegram или email.

Prometheus Operator упрощает настройку: вместо правки configmap с scrape_configs вы создаете ресурсы ServiceMonitor или PodMonitor, а оператор автоматически генерирует конфигурацию Prometheus. Этот подход - стандарт с 2020 года и остается основным в 2026.

Установка kube-state-metrics и node-exporter

Установка через Helm - промышленный стандарт. Оба чарта находятся в репозитории prometheus-community. Если вы еще не работали с этим стеком, начните с руководства по развертыванию Prometheus и Grafana.

Установка kube-state-metrics через Helm

Добавьте репозиторий и установите чарт:

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install kube-state-metrics prometheus-community/kube-state-metrics \
  --namespace monitoring \
  --create-namespace \
  --set rbac.create=true

Для тонкой настройки создайте values.yaml:

# values-kube-state-metrics.yaml
collectors:
  pods: true
  nodes: true
  deployments: true
  persistentvolumeclaims: true
  namespaces: true

rbac:
  create: true

serviceMonitor:
  enabled: true
  namespace: monitoring

Примените конфигурацию:

helm upgrade kube-state-metrics prometheus-community/kube-state-metrics \
  --namespace monitoring \
  -f values-kube-state-metrics.yaml

Проверьте, что под запустился:

kubectl get pods -n monitoring -l app.kubernetes.io/name=kube-state-metrics

Установка node-exporter через Helm

Node-exporter разворачивается как DaemonSet - по одному экземпляру на каждый узел, включая control-plane:

helm install node-exporter prometheus-community/prometheus-node-exporter \
  --namespace monitoring \
  --set tolerations[0].operator=Exists \
  --set serviceMonitor.enabled=true \
  --set serviceMonitor.namespace=monitoring

Флаг tolerations[0].operator=Exists разрешает запуск на control-plane узлах, где обычно настроены taint-ы. Проверьте метрики напрямую с пода:

kubectl exec -n monitoring daemonset/node-exporter -- wget -qO- localhost:9100/metrics | head -20

Вы увидите метрики node_cpu_seconds_total, node_memory_MemAvailable_bytes и другие.

Настройка сбора метрик в Prometheus

ServiceMonitor - ресурс Prometheus Operator, который указывает, какие сервисы нужно опрашивать. Prometheus автоматически подхватывает ServiceMonitor с лейблом release: prometheus (значение по умолчанию для kube-prometheus-stack).

Создание ServiceMonitor для kube-state-metrics

# servicemonitor-kube-state-metrics.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: kube-state-metrics
  namespace: monitoring
  labels:
    release: prometheus
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: kube-state-metrics
  endpoints:
  - port: http
    interval: 30s
    scrapeTimeout: 10s
  namespaceSelector:
    matchNames:
    - monitoring

Примените манифест и проверьте таргеты в Prometheus: откройте http://prometheus:9090/targets и найдите группу serviceMonitor/monitoring/kube-state-metrics. Все эндпоинты должны быть в состоянии UP.

Создание ServiceMonitor для node-exporter

# servicemonitor-node-exporter.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: node-exporter
  namespace: monitoring
  labels:
    release: prometheus
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: prometheus-node-exporter
  endpoints:
  - port: metrics
    interval: 15s
    scrapeTimeout: 5s
    relabelings:
    - sourceLabels: [__meta_kubernetes_pod_node_name]
      targetLabel: node
  namespaceSelector:
    matchNames:
    - monitoring

Параметр relabelings добавляет лейбл node с именем узла Kubernetes - это удобно для фильтрации в Grafana и алертах.

Ключевые метрики для мониторинга ресурсов

Тысячи метрик от экспортеров сводятся к двум-трем критичным показателям на каждый тип ресурса. Вот что нужно отслеживать в первую очередь.

Метрики CPU

node_cpu_seconds_total - счетчик времени, которое CPU провел в разных режимах (user, system, idle, iowait). Для расчета загрузки используйте rate():

100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance) * 100)

Этот запрос возвращает процент utilization. Значение выше 90% на протяжении 5 минут - повод для алерта.

kube_pod_container_resource_requests{resource="cpu"} - запрошенные ресурсы CPU для контейнеров. Сравнение requests с фактическим потреблением помогает выявить перезапрос (overprovisioning) или, наоборот, недозапрос, ведущий к троттлингу.

Метрики памяти

node_memory_MemAvailable_bytes - доступная память на узле с учетом кеша и буферов. Это точнее, чем MemFree_bytes, потому что Linux активно использует свободную память под кеш.

(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100

Результат - процент использованной памяти. Порог 90% означает, что узел близок к нехватке.

container_memory_working_set_bytes - реальное потребление памяти контейнером, включая анонимные страницы и кеш, который нельзя вытеснить. Именно эту метрику kubelet сравнивает с limits. Превышение limits приводит к OOMKill.

Метрики диска

node_filesystem_avail_bytes - свободное место на файловой системе. Фильтруйте по mountpoint, исключая временные FS:

(node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100

Значение ниже 15% - критично. При 5% kubelet начнет эвакуировать поды с узла.

kubelet_volume_stats_available_bytes - свободное место на Persistent Volume. Отслеживайте по каждому PVC, чтобы предотвратить остановку StatefulSet-приложений.

Метрики сети

node_network_receive_bytes_total и node_network_transmit_bytes_total - счетчики входящего и исходящего трафика по сетевым интерфейсам. Используйте rate() для получения полосы пропускания:

rate(node_network_receive_bytes_total{device!="lo"}[5m]) * 8

Умножение на 8 переводит байты в биты для оценки утилизации сетевого канала. Насыщение канала - частая причина деградации сервисов, которую сложно диагностировать без метрик.

Создание дашбордов в Grafana

Хороший дашборд показывает общую картину кластера за 5 секунд и позволяет провалиться в детали за два клика. Рекомендованная структура: обзор всех узлов, детализация по конкретному узлу, топ подов по потреблению.

Готовые дашборды с Grafana.com (ID 1860 для node-exporter, ID 13332 для kube-state-metrics) можно импортировать и адаптировать. Для глубокой диагностики проблем с подами и узлами используйте руководство по диагностике через метрики мониторинга - там собраны PromQL-запросы для быстрого поиска корневой причины аварии.

Панель «Обзор узлов»

Четыре ряда по числу ресурсов. Каждый ряд - Stat-панель с текущим значением и Sparkline за 6 часов.

CPU utilization %:

100 - (avg(rate(node_cpu_seconds_total{mode="idle", node=~"$node"}[5m])) by (node) * 100)

Переменная $node позволяет выбрать конкретный узел или все сразу.

Memory usage %:

(1 - (node_memory_MemAvailable_bytes{node=~"$node"} / node_memory_MemTotal_bytes{node=~"$node"})) * 100

Disk usage %:

(1 - (node_filesystem_avail_bytes{mountpoint="/", node=~"$node"} / node_filesystem_size_bytes{mountpoint="/", node=~"$node"})) * 100

Network traffic - TimeSeries с двумя линиями:

rate(node_network_receive_bytes_total{device!="lo", node=~"$node"}[5m]) * 8
rate(node_network_transmit_bytes_total{device!="lo", node=~"$node"}[5m]) * 8

Панель «Топ подов по потреблению ресурсов»

Таблица с колонками Namespace, Pod, CPU Usage, Memory Usage. PromQL для CPU:

topk(10, sum(rate(container_cpu_usage_seconds_total{container!="", pod!=""}[5m])) by (pod, namespace))

Для памяти:

topk(10, sum(container_memory_working_set_bytes{container!="", pod!=""}) by (pod, namespace))

Эта панель мгновенно выявляет «прожорливые» поды, которые потребляют ресурсы непропорционально своей роли.

Настройка алертов для критических ситуаций

Алерты превращают мониторинг из пассивного наблюдения в активную защиту. Пороговые значения настраиваются под конкретную инфраструктуру, но есть универсальные правила, которые работают в 90% случаев.

Алерты по ресурсам узлов

Создайте ресурс PrometheusRule:

# prometheusrule-node-resources.yaml
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: node-resources
  namespace: monitoring
  labels:
    release: prometheus
spec:
  groups:
  - name: node-resources
    rules:
    - alert: HighCPUUsage
      expr: (1 - avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance)) * 100 > 90
      for: 5m
      labels:
        severity: warning
      annotations:
        summary: "Высокая загрузка CPU на узле {{ $labels.instance }}"
        description: "CPU utilization = {{ $value | humanize }}% на протяжении 5 минут"

    - alert: LowMemory
      expr: (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100 < 10
      for: 5m
      labels:
        severity: critical
      annotations:
        summary: "Мало свободной памяти на узле {{ $labels.instance }}"
        description: "Доступно {{ $value | humanize }}% памяти"

    - alert: DiskSpaceFillingUp
      expr: (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100 < 15
      for: 5m
      labels:
        severity: warning
      annotations:
        summary: "Заканчивается место на диске {{ $labels.instance }}"
        description: "Свободно {{ $value | humanize }}% на корневом разделе"

    - alert: DiskSpaceCritical
      expr: (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100 < 5
      for: 1m
      labels:
        severity: critical
      annotations:
        summary: "Критически мало места на диске {{ $labels.instance }}"
        description: "Свободно {{ $value | humanize }}%. Kubelet начнет эвакуацию подов"

Алерты по состоянию Kubernetes-объектов

# prometheusrule-kubernetes-state.yaml
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: kubernetes-state
  namespace: monitoring
  labels:
    release: prometheus
spec:
  groups:
  - name: kubernetes-state
    rules:
    - alert: NodeNotReady
      expr: kube_node_status_condition{condition="Ready",status="true"} == 0
      for: 5m
      labels:
        severity: critical
      annotations:
        summary: "Узел {{ $labels.node }} в статусе NotReady"
        description: "Узел не готов принимать поды более 5 минут"

    - alert: PodCrashLoopBackOff
      expr: kube_pod_container_status_waiting_reason{reason="CrashLoopBackOff"} > 0
      for: 5m
      labels:
        severity: warning
      annotations:
        summary: "Под {{ $labels.namespace }}/{{ $labels.pod }} в CrashLoopBackOff"
        description: "Контейнер {{ $labels.container }} перезапускается циклически"

Alertmanager маршрутизирует эти алерты в нужные каналы. Интеграция со Slack, Telegram и email настраивается в конфигурации Alertmanager. Для актуальных шаблонов алертов и практик 2026 года изучите руководство по наблюдаемости для высоконагруженных систем.

Типовые проблемы и их решение

Метрики не появляются в Prometheus. Проверьте, что ServiceMonitor имеет лейбл release: prometheus (или тот, который указан в serviceMonitorSelector у Prometheus). Проверьте сетевые политики: Prometheus должен достучаться до сервиса экспортера по порту metrics. Команда для диагностики:

kubectl port-forward -n monitoring svc/prometheus-operated 9090:9090

Откройте /targets и найдите проблемный эндпоинт - там будет детализация ошибки.

Высокая кардинальность метрик. Kube-state-metrics генерирует метрики с лейблами pod, container, namespace. В большом кластере это миллионы временных рядов. Решение - relabel_configs в ServiceMonitor, которые дропают ненужные лейблы:

metricRelabelings:
- action: drop
  regex: container_id|image_id|pod_id
  sourceLabels: [__name__]

Node-exporter потребляет много CPU. Отключите ненужные коллекторы через аргументы запуска. Например, если вы не используете текстильные коллекторы (bonding, infiniband), отключите их:

--no-collector.bonding --no-collector.infiniband

В values.yaml для Helm это флаги в разделе extraArgs.

Дублирование метрик с control-plane узлов. Если вы используете managed Kubernetes (GKE, EKS, AKS), метрики control-plane могут дублироваться с вашими node-exporter. Фильтруйте их по лейблу node, исключая master-узлы, или настройте отдельный ServiceMonitor только для worker-узлов.

Заключение: мониторинг как основа стабильности

Настроенный стек Prometheus, kube-state-metrics, node-exporter и Grafana дает полную прозрачность ресурсов кластера. Вы видите загрузку CPU, потребление памяти, свободное место на дисках и сетевую активность в реальном времени. Алерты предупреждают о проблемах до того, как они затронут пользователей.

В 2026 году этот стек остается стандартом индустрии для мониторинга Kubernetes. Он не зависит от облачного провайдера, работает на bare-metal и в любых managed-кластерах. Конфигурации из этой статьи применимы к версиям Kubernetes 1.28-1.31.

Следующий шаг - расширение наблюдаемости за пределы инфраструктурных метрик. Подключите трейсинг приложений через OpenTelemetry и централизованное логирование через Loki. Для мониторинга кластерных решений за пределами Kubernetes (Pacemaker, Ceph) используйте руководство по мониторингу кластеров серверов.

Поделиться:
Сохранить гайд? В закладки браузера