Skip to main content
Kubernetes·10 min read

kubectl get pods — Filtering, Debugging & Finding Why Pods Won't Start

Master kubectl get pods with real-world examples for filtering by label, namespace, and status. Learn custom columns, sorting, JSON output, and field selectors for production Kubernetes clusters.

DT

DevOps Engineer & Technical Writer

The Problem

You're on-call and an alert fires. You need to quickly identify which pods are failing across a cluster with 500+ pods spread across 30 namespaces. Running a bare kubectl get pods dumps everything in the current namespace with no useful filtering. You need precise queries that surface exactly what matters.

This guide covers every practical pattern for querying pods in production Kubernetes clusters — from basic listing to complex JSONPath expressions.

kubectl Request Flow kubectl CLI get pods -l app=x kubeconfig context cluster + user certificates API Server Authentication Authorization (RBAC) Admission Control kube-apiserver:6443 etcd cluster state Pod State / List returned to client

Basic Pod Listing

Start with the fundamentals and build up:

# List pods in the current namespace

kubectl get pods

# List pods in a specific namespace

kubectl get pods -n production

# List pods across ALL namespaces

kubectl get pods -A

# Wide output — shows node assignment, IP, and nominated node

kubectl get pods -o wide

# Watch pods in real-time (useful during deployments)

kubectl get pods -w

The -o wide flag is underrated. It shows which node each pod landed on, which is critical when you suspect a node-level issue.

Filtering by Label

Labels are the primary mechanism for organizing and querying pods. Master label selectors and you can find anything instantly.

# Pods with a specific label

kubectl get pods -l app=api-gateway

# Pods matching multiple labels (AND logic)

kubectl get pods -l app=api-gateway,environment=production

# Pods where a label exists (regardless of value)

kubectl get pods -l 'app'

# Pods where a label does NOT exist

kubectl get pods -l '!canary'

# Set-based selectors — label value in a set

kubectl get pods -l 'tier in (frontend, backend)'

# Set-based selectors — label value NOT in a set

kubectl get pods -l 'environment notin (dev, staging)'

# Combine equality and set-based selectors

kubectl get pods -l 'app=payment-service,version in (v2, v3)'

Production pattern: find all pods for a service across environments

# All pods belonging to the checkout service regardless of environment

kubectl get pods -A -l app.kubernetes.io/name=checkout-service

# All pods managed by a specific deployment

kubectl get pods -l app.kubernetes.io/managed-by=helm,app.kubernetes.io/instance=my-release

Filtering by Field Selectors

Field selectors filter on pod spec fields, not labels. The supported fields are limited but powerful.

# Pods on a specific node

kubectl get pods --field-selector spec.nodeName=ip-10-0-1-42.ec2.internal

# Pods in a specific phase

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

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

# Pods NOT running (find problems fast)

kubectl get pods -A --field-selector status.phase!=Running,status.phase!=Succeeded

# Combine field selectors

kubectl get pods --field-selector status.phase=Failed,spec.nodeName=worker-03

Find problematic pods across the entire cluster

# All pods that are not in Running or Completed state

kubectl get pods -A --field-selector 'status.phase!=Running,status.phase!=Succeeded'

# Pods stuck in Pending (scheduling issues)

kubectl get pods -A --field-selector status.phase=Pending

Output Formats

The default table output is fine for humans, but you often need structured data for scripting and automation.

JSON and YAML output

# Full JSON output

kubectl get pods -o json

# Full YAML output (more readable)

kubectl get pods -o yaml

# Single pod as JSON

kubectl get pod my-pod-abc123 -o json

# Extract a specific field with JSONPath

kubectl get pod my-pod-abc123 -o jsonpath='{.status.phase}'

# Get all pod names

kubectl get pods -o jsonpath='{.items[*].metadata.name}'

# Pod names with their status — one per line

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

Custom columns — build your own table

Custom columns let you define exactly what information you want in table format:

# Pod name, status, restarts, and node

kubectl get pods -o custom-columns=\

NAME:.metadata.name,\

STATUS:.status.phase,\

RESTARTS:.status.containerStatuses[0].restartCount,\

NODE:.spec.nodeName

# Pod name, image, and resource requests

kubectl get pods -o custom-columns=\

NAME:.metadata.name,\

IMAGE:.spec.containers[0].image,\

CPU_REQ:.spec.containers[0].resources.requests.cpu,\

MEM_REQ:.spec.containers[0].resources.requests.memory

# Pods with their IP addresses and host IPs

kubectl get pods -o custom-columns=\

NAME:.metadata.name,\

POD_IP:.status.podIP,\

HOST_IP:.status.hostIP,\

NODE:.spec.nodeName

go-template for complex formatting

# List pods with restart counts > 0

kubectl get pods -o go-template='{{range .items}}{{if gt (index .status.containerStatuses 0).restartCount 0}}{{.metadata.name}} — {{(index .status.containerStatuses 0).restartCount}} restarts{{"\n"}}{{end}}{{end}}'

Sorting Pods

Sort output by any field path:

# Sort by creation time (newest first)

kubectl get pods --sort-by=.metadata.creationTimestamp

# Sort by restart count (most restarts first)

kubectl get pods --sort-by='.status.containerStatuses[0].restartCount'

# Sort by node name (group by node)

kubectl get pods --sort-by=.spec.nodeName

# Combine sorting with custom columns for a restart report

kubectl get pods --sort-by='.status.containerStatuses[0].restartCount' \

-o custom-columns=\

NAME:.metadata.name,\

RESTARTS:.status.containerStatuses[0].restartCount,\

LAST_STATE:.status.containerStatuses[0].lastState.terminated.reason

Practical On-Call Patterns

Pattern 1: Triage cluster health

# Quick health check — how many pods are in each state?

kubectl get pods -A --no-headers | awk '{print $4}' | sort | uniq -c | sort -rn

# Find CrashLoopBackOff pods

kubectl get pods -A | grep CrashLoopBackOff

# Find pods with high restart counts

kubectl get pods -A --sort-by='.status.containerStatuses[0].restartCount' | tail -20

# Find ImagePullBackOff issues

kubectl get pods -A | grep -E "ImagePull|ErrImagePull"

Pattern 2: Deployment rollout investigation

# See pods for a deployment with their age

kubectl get pods -l app=my-service --sort-by=.metadata.creationTimestamp

# Compare old and new replicaset pods during rollout

kubectl get pods -l app=my-service -o custom-columns=\

NAME:.metadata.name,\

READY:.status.conditions[?(@.type=='Ready')].status,\

AGE:.metadata.creationTimestamp,\

IMAGE:.spec.containers[0].image

Pattern 3: Resource consumption overview

# Pods and their resource requests (requires metrics-server for actual usage)

kubectl top pods --sort-by=memory

kubectl top pods --sort-by=cpu

# Pods without resource limits (dangerous in production)

kubectl get pods -o json | jq '.items[] | select(.spec.containers[].resources.limits == null) | .metadata.name'

Pattern 4: Pod scheduling and node distribution

# Count pods per node

kubectl get pods -A -o custom-columns=NODE:.spec.nodeName --no-headers | sort | uniq -c | sort -rn

# Find unscheduled pods

kubectl get pods -A --field-selector spec.nodeName="" 2>/dev/null

kubectl get pods -A --field-selector status.phase=Pending

Scripting with kubectl get pods

Combine kubectl output with shell tools for powerful automation:

# Delete all Evicted pods across all namespaces

kubectl get pods -A --field-selector status.phase=Failed -o json | \

jq -r '.items[] | select(.status.reason=="Evicted") | "\(.metadata.namespace) \(.metadata.name)"' | \

while read ns name; do kubectl delete pod "$name" -n "$ns"; done

# Export pod list as CSV

kubectl get pods -A -o custom-columns=\

NAMESPACE:.metadata.namespace,\

NAME:.metadata.name,\

STATUS:.status.phase,\

NODE:.spec.nodeName,\

IP:.status.podIP \

--no-headers | tr -s ' ' ','

# Get container images for vulnerability scanning

kubectl get pods -A -o jsonpath='{range .items[]}{range .spec.containers[]}{.image}{"\n"}{end}{end}' | sort -u

Common Mistakes

  • Forgetting namespace scopekubectl get pods only shows the current namespace. Use -A to see everything or -n to target a specific namespace.
  • Confusing pod status with container status — A pod can be "Running" while a container inside is in CrashLoopBackOff. Check READY column (e.g., 0/1 means the container isn't ready).
  • Using grep instead of label selectorskubectl get pods | grep my-app is fragile. Use -l app=my-app for reliable filtering.
  • Ignoring the RESTARTS column — A pod showing "Running" with 847 restarts is not healthy. Sort by restart count regularly.
  • Not using --no-headers in scripts — When piping kubectl output to awk or other tools, the header row will pollute your results.
  • Over-relying on kubectl get vs kubectl describeget shows summary data. For events, conditions, and scheduling decisions, you need kubectl describe pod <name>.
  • Quick Reference

    TaskCommand
    All pods, all namespaces<code class="inline-code">kubectl get pods -A</code>
    Filter by label<code class="inline-code">kubectl get pods -l app=name</code>
    Filter by node<code class="inline-code">kubectl get pods --field-selector spec.nodeName=node1</code>
    Non-running pods<code class="inline-code">kubectl get pods -A --field-selector status.phase!=Running,status.phase!=Succeeded</code>
    Custom columns<code class="inline-code">kubectl get pods -o custom-columns=NAME:.metadata.name,STATUS:.status.phase</code>
    JSON specific field<code class="inline-code">kubectl get pod X -o jsonpath=&#39;{.status.phase}&#39;</code>
    Sort by restarts<code class="inline-code">kubectl get pods --sort-by=&#39;.status.containerStatuses[0].restartCount&#39;</code>
    Watch real-time<code class="inline-code">kubectl get pods -w</code>
    Pod count per node<code class="inline-code">kubectl get pods -A -o custom-columns=NODE:.spec.nodeName --no-headers \sort \uniq -c</code>
    Get all container images<code class="inline-code">kubectl get pods -A -o jsonpath=&#39;{..image}&#39; \tr &#39; &#39; &#39;\n&#39; \sort -u</code>

    Summary

    kubectl get pods is your first stop in any Kubernetes investigation. Master label selectors for filtering, custom columns for readable output, and JSONPath for scripting. The difference between a 5-minute and 30-minute incident response often comes down to knowing the right query to run.

    ---

    Frequently Asked Questions

    How do I list all pods in all namespaces?

    Use kubectl get pods --all-namespaces or the shorthand kubectl get pods -A. Add -o wide to include node names, IP addresses, and nominated nodes. For a specific namespace, use kubectl get pods -n <namespace-name>.

    How do I filter pods by label in kubectl?

    Use the -l flag with label selectors: kubectl get pods -l app=nginx for exact match, kubectl get pods -l 'environment in (production,staging)' for set-based selection, or kubectl get pods -l app=nginx,version=v2 for multiple labels. Use --show-labels to see all labels on each pod.

    How do I get more details about a specific pod?

    Use kubectl describe pod <pod-name> for a human-readable summary including events, conditions, and container status. Use kubectl get pod <pod-name> -o yaml for the full resource specification. For just the status, use kubectl get pod <pod-name> -o jsonpath='{.status.phase}'.

    What does pod status "Pending" mean?

    Pending means Kubernetes accepted the pod but one or more containers cannot start yet. Common causes are: insufficient cluster resources (CPU/memory), no node matching nodeSelector or affinity rules, PersistentVolumeClaim not bound, or image pull taking longer than expected. Run kubectl describe pod and check the Events section for the specific reason.

    How do I watch pods in real-time?

    Use kubectl get pods --watch or kubectl get pods -w to stream status changes as they happen. For a more visual experience, use tools like k9s or watch -n 1 kubectl get pods. Combine with grep for specific pods: kubectl get pods -w | grep my-app.

    ---