Asterrr's Handbook

Resource usage

Measuring what nodes, Pods and containers actually consume with metrics-server and kubectl top, telling usage apart from requests, and using events to explain evictions and pressure.

Exam tasks: 5.3 (monitor cluster and application resource usage)

The decision: do you need live usage (kubectl top, from metrics-server), reserved capacity (requests and limits in describe node), or history of what happened (events)?

Three different numbers

QuestionCommandSource
What is this Pod using right now?k top pod, k top pod --containersmetrics-server, scraped from each kubelet
How full is this node, really?k top nodemetrics-server
How much has been promised on this node?k describe node → Allocated resourcesSum of Pod requests and limits in the API
Why was a Pod evicted, OOM-killed or not scheduled?k events, k describeEvent objects
Long-term trends, dashboards, alertsNot kubectlPrometheus or another monitoring stack
  • metrics-server keeps only the latest sample in memory. It is not a monitoring system and has no history.
  • kubectl top memory is the working set, the number the kubelet uses for eviction decisions. It's not the same as what free shows on the node.
  • CPU is shown in millicores (250m is a quarter of a core); memory in Mi.

describe node is not usage

Allocated resources in k describe node adds up requests. A node can show 95% CPU requests while k top node shows 10% actual use, or the reverse if Pods run without requests. A task that asks "which Pod uses the most" wants kubectl top, not the requests table.

kubectl top

k top node                                       # every node: CPU(cores) CPU% MEMORY(bytes) MEMORY%
k top pod -n checkout                            # Pods in one namespace
k top pod -A --sort-by=memory                    # whole cluster, biggest first
k top pod -l tier=batch -A --sort-by=cpu --no-headers | head -1
k top pod relay-7f9 -n checkout --containers     # per container inside one Pod

Exam signal

"Write the name of the Pod using the most CPU among Pods labelled x=y to /opt/answers/top.txt" is a classic. Use --sort-by=cpu --no-headers and take the first line. With -A, the first column is the namespace and the second is the Pod name, so awk '{print $2}'; without -A it's $1. Write only what was asked.

When kubectl top doesn't work

ErrorFix
error: Metrics API not availablemetrics-server isn't installed or isn't ready. Check k get apiservice v1beta1.metrics.k8s.io and k -n kube-system get deploy metrics-server
APIService Available=False, "FailedDiscoveryCheck"The metrics-server Pod isn't running or the API server can't reach it. Check its logs
metrics-server logs "x509: cannot validate certificate … doesn't contain any IP SANs"Kubelet serving certs are self-signed. In a lab, add --kubelet-insecure-tls to its args; in production, sign kubelet serving certs
metrics not available yet for a new PodWait for the next scrape (default resolution 15s)
# install the current release
k apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
# lab-only: trust kubelets' self-signed serving certs
k -n kube-system patch deploy metrics-server --type=json \
  -p='[{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"--kubelet-insecure-tls"}]'
k get --raw /apis/metrics.k8s.io/v1beta1/nodes | head -c 300   # raw API check

Events: what happened and why

Events record scheduling failures, image pulls, probe failures, OOM kills, evictions and node pressure.

k events -n checkout                              # sorted oldest to newest
k events -n checkout --types=Warning              # only problems
k events -n checkout --for pod/relay-7f9          # one object
k events -A --watch                               # live stream
k get events -n checkout --field-selector type=Warning,reason=Evicted
k get events -A --sort-by=.metadata.creationTimestamp
  • The API server keeps events for 1 hour by default (--event-ttl). An incident from yesterday won't show.
  • Evicted with "The node was low on resource: memory" points to node MemoryPressure. Look at the node's conditions and the top memory consumers on it.
  • OOMKilled is a container hitting its own memory limit, not the node running out. See Troubleshooting applications.
15s
metrics-server default scrape resolution.
1h
Default event retention (kube-apiserver --event-ttl).
metrics.k8s.io
API group served by metrics-server through the aggregation layer, used by kubectl top and the HPA.
working set
The memory figure kubectl top shows and the kubelet evicts on.

Finding the noisy Pod on a node

k top node                                                  # which node is hot
k get pods -A -o wide --field-selector spec.nodeName=worker-4
k top pod -A --sort-by=memory | head                        # then match names to that node
k describe node worker-4 | grep -A6 Conditions              # pressure flags

For QoS and eviction order (BestEffort before Burstable before Guaranteed), see Resources and quotas.

Scenarios

Scenario
A task asks for the Pod in namespace telemetry that currently uses the most memory. `k describe node` shows that Pod collector-0 has the largest memory request. `k top pod -n telemetry --sort-by=memory` lists ingest-5d8 first. What should you write as the answer?
Scenario
`k top nodes` returns 'error: Metrics API not available'. `k get apiservice v1beta1.metrics.k8s.io` shows Available=False, and the metrics-server Pod logs repeat 'x509: cannot validate certificate for 10.0.4.12 because it doesn't contain any IP SANs'. This is a practice cluster. What is the quickest fix?

Drill

kubectl config use-context lab-metrics. Among all Pods in all namespaces with label team=fulcrum, find the one using the most CPU and write only its name to /opt/drill/cpu-hog.txt.

Further reading

On this page