kubectl top — Node Resource Usage & Shell Scripting¶
Reference: https://kubernetes.io/docs/reference/kubectl/cheatsheet/
The Task¶
Find the node consuming the most memory in the cluster. Store the result in high_memory_node.txt in the format: current_context,node_name
What kubectl top Does¶
kubectl top shows real-time CPU and memory usage for nodes or pods. It's the Kubernetes equivalent of top or htop on Linux — except it queries the Metrics Server (an in-cluster component) rather than reading from the OS directly.
Output:
NAME CPU(cores) CPU(%) MEMORY(bytes) MEMORY(%)
controlplane 105m 10% 1292Mi 60%
node01 50m 5% 792Mi 43%
Column meanings:
| Column | What it shows |
|---|---|
NAME |
Node name |
CPU(cores) |
CPU usage in millicores. 105m = 105 millicores = 0.105 of a CPU core |
CPU(%) |
CPU usage as a percentage of the node's total CPU |
MEMORY(bytes) |
RAM in use, shown in Mi (mebibytes) |
MEMORY(%) |
RAM as a percentage of the node's total RAM |
Millicores explained: CPU is measured in millicores where 1000m = 1 core. So 105m = about 10% of one CPU core. This unit exists because containers often use fractions of a core and you need a precise way to express that.
Requires Metrics Server: kubectl top will fail with error: Metrics API not available if the Metrics Server isn't installed. In KillerCoda and CKA exam environments it's pre-installed.
What NOT to Do¶
context is not a Kubernetes resource — it's a local kubeconfig concept. The API server knows nothing about it. The correct command is:
kubectl config get-contexts # list all contexts
kubectl config current-context # show the active context name
kubectl config subcommands operate on ~/.kube/config locally. They never hit the API server.
Manual vs One-liner Approach¶
What was done manually:
kubectl top node
# visually identify highest memory node
echo "kubernetes-admin@kubernetes,controleplane" > high_memory_node.txt
# then manually fix the typo in vim
Problems: manual reading is error-prone (typo: controleplane), requires two steps, doesn't scale if you have 50 nodes.
The correct one-liner:
echo "$(kubectl config current-context),$(kubectl top node --sort-by=memory --no-headers | head -1 | awk '{print $1}')" > high_memory_node.txt
Full Breakdown — Every Part¶
Outer Structure¶
echo prints a string. "..." is the string. > redirects output to the file. The string contains two command substitutions joined by a comma.
$(...) — Command Substitution¶
$(command) runs command in a subshell and substitutes its output inline. So "$(cmd1),$(cmd2)" becomes "output1,output2".
This is different from backticks `command` which do the same thing but are harder to nest and read. Always prefer $(...).
Part 1: $(kubectl config current-context)¶
| Part | What it does |
|---|---|
kubectl config |
Operate on the kubeconfig file |
current-context |
Print the name of the currently active context |
Output: kubernetes-admin@kubernetes
No flags needed. Returns a single clean string — perfect for embedding in a command substitution.
Part 2: $(kubectl top node --sort-by=memory --no-headers | head -1 | awk '{print $1}')¶
Breaking this pipeline stage by stage:
Stage 1:
| Flag | What it does |
|---|---|
--sort-by=memory |
Sort the output by memory usage, highest first. Also accepts cpu |
--no-headers |
Suppress the column header row. Without this, head -1 would grab the header, not the first data row |
Output (no headers, sorted by memory descending):
Stage 2:
head -1 takes only the first line. Since the output is sorted by memory descending, the first line = the node with the most memory. Output: controlplane 108m 10% 1292Mi 60%
Stage 3:
awk processes text column by column. $1 means the first whitespace-separated field. The first field of controlplane 108m 10% 1292Mi 60% is controlplane. Output: controlplane
awk vs cut vs grep for field extraction:
| Tool | Use case |
|---|---|
awk '{print $1}' |
Extract by column position (whitespace-separated). Most flexible |
cut -f1 -d' ' |
Cut by delimiter — needs exact delimiter, fragile with multiple spaces |
grep |
Pattern matching — not for field extraction |
awk is the right tool here because kubectl top output uses variable-width spaces between columns.
Final Assembly¶
echo "$(kubectl config current-context),$(kubectl top node --sort-by=memory --no-headers | head -1 | awk '{print $1}')" > high_memory_node.txt
Expands to:
Result in high_memory_node.txt:
Verify the Output¶
Check: correct context name, no typos, no trailing newline issues, comma-separated exactly as required.
kubectl top for Pods¶
The same tool works for pods:
kubectl top pod
kubectl top pod -n kube-system
kubectl top pod --sort-by=memory
kubectl top pod --sort-by=cpu
kubectl top pod -A --sort-by=memory # across all namespaces
Find the pod consuming the most CPU across the cluster:
Find and save in one shot:
kubectl top pod -A --sort-by=cpu --no-headers | head -1 | awk '{print $1"/"$2}'
# output: namespace/podname
Shell Pipeline Reference¶
These tools appear constantly in CKA exam one-liners:
| Tool | What it does | Example |
|---|---|---|
head -N |
Take first N lines | head -1 = first line only |
tail -N |
Take last N lines | tail -1 = last line only |
awk '{print $N}' |
Print Nth whitespace-separated field | awk '{print $1}' = first column |
cut -dX -fN |
Cut by delimiter X, take field N | cut -d',' -f2 = 2nd CSV field |
sort -k N |
Sort by column N | sort -k4 -n = sort by 4th field numerically |
grep pattern |
Filter lines matching pattern | grep Running |
grep -v pattern |
Exclude lines matching pattern | grep -v Completed |
wc -l |
Count lines | kubectl get pods \| wc -l |
tr |
Translate/delete characters | tr ',' '\n' = comma to newline |
$(...) |
Command substitution | Embed command output in a string |