Skip to content

Filtering & Querying Pods — Full Reference

Reference: https://kubernetes.io/docs/reference/kubectl/jsonpath/


What the Raw Notes Were

kubectl get pod nginx-pod -o=jsonpath='{.metadata.labels.application}'

This extracts a single label value from a pod. Let's break it down fully, then expand to everything you'd need for filtering/querying pods in the exam.


The Command — Full Breakdown

kubectl get pod nginx-pod -o=jsonpath='{.metadata.labels.application}'
Part What it does
kubectl get pod nginx-pod Fetch the pod object named nginx-pod
-o=jsonpath= Output format: jsonpath — lets you extract specific fields from the JSON response
'{.metadata.labels.application}' The path to navigate: root → metadata → labels → application key

Why jsonpath? kubectl get pod nginx-pod returns a table. -o yaml returns everything. jsonpath returns exactly one value — no parsing, no grep, just the value you need.


jsonpath Syntax — From Scratch

The Kubernetes API returns every resource as a JSON object. jsonpath is a query language to extract specific fields from that object.

The dot notation follows the JSON structure:

Pod JSON structure:
{
  "metadata": {
    "name": "nginx-pod",
    "labels": {
      "application": "nginx",
      "env": "prod"
    }
  },
  "spec": {
    "containers": [
      { "name": "nginx", "image": "nginx:1.25" }
    ]
  },
  "status": {
    "podIP": "10.244.1.5",
    "phase": "Running"
  }
}

To get metadata.labels.application:

kubectl get pod nginx-pod -o jsonpath='{.metadata.labels.application}'
# output: nginx

To get the pod IP:

kubectl get pod nginx-pod -o jsonpath='{.status.podIP}'

To get the first container's image:

kubectl get pod nginx-pod -o jsonpath='{.spec.containers[0].image}'
# [0] = first element of the array (zero-indexed)


Labels — Get, Filter, Select

Read a label value

kubectl get pod nginx-pod -o jsonpath='{.metadata.labels.application}'
kubectl get pod nginx-pod -o jsonpath='{.metadata.labels.env}'

List all labels on a pod

kubectl get pod nginx-pod --show-labels
kubectl get pod nginx-pod -o jsonpath='{.metadata.labels}'

Filter pods BY label — the selector flag

kubectl get pods -l app=nginx                     # pods where label app=nginx
kubectl get pods -l app=nginx,env=prod            # multiple labels (AND)
kubectl get pods -l 'env in (prod,staging)'       # env is prod OR staging
kubectl get pods -l 'env notin (dev)'             # env is NOT dev
kubectl get pods -l '!deprecated'                 # label 'deprecated' does not exist

-l is short for --selector. This is how Services and Deployments find their pods — they use the same label selector mechanism.

Add / update a label on a running pod

kubectl label pod nginx-pod version=v2            # add label
kubectl label pod nginx-pod version=v3 --overwrite  # update existing label
kubectl label pod nginx-pod version-              # remove label (trailing dash)

Annotations — Same Pattern, Different Purpose

Labels = used for selection (Services, Deployments use them to find pods). Annotations = metadata for tooling/humans — not used for selection.

kubectl get pod nginx-pod -o jsonpath='{.metadata.annotations}'
kubectl annotate pod nginx-pod description="this is the main app pod"
kubectl annotate pod nginx-pod description="updated" --overwrite
kubectl annotate pod nginx-pod description-        # remove annotation

jsonpath — Arrays and Multiple Values

Get all container names in a pod

kubectl get pod nginx-pod -o jsonpath='{.spec.containers[*].name}'
# [*] = all elements

Get all container images

kubectl get pod nginx-pod -o jsonpath='{.spec.containers[*].image}'

Loop with range — newline between each value

kubectl get pod nginx-pod -o jsonpath='{range .spec.containers[*]}{.name}{"\n"}{end}'

Without range...end, multiple values are printed with a space separator and no newline — hard to read. range iterates and you control the formatting.

Get name + image pairs

kubectl get pod nginx-pod -o jsonpath='{range .spec.containers[*]}{.name}{"\t"}{.image}{"\n"}{end}'

Output:

nginx    nginx:1.25
sidecar  busybox:latest

Across all pods — no pod name needed

kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.phase}{"\n"}{end}'

.items[*] = all items in the list response. This iterates every pod.


-o wide, -o yaml, -o json — When to Use Which

kubectl get pods                          # table — human readable
kubectl get pods -o wide                  # table + node, IP, nominated node
kubectl get pod nginx-pod -o yaml         # full spec — everything, verbose
kubectl get pod nginx-pod -o json         # same as yaml but JSON format
kubectl get pod nginx-pod -o jsonpath=... # surgical extraction of one value
kubectl get pod nginx-pod -o name         # just "pod/nginx-pod" — useful in scripts

For exam tasks that say "write the pod IP to a file":

kubectl get pod nginx-pod -o jsonpath='{.status.podIP}' > /tmp/pod-ip.txt


Field Selectors — Filter on Any Field

Different from label selectors — field selectors filter on the actual resource fields:

kubectl get pods --field-selector status.phase=Running
kubectl get pods --field-selector spec.nodeName=node01
kubectl get pods --field-selector metadata.namespace=default
kubectl get pods --field-selector status.phase!=Running       # NOT running

Combine:

kubectl get pods --field-selector status.phase=Running,spec.nodeName=node01


Common Exam Patterns

"Get the label value X from pod Y":

kubectl get pod nginx-pod -o jsonpath='{.metadata.labels.<label-name>}'

"List all pods on node X":

kubectl get pods --field-selector spec.nodeName=node01
kubectl get pods -o wide | grep node01          # alternative

"List all Running pods":

kubectl get pods --field-selector status.phase=Running

"Get pod IP":

kubectl get pod nginx-pod -o jsonpath='{.status.podIP}'

"Get pod's service account":

kubectl get pod nginx-pod -o jsonpath='{.spec.serviceAccountName}'

"List all pod names and their nodes":

kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.nodeName}{"\n"}{end}'

"Get the image of the first container":

kubectl get pod nginx-pod -o jsonpath='{.spec.containers[0].image}'


Quick Reference

# Label operations
kubectl get pods -l app=nginx
kubectl get pods --show-labels
kubectl get pod <pod> -o jsonpath='{.metadata.labels}'
kubectl get pod <pod> -o jsonpath='{.metadata.labels.<key>}'
kubectl label pod <pod> key=value
kubectl label pod <pod> key=value --overwrite
kubectl label pod <pod> key-                          # remove

# jsonpath extractions
kubectl get pod <pod> -o jsonpath='{.status.podIP}'
kubectl get pod <pod> -o jsonpath='{.spec.nodeName}'
kubectl get pod <pod> -o jsonpath='{.spec.containers[0].image}'
kubectl get pod <pod> -o jsonpath='{.spec.containers[*].name}'
kubectl get pod <pod> -o jsonpath='{.metadata.labels.<key>}'

# Field selectors
kubectl get pods --field-selector status.phase=Running
kubectl get pods --field-selector spec.nodeName=node01

# Multi-pod jsonpath
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.phase}{"\n"}{end}'