kubectl top и Metrics API
kubectl top pod и kubectl top nodes — это окно в текущее ресурсопотребление кластера. За простой командой скрывается полноценный API (metrics.k8s.io), отдельный addon (metrics-server), и сложная цепочка: cgroup → cAdvisor → kubelet → metrics-server → apiserver. Понимая эту цепочку, ясно, почему top показывает только текущий момент и почему он не работает «из коробки» на kind / minikube.
top и htop: как читать системный мониторинг
Что показывает kubectl top
# Использование Pods
kubectl top pod
kubectl top pod -n production
kubectl top pod -A # все namespaces
kubectl top pod --containers # per-container, не агрегат на Pod
kubectl top pod -l app=web
kubectl top pod --sort-by=cpu
kubectl top pod --sort-by=memory
# Использование Nodes
kubectl top nodes
kubectl top nodes --sort-by=cpu
# Pretty output
kubectl top pod --no-headers
Вывод:
NAME CPU(cores) MEMORY(bytes)
web-7d4f-abc12 125m 234Mi
web-7d4f-def34 89m 198Mi
api-6b8c-ghi56 450m 512Mi
Это CPU usage в millicores и memory usage в bytes (с суффиксом Mi/Gi). Числа — текущие (на момент последней scrape, обычно меньше 15 секунд назад).
metrics-server: addon, который собирает данные
metrics-server — это не часть «дефолтного» Kubernetes. Это отдельный addon (Deployment в namespace kube-system). Его задачи:
- Скрейпить kubelet API
/metrics/resourceна каждой ноде каждые 15 секунд. - Хранить последние значения в памяти (RAM, не etcd, не persistent).
- Экспонировать через Metrics API (
metrics.k8s.io/v1beta1) — это API extension через APIService.
# Проверить, установлен ли metrics-server
kubectl get apiservice v1beta1.metrics.k8s.io
# Если NAMESPACE=kube-system и AVAILABLE=True — metrics-server работает
# Посмотреть raw данные Metrics API
kubectl get --raw "/apis/metrics.k8s.io/v1beta1/pods" | jq
kubectl get --raw "/apis/metrics.k8s.io/v1beta1/nodes" | jq
На kind / minikube / k3s metrics-server по умолчанию не установлен. kubectl top упадёт с error: Metrics API not available. Решение: установить отдельно (kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml). На kind часто требуется флаг --kubelet-insecure-tls в args metrics-server-а.
Откуда метрики приходят: cgroup → cAdvisor → kubelet
Ключевые лимиты metrics-server
- Только текущее значение, не история. Нельзя сделать «top за последний час» или «график CPU за день» — для этого нужен Prometheus.
- Только CPU и memory. Никаких network, disk I/O, file descriptor counts, custom application metrics.
- In-memory storage. Если metrics-server рестартует — данные пропадают, восстановление займёт 15 секунд (один scrape cycle).
- Latency ~15-30 секунд. Если процесс вырос за 5 секунд —
kubectl topэто не увидит, пока не пройдёт scrape.
Это намеренный design: metrics-server должен быть lightweight и существовать для двух вещей — kubectl top и HorizontalPodAutoscaler. Для всего остального — Prometheus.
Prometheus stack для production
Полноценный мониторинг — kube-prometheus-stack (Helm chart):
- Prometheus — TSDB, scrape Prometheus-endpoints всего кластера, хранит metrics с retention 15 дней по умолчанию.
- Grafana — UI для запросов и дашбордов.
- AlertManager — обработка алертов.
- node-exporter — DaemonSet, экспонирует metrics ноды (disk, network, FS).
- kube-state-metrics — Deployment, экспонирует metrics ОБЪЕКТОВ Kubernetes.
node-exporter ≠ kube-state-metrics — это разные вещи. node-exporter — usage ресурсов ноды (CPU, mem, disk, network). kube-state-metrics — состояние K8s-объектов (количество Pods в Pending, Replicas Deployment, рестарты container-ов). Оба обычно ставят вместе.
kube-state-metrics: метрики объектов
Экспонирует state K8s objects как Prometheus metrics:
kube_pod_status_phase{namespace="default", pod="web-1", phase="Running"} 1
kube_pod_container_status_restarts_total{pod="web-1", container="app"} 7
kube_deployment_status_replicas_available{deployment="web"} 3
kube_deployment_status_replicas_unavailable{deployment="web"} 1
kube_node_status_condition{node="worker-1", condition="Ready", status="true"} 1
Это не resource usage — это состояние объектов. Используется для алертов типа «есть Pod, который рестартует >5 раз», «Deployment availability < 100%».
HPA: автоматическое масштабирование на основе метрик
HorizontalPodAutoscaler — это потребитель metrics-server (и не только):
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70 # target 70% от cpu requests
HPA controller (внутри kube-controller-manager) каждые 15 секунд опрашивает Metrics API, считает avg CPU% по всем Pods Deployment-а, и подгоняет replicas: формула desiredReplicas = currentReplicas * (currentMetric / target).
- Resource metrics (CPU, memory) — через metrics-server.
- Custom metrics (app-level, например queue depth) — через
custom.metrics.k8s.ioAPI, который реализует Prometheus Adapter. - External metrics (SQS queue length, Pub/Sub) — через
external.metrics.k8s.io, для KEDA, Stackdriver-adapter.
Для CKAD достаточно знать: HPA существует, использует metrics-server, требует CPU/memory requests в Pod spec (без requests нельзя считать utilization%). Глубокая настройка HPA — CKA/SRE scope.
CKAD scope: что знать
kubectl top— must-know.- metrics-server как addon, понимать что без него
topне работает. - HPA на CPU — концептуально, что использует Metrics API.
- Prometheus / Grafana / kube-state-metrics — общие представления.
- Глубокая настройка, custom-metrics, alerting rules — CKA / SRE.
Killer-моменты
- metrics-server — отдельный addon. На kind / minikube / k3s нужно ставить руками. На managed K8s (EKS, GKE, AKS) обычно установлен по умолчанию.
- metrics-server показывает CURRENT значения, никакой истории. Для истории — Prometheus.
/metrics/resource— endpoint kubelet-а для metrics-server (Prometheus format, последние значения)./metrics/cadvisor— полный cAdvisor для Prometheus.- HPA на v2 API требует CPU
requestsв Pod spec — utilization считается как % от requests, без requests нет базы. kubectl top pod --containers— per-container, иначе агрегат Pod-а.kubectl topподдерживает только--sort-by=cpuилиmemory, не custom fields.