Guide · Kubernetes · about 5 minutes

Kubernetes cheatsheet: kubectl by task

Every kubectl command from the Kubernetes track, grouped by the job you're trying to do, with what a stuck pod's status means, how health checks work, and where to look first. Each row links to the lesson that explains it.

Last checked October 2026

How to use this page

Find the job you're trying to do, and copy the command. Words in capitals, like NAME or FILE, are yours to replace. Every row links to the lesson that explains it, if you want the why as well as the how. Use the print button at the top to keep a copy next to you.

Two habits that make every command here easier:

  • Most commands work on the current namespace. Add -n NAMESPACE to choose another, or -A for all of them.
  • Ask before you change. kubectl get, describe and logs only read. apply, delete, patch and rollout change things.

When a pod won't start

Start here when something's wrong. The STATUS column of kubectl get pods usually tells you where to look.

StatusUsually meansLook firstLesson
PendingNo node can take it yet: not enough room, a taint, or storage that isn't readykubectl describe pod NAME, the Events at the bottom9, 11
ContainerCreatingDownloading the image or attaching storage. Fine briefly; a problem if it stayskubectl describe pod NAME3
ErrImagePull, ImagePullBackOffThe image name or tag is wrong, or the image is privatekubectl describe pod NAME, then check the image name3
CrashLoopBackOffThe container starts, exits, and is restarted, over and overkubectl logs NAME --previous3
OOMKilledIt used more memory than its limit, and was stoppedkubectl describe pod NAME, under Last State9
CreateContainerConfigErrorA ConfigMap or Secret it needs, or a key inside one, doesn't existkubectl describe pod NAME, then check the names7
Running, but READY 0/1It's running, but its readiness check is failing, so it gets no traffickubectl get events --field-selector reason=Unhealthy6
Running, and RESTARTS keeps climbingIts liveness check is failing, so Kubernetes keeps restarting it. Often the app is fine and the check is wrongkubectl get events --field-selector reason=Unhealthy6

Seeing what's there

ToRunLesson
List podskubectl get pods3
Which node each pod is on, and its addresskubectl get pods -o wide2
Watch pods change, livekubectl get pods --watch3
Several kinds at oncekubectl get deployments,replicasets,pods5
Everything, in every namespacekubectl get deployments -A10
Show labelskubectl get pods --show-labels8
Only pods with a labelkubectl get pods -l app=NAME8
The full details, as YAMLkubectl get pod NAME -o yaml4
Details and recent events, readablekubectl describe pod NAME3
Recent events of one kindkubectl get events --field-selector reason=Failed7
The nodeskubectl get nodes2
What a node has room forkubectl describe node NAME9
Memory and CPU in use (needs metrics-server)kubectl top pods, kubectl top node9
What a field in a YAML file meanskubectl explain deployment.spec.replicas4

Inside a running pod

ToRunLesson
Its logskubectl logs NAME3
Logs from before the last crashkubectl logs NAME --previous3
Run one command inside itkubectl exec NAME -- COMMAND3
The same, on any pod of a Deploymentkubectl exec deploy/NAME -- env7
Reach it from your laptopkubectl port-forward pod/NAME 8080:803
Reach a Service from your laptopkubectl port-forward service/NAME 8080:808
Test a Service from inside the clusterkubectl run tmp --rm -it --image=busybox:1.36 --restart=Never -- wget -qO- http://NAME8
Check a Service's DNS namekubectl run tmp --rm -it --image=busybox:1.36 --restart=Never -- nslookup NAME.NAMESPACE.svc.cluster.local8

Creating and changing things

ToRunLesson
Create or update from a filekubectl apply -f FILE.yaml3
Check a file against the cluster, without changing anythingkubectl apply -f FILE.yaml --dry-run=server4
Write the YAML for you, without creating anythingkubectl create deployment NAME --image=nginx:1.27 --replicas=2 --dry-run=client -o yaml > deploy.yaml4
Create a Deploymentkubectl create deployment NAME --image=IMAGE --replicas=32
Run a single podkubectl run NAME --image=IMAGE3
Give a Deployment a Servicekubectl expose deployment NAME --port=80 --target-port=567812
Set an environment variablekubectl set env deployment/NAME KEY="value"12
Change one field in placekubectl patch configmap NAME -p '{"data":{"KEY":"value"}}'7
Label a nodekubectl label node NAME disk=ssd2
Keep ordinary pods off a nodekubectl taint nodes NAME dedicated=gpu:NoSchedule9
Wait until something is readykubectl wait --for=condition=Available deployment/NAME --timeout=5m12
Delete a pod (a Deployment replaces it)kubectl delete pod NAME2
Delete everything with a labelkubectl delete pod -l app=NAME11

Rolling out a change

ToRunLesson
Watch an update finishkubectl rollout status deployment/NAME5
Go back to the previous versionkubectl rollout undo deployment/NAME5
See past versionskubectl rollout history deployment/NAME5
Restart every pod, one at a timekubectl rollout restart deployment/NAME7

Health checks (probes)

A probe is a check Kubernetes runs on a container, on a schedule. There are three, and each one does something different when it fails.

ProbeAsksWhen it failsUse it for
readinessProbeCan you take requests right now?The pod gets no traffic, but keeps running. Nothing restartsAlmost every app that serves requests
livenessProbeAre you still working at all?The container is restartedApps that can freeze without exiting
startupProbeHave you finished starting?The other two wait until it passes. If it never passes, the container is restartedApps that take a long time to start

A probe asks in one of three ways: httpGet sends an HTTP request (any 200 to 399 reply passes), tcpSocket checks that a port accepts connections, and exec runs a command inside the container (exit code 0 passes). This goes under a container in a Deployment:

YAML
readinessProbe:
  httpGet:
    path: /ready
    port: 8080
  periodSeconds: 5
livenessProbe:
  httpGet:
    path: /alive
    port: 8080
  periodSeconds: 10
  failureThreshold: 3
startupProbe:
  httpGet:
    path: /alive
    port: 8080
  periodSeconds: 10
  failureThreshold: 30

That startup probe gives the app up to 5 minutes to start (30 checks, 10 seconds apart) before the liveness probe takes over.

SettingMeansDefault
periodSecondsHow often to check10
failureThresholdFailures in a row before acting3
timeoutSecondsHow long to wait for a reply before it counts as a failure1
initialDelaySecondsHow long to wait after the container starts before the first check. A startup probe is usually the better choice0
ToRunLesson
See failed probes, and whykubectl get events --field-selector reason=Unhealthy6
See a pod's probes and their settingskubectl describe pod NAME, the Liveness: and Readiness: lines6
Watch readiness and restarts changekubectl get pods -w, the READY and RESTARTS columns6
Hit the probe's path yourselfkubectl port-forward pod/NAME 8080:8080, then curl -i localhost:8080/PATH3
Look up every probe fieldkubectl explain pod.spec.containers.livenessProbe4
Undo a release whose probe is wrongkubectl rollout undo deployment/NAME6

Two rules that prevent most probe trouble:

  • Liveness checks only the app itself. Never make it depend on a database or another service. If it does, one database outage makes Kubernetes restart every healthy pod. Put those checks in readiness instead.
  • Not sure an app needs a liveness probe? Leave it out. Kubernetes already restarts containers that exit. A wrong liveness probe turns a healthy app into a crashing one.

Settings and Secrets

ToRunLesson
Create a ConfigMapkubectl create configmap NAME --from-literal=KEY="value"7
Type a secret without it showing or being saved in historyread -s API_KEY7
Create a Secret from it, then forget itkubectl create secret generic NAME --from-literal=API_KEY="$API_KEY", then unset API_KEY7
Read one value from a Secretkubectl get secret NAME -o jsonpath='{.data.API_KEY}' | base64 -d7
See a pod's environmentkubectl exec deploy/NAME -- env7

Secrets are encoded, not encrypted: anyone who can read them can decode them, as the base64 -d row shows. Protect them with access control.

Namespaces and who can do what

ToRunLesson
List namespaceskubectl get namespaces10
Create onekubectl create namespace NAME10
Work in one by defaultkubectl config set-context --current --namespace=NAME10
Create a ServiceAccountkubectl create serviceaccount NAME -n NAMESPACE10
Check what an account is allowed to dokubectl auth can-i list pods -n NAMESPACE --as=system:serviceaccount:NAMESPACE:NAME10
Check what you're allowed to dokubectl auth can-i delete pods10

Storage

ToRunLesson
Which kinds of storage the cluster offerskubectl get storageclass11
Claims, and whether they're boundkubectl get pvc11
The volumes behind themkubectl get pv11
Why a claim is stuckkubectl describe pvc NAME11

Getting traffic in

ToRunLesson
A Service's address and portskubectl get service NAME8
Which pods a Service sends traffic tokubectl describe service NAME, under Endpoints8
List routeskubectl get httproute12
Why a route isn't workingkubectl describe httproute NAME, under Conditions12
Test a route that matches on host namecurl -H "Host: www.example.com" http://localhost:8080/12

Your cluster and context

ToRunLesson
Which cluster kubectl is talking tokubectl config current-context2
Where that cluster iskubectl cluster-info2
The kubectl versionkubectl version --client2
Make a practice clusterkind create cluster --name learn2
Delete itkind delete cluster --name learn2

Check the context before anything that changes things. kubectl changes whichever cluster it's pointed at. One kubectl config current-context before an apply or delete is the cheapest habit in Kubernetes.