kubectl Cheatsheet - Pods, Deploy, Logs & Apply Commands
A kubectl command reference for app developers and cluster operators, covering resource queries, Pod diagnosis, replica scaling, and cluster context management. Unlike reading YAML directly, kubectl is the consistent window into cluster state and change control, letting you quickly localize frequent incidents such as CrashLoopBackOff, Pods stuck in Pending, and failed rollouts. By the end you can run the whole loop yourself: inspect status → check events → read logs → recover or roll back.
Typical Use Case
For Kubernetes ops and delivery: inspect resource status, scale and roll out updates, and troubleshoot Pods stuck in Pending / CrashLoopBackOff / ImagePullBackOff, plus reading logs and events to find root causes.
Get Resources 5
kubectl get pods -n prodkubectl get pods -o widekubectl get pods -Akubectl get svc,ingress -n prodkubectl get events --sort-by=.lastTimestampDescribe & Diagnose 5
kubectl describe pod <pod> -n prodkubectl logs <pod> -n prodkubectl logs <pod> --previouskubectl logs <pod> -c <container>kubectl exec -it <pod> -- shScale & Rollout 5
kubectl scale deploy/app --replicas=3kubectl rollout status deploy/appkubectl rollout undo deploy/appkubectl set image deploy/app c=app:1.1kubectl delete pod <pod>Context & Configuration 4
kubectl config get-contextskubectl config use-context <ctx>kubectl config set-context --current --namespace=prodkubectl top pod -n prodFAQ 5
Q: How do I list pods across all namespaces?Q: What is the difference between kubectl apply and kubectl create?Q: How do I view a pod log?Q: How do I shell into a pod container?Q: How do I check cluster node status?Debugging & Output Formatting (REQ-02 add-on) 22
kubectl get pods --field-selector=status.phase=Runningkubectl get nodes --selector='!node-role.kubernetes.io/control-plane'kubectl get pods --show-labelskubectl get services --sort-by=.metadata.namekubectl get pods --sort-by='.status.containerStatuses[0].restartCount'kubectl get pv --sort-by=.spec.capacity.storagekubectl get nodes -o jsonpath={.items[*].status.addresses[?(@.type=="ExternalIP")].address}kubectl get secret my-secret -o go-template={{range $k,$v := .data}}{{$k}}:{{$v|base64decode}}{{end}}kubectl get pods -A -o=custom-columns='DATA:spec.containers[*].image'kubectl get node -o custom-columns='NODE_NAME:.metadata.name,STATUS:.status.conditions[?(@.type=="Ready")].status'kubectl diff -f ./my-manifest.yamlkubectl patch node k8s-node-1 -p {"spec":{"unschedulable":true}}kubectl patch deployment web --subresource=scale --type=merge -p {"spec":{"replicas":2}}kubectl replace --force -f ./pod.jsonkubectl expose deployment web --port=80 --target-port=8000kubectl logs -f -l name=myLabel --all-containerskubectl logs my-pod --previouskubectl debug my-pod -it --image=busybox:1.28kubectl debug node/my-node -it --image=busybox:1.28kubectl cluster-info dump --output-directory=/path/to/cluster-statekubectl api-resources --verbs=list,getkubectl run nginx --image=nginx --dry-run=client -o yaml > pod.yamlParameter matrix
| Parameter | Effect | Example |
|---|---|---|
-n | Target a namespace so you never touch the default one by accident. | kubectl -n prod get pods |
-o | Choose the output format: yaml, json, wide or name. | kubectl get pod web -o yaml |
--kubeconfig | Point at a specific cluster credential file. | kubectl --kubeconfig ~/.kube/prod get nodes |
-f | Create, apply or delete resources described by a YAML file. | kubectl apply -f deploy.yaml |
--dry-run=client | Validate without creating anything, and emit the manifest for review. | kubectl run nginx --image=nginx --dry-run=client -o yaml |
-l | Select resources by label. | kubectl get pods -l app=web |
--previous | Read the logs of the container from the previous, crashed run. | kubectl logs web --previous |
-c | Pick one container out of a multi-container Pod. | kubectl logs web -c app |
--watch | Keep streaming resource changes as they happen. | kubectl get pods --watch |
--record | Write the reason for the change into the revision history. | kubectl set image deploy/web app=new:1.1 --record |
Common pitfalls
SymptomA Pod sits in Pending for a long time.
CauseThe node has no spare capacity, no node matches the scheduling constraints (taints and affinity), or the PVC cannot be bound.
FixRun kubectl describe pod and read the Events; check node capacity with kubectl top nodes and inspect the PVC; then loosen the resource requests or the tolerations.
SymptomThe Pod restarts repeatedly and reports CrashLoopBackOff.
CauseThe application dies as soon as it starts (bad config, dependencies not ready, port already taken), or a probe fails.
FixRead kubectl logs web --previous for the last crash; use kubectl describe pod for Last State and Events; then fix the start command or relax the probe thresholds.
SymptomImage pull fails with ImagePullBackOff or ErrImagePull.
CauseThe image name or tag is wrong, the private registry has no imagePullSecret configured, or the node cannot reach the registry.
FixVerify the image reference and tag; attach imagePullSecrets for private registries; test connectivity from the node with crictl pull.
Symptomkubectl top reports that metrics are not available.
Causemetrics-server is not installed in the cluster — the command itself is fine.
FixConfirm the component is deployed with kubectl get apiservice v1beta1.metrics.k8s.io, install it, then use top again.
SymptomA change intended for local work landed in the production cluster.
CauseThe current context points at production and nothing confirmed the target before the write.
FixRun kubectl config get-contexts and kubectl config current-context before any mutating command, and keep aliases or guard tooling that blocks accidental writes.
SymptomAn apply reports success but the change does not stick.
CauseAnother controller (HPA, an Operator) owns the field and overwrites it, or the field is immutable.
FixInspect the live object with kubectl get; immutable fields such as selector require delete and recreate; check whether a controller is managing that resource.
Troubleshooting
1Start with Pod status and events
kubectl describe pod webThe Events block usually names the real failure directly: FailedScheduling, BackOff, FailedMount and friends.
2Read the application logs, including the previous crash
kubectl logs web --previous -c appDuring a CrashLoop the current container has already exited, so --previous is required to see what it printed before dying.
3Check node capacity and scheduling
kubectl top nodesPending is usually caused by insufficient CPU or memory, or by no schedulable node at all.
4Review the revision history before rolling back
kubectl rollout history deploy/webConfirm there is a good revision to return to, then roll back with kubectl rollout undo deploy/web.
Command Examples
The standard three-step triage for CrashLoopBackOff
kubectl get pods -n prod
kubectl logs <pod> --previous -n prod
kubectl describe pod <pod> -n prodThe restart count only says it is restarting; the real cause is in the previous crash's log, which is why --previous is mandatory here. The Events section at the bottom of describe names the actual reason: failed probe, OOMKilled, or image pull failure.
Output
NAME READY STATUS RESTARTS AGE web-7d9f8b6c5-2xk4t 0/1 CrashLoopBackOff 7 12m
Sort by restart count to spot the outliers immediately
kubectl get pods -n prod --sort-by='.status.containerStatuses[0].restartCount'With hundreds of Pods there is no time to describe them one by one. Sorting ascending by restartCount floats the pods restarting dozens or hundreds of times to the top and narrows the investigation to one or two targets.
Output
NAME READY STATUS RESTARTS AGE api-5f7c9d4b8-mq2xv 0/1 CrashLoopBackOff 142 3h web-7d9f8b6c5-2xk4t 1/1 Running 0 3h
Block on rollout confirmation, then roll back on timeout
kubectl set image deployment/web web=nginx:1.25
kubectl rollout status deployment/web
kubectl rollout undo deployment/webrollout status blocks until the new ReplicaSet is ready, so a timeout almost always means the new version's probes fail. Roll back to the previous revision with undo rather than hand-editing the image and guessing.
Output
deployment "web" successfully rolled out
Dump every container image running in the cluster
kubectl get pods -A -o=custom-columns='DATA:spec.containers[*].image' | sort -uFor version audits and hunting missed upgrades, one -A plus custom-columns yields the image set for the whole cluster; sort -u de-duplicates it and is far faster than describing pods one by one.
Render the manifest first, then apply it safely
kubectl run nginx --image=nginx --dry-run=client -o yaml > pod.yaml
kubectl diff -f ./my-manifest.yaml
kubectl apply -f ./my-manifest.yaml--dry-run=client renders entirely locally and sends no requests, and kubectl diff prints the actual delta that applying would produce. Checking the diff before apply stops a mistyped YAML field from landing straight in the cluster.
Common Pitfalls
- Pointing kubectl config use-context at the wrong cluster means the following delete/scale hits production; confirm with kubectl config current-context before any destructive command.
- kubectl delete pod <pod> --grace-period=0 skips graceful shutdown, killing the process before it can flush or close connections — long requests fail and data is lost.
- kubectl drain evicts workloads but never un-cordons; forgetting kubectl uncordon leaves the node unschedulable and pushes every new Pod elsewhere.
- kubectl replace --force deletes then recreates, which for stateful workloads means fresh volumes and a changed IP — far riskier than an in-place kubectl apply.
- kubectl get secret -o jsonpath={.data.token} still prints base64, not plaintext; using it directly as a credential fails at auth time, and pasting it into logs leaks the secret.
- On a multi-container Pod, omitting -c makes kubectl logs fail with "a container name must be specified" — but it works fine with a single container, which breeds confusing habits.
Tips
- Troubleshooting order: get for status → describe for events → logs for app errors, add --previous for CrashLoop.
- Run kubectl config get-contexts first to confirm the current cluster to avoid accidental operations on production.
- kubectl top errors usually mean metrics-server is not installed, not a command syntax issue.
FAQ
What is the fastest way to debug a CrashLoopBackOff pod?
Follow the same three steps every time: kubectl get pods to see status and restart counts, kubectl describe pod <pod> to read the Events section for scheduling or image-pull failures, then kubectl logs <pod> --previous for the log of the previous crashed instance — without --previous you only see the fresh empty log. Application errors mean a new image or config; if describe shows Pending, shift focus to node resources and taints with kubectl describe node.
kubectl top errors out with a metrics-server connection failure — am I using it wrong?
The command is fine; the cluster simply has no metrics-server installed, so there is no backend behind the Metrics API and kubectl top pod / kubectl top node gets refused. Install metrics-server matching your cluster version and control-plane network plugin, then check kubectl get apiservice to confirm metrics.k8s.io reports Available. While metrics are still warming up, fall back to kubectl describe to read the requests and limits that caused throttling.
How do I avoid firing commands at the production cluster in a multi-cluster setup?
Run kubectl config get-contexts first and check which context carries the current marker, then switch explicitly with kubectl config use-context <ctx>. Pin the namespace too — kubectl config set-context --current --namespace=prod — so you can stop repeating -n prod. After switching, kubectl cluster-info confirms the endpoint you are now talking to. Only after those two checks should you run destructive things like delete or scale.
Both apply and create can create resources — why is apply preferred in production?
create is imperative: it errors out when the object already exists and never updates fields. apply is declarative — it diffs the live cluster state against your manifest, fills in missing fields and overwrites changed ones, so the same file can be applied repeatedly. A good habit is kubectl diff -f ./manifest.yaml to preview the change first, then apply. Reserve create for throwaway experiments like kubectl create deployment web --image=nginx.
A new version deploys but pods never become Ready — roll back or keep waiting?
Do not wait forever: kubectl rollout status deploy/app blocks until it times out, and that timeout is itself the signal that the new version fails its probes. Pass a timeout parameter to bound it. To roll back use kubectl rollout undo deploy/app, optionally with --to-revision to pick the target, and inspect kubectl rollout history deploy/app to see the revisions. Prefer undo over hand-editing the image, otherwise the revision log drifts from what is actually deployed.
Official References
Each command links to its official documentation below, so you can verify the latest usage and read deeper.
Maintained by LaoHand
Publicly updated on Sep 10, 2026, continuously proofread against official docs.
Contact Us
Wrong command or description? Send us corrections, business inquiries or product feedback by email.
Contact Us