Stop piping kubectl output to grep, awk, and sed. JSONPath can get you exactly what you need in one command.
the basic pattern
bash
kubectl get <resource> -o jsonpath='{<jsonpath-expression>}'simple examples
get pod IPs
Instead of:
bash
kubectl get pods -o wide | awk '{print $6}'Do:
bash
kubectl get pods -o jsonpath='{.items[*].status.podIP}'get pod names only
bash
kubectl get pods -o jsonpath='{.items[*].metadata.name}'get pod name + IP
bash
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.podIP}{"\n"}{end}'Output:
bash
nginx-abc123 10.244.1.5
redis-xyz789 10.244.1.6real-world use cases
1. find all container images
bash
kubectl get pods -o jsonpath='{.items[*].spec.containers[*].image}' | tr ' ' '\n' | sort -u2. get pods not running
bash
kubectl get pods -o jsonpath='{range .items[?(@.status.phase!="Running")]}{.metadata.name}{"\t"}{.status.phase}{"\n"}{end}'3. find pods using most memory
bash
kubectl top pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.usage.memory}{"\n"}{end}' | sort -k2 -h4. get all node capacities
bash
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.capacity.cpu}{" CPU\t"}{.status.capacity.memory}{" RAM\n"}{end}'5. find secrets in a namespace
bash
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.volumes[?(@.secret)].secret.secretName}{"\n"}{end}'6. get all services and their type
bash
kubectl get svc -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.type}{"\n"}{end}'JSONPath syntax cheat sheet
| Pattern | Description | Example |
|---|---|---|
.items[*] | All items | Get all pods |
.items[0] | First item | Get first pod |
.items[0:3] | First 3 items | Get first 3 pods |
.items[-1] | Last item | Get last pod |
.items[?(@.field=="value")] | Filter | Pods where phase=Running |
{range .items[*]}...{end} | Loop | Iterate over items |
{"\n"} | Newline | Format output |
{"\t"} | Tab | Format output |
advanced filtering
pods with specific label
bash
kubectl get pods -l app=nginx -o jsonpath='{.items[*].metadata.name}'pods in Running state
bash
kubectl get pods -o jsonpath='{.items[?(@.status.phase=="Running")].metadata.name}'containers in Waiting state
bash
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.containerStatuses[?(@.state.waiting)].name}{"\n"}{end}'pods with restart count > 0
bash
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.containerStatuses[0].restartCount}{"\n"}{end}' | awk '$2 > 0'useful aliases
Add to your ~/.bashrc or ~/.zshrc:
bash
# Get pod IPs
alias kip='kubectl get pods -o jsonpath='\''{range .items[*]}{.metadata.name}{"\t"}{.status.podIP}{"\n"}{end}'\'''
# Get images
alias kimages='kubectl get pods -o jsonpath='\''{.items[*].spec.containers[*].image}'\'' | tr " " "\n" | sort -u'
# Get pod with most restarts
alias krestart='kubectl get pods -o jsonpath='\''{range .items[*]}{.metadata.name}{"\t"}{.status.containerStatuses[0].restartCount}{"\n"}{end}'\'' | sort -k2 -n -r | head -1'
# Get not ready pods
alias knotready='kubectl get pods -o jsonpath='\''{range .items[?(@.status.phase!="Running")]}{.metadata.name}{"\t"}{.status.phase}{"\n"}{end}'\'''custom columns (even better)
Sometimes custom columns are cleaner than JSONPath:
bash
# Pod name, phase, and IP
kubectl get pods -o custom-columns=NAME:.metadata.name,PHASE:.status.phase,IP:.status.podIP
# Node name, CPU, and memory
kubectl get nodes -o custom-columns=NAME:.metadata.name,CPU:.status.capacity.cpu,MEMORY:.status.capacity.memory
# Services and their ClusterIP
kubectl get svc -o custom-columns=NAME:.metadata.name,TYPE:.spec.type,CLUSTER-IP:.spec.clusterIPcommon patterns I use daily
1. quick debug — get all pod info
bash
kubectl get pod nginx-abc123 -o jsonpath='{range .spec.containers[*]}Name: {.name}{"\n"}Image: {.image}{"\n"}Ports: {.ports[*].containerPort}{"\n\n"}{end}'2. get all environment variables
bash
kubectl get pod nginx-abc123 -o jsonpath='{range .spec.containers[*].env[*]}{.name}={.value}{"\n"}{end}'3. find pods on a specific node
bash
kubectl get pods --all-namespaces -o jsonpath='{range .items[?(@.spec.nodeName=="node-1")]}{.metadata.name}{"\t"}{.metadata.namespace}{"\n"}{end}'4. get ConfigMaps used by pods
bash
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.volumes[?(@.configMap)].configMap.name}{"\n"}{end}'5. network policies applied to pods
bash
kubectl get netpol -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.podSelector.matchLabels}{"\n"}{end}'the live-updates move
Combine JSONPath with watch for live updates:
bash
watch -n 2 'kubectl get pods -o jsonpath='\''{range .items[*]}{.metadata.name}{"\t"}{.status.phase}{"\n"}{end}'\'''debugging JSONPath
If your JSONPath isn't working, test it step by step:
bash
# Get full JSON first
kubectl get pod nginx-abc123 -o json | jq '.'
# Then build your JSONPath incrementally
kubectl get pod nginx-abc123 -o jsonpath='{.metadata}'
kubectl get pod nginx-abc123 -o jsonpath='{.metadata.name}'
kubectl get pod nginx-abc123 -o jsonpath='{.status}'
kubectl get pod nginx-abc123 -o jsonpath='{.status.phase}'the gotcha
JSONPath in kubectl has some quirks:
- Filters must use
@:.items[?(@.field=="value")]not.items[?(.field=="value")] - *Arrays need `[]`*: `.items[]
not.items[]` - Quotes matter: use single quotes outside, double inside:
'{.items[?(@.name=="value")]}'