Skip to main content
kubectl Cheat Sheet 2026: 60 Commands Grouped by Task

kubectl Cheat Sheet 2026: 60 Commands Grouped by Task

KU
• 8 min read•0 views

The kubectl commands we actually type, grouped by the job in front of you, from switching contexts to rolling back a bad deploy. Copy-paste blocks, real output fields, and the errors that mean you are pointed at the wrong cluster.

Key takeaways

  • The kubectl commands worth memorizing fall into a dozen jobs, setting your context and namespace, reading state with get and describe, logs and exec, rollouts, scaling, apply and diff, permissions with auth can-i, port-forward, top, and output shaping with jsonpath.
  • Set a default namespace per context first, because most kubectl mistakes are the wrong cluster.

You need about sixty kubectl commands for daily Kubernetes work, and they cluster into twelve jobs: context, reading state, logs and exec, debugging, rollouts, scaling, apply and diff, permissions, port-forward, metrics, output shaping and cleanup. The single habit that prevents the most damage is kubectl config set-context --current --namespace=<ns>, so every command lands where you think it does.

Verified against

Kubernetes 1.37, kubectl 1.37, against the kubernetes.io kubectl Quick Reference, the JSONPath support page, and the generated kubectl auth can-i and kubectl wait references. Checked October 2026.

This page is the whole-job reference. When a specific Pod is misbehaving, our ordered kubectl debugging commands walk through the investigation step by step; this sheet is what you keep open in the other tab.

Context and namespace: check this before anything else

Most kubectl incidents are not bad commands. They are good commands run against production. Confirm where you are, then pin a namespace to the context.

code
$ kubectl config get-contexts                        # every context, current one starred
$ kubectl config current-context                     # just the name
$ kubectl config use-context staging-eu              # switch clusters
$ kubectl config set-context --current --namespace=payments   # default namespace for this context
$ kubectl config view --minify                       # only the active context's config
$ kubectl auth whoami                                # which identity the API server sees

Put the current context in your shell prompt.

Reading state: get, describe, explain

code
$ kubectl get pods -o wide                           # node and Pod IP columns
$ kubectl get pods -A                                # all namespaces
$ kubectl get pods -l app=checkout -w                # label selector, then watch
$ kubectl get pods --sort-by='.status.containerStatuses[0].restartCount'
$ kubectl get pods --field-selector=status.phase!=Running
$ kubectl get deploy,svc,ingress                     # several kinds at once
$ kubectl describe pod checkout-7d9f8-abcde          # Events block at the bottom
$ kubectl get events --sort-by=.metadata.creationTimestamp
$ kubectl events --types=Warning                     # warnings only
$ kubectl explain deployment.spec.strategy           # field docs from the API server
$ kubectl api-resources                              # every kind, short name and API group

describe is where the scheduler and kubelet leave their notes. If you only remember one read command, remember that the answer to "why" usually sits in its Events block.

Logs and exec

code
$ kubectl logs -f checkout-7d9f8-abcde               # stream
$ kubectl logs checkout-7d9f8-abcde --previous       # the container that just died
$ kubectl logs checkout-7d9f8-abcde -c envoy         # one container in a multi-container Pod
$ kubectl logs -f -l app=checkout --all-containers   # every Pod matching a label
$ kubectl exec -it checkout-7d9f8-abcde -- /bin/sh   # interactive shell
$ kubectl exec deploy/checkout -- env                # first Pod of a Deployment
$ kubectl cp checkout-7d9f8-abcde:/tmp/heap.out ./heap.out

--previous is the flag people forget during a crash loop. The current container may not have logged anything yet; the one before it has the stack trace.

Debugging Pods and nodes

code
$ kubectl debug checkout-7d9f8-abcde -it --image=busybox:1.28 --target=app   # ephemeral container
$ kubectl debug node/worker-3 -it --image=busybox:1.28                       # shell on a node

Both commands come straight from the Quick Reference. For the decision tree that tells you which one to reach for, use the debugging post linked above or the broader Kubernetes error troubleshooting guide.

Rollouts and scaling

code
$ kubectl rollout status -w deployment/checkout      # block until done or failed
$ kubectl rollout history deployment/checkout        # revisions
$ kubectl rollout undo deployment/checkout           # back one revision
$ kubectl rollout undo deployment/checkout --to-revision=4
$ kubectl rollout restart deployment/checkout        # new Pods, same spec
$ kubectl rollout pause deployment/checkout          # batch several edits
$ kubectl rollout resume deployment/checkout
$ kubectl set image deployment/checkout app=registry.example.com/checkout:2.14.1
$ kubectl scale --replicas=6 deployment/checkout
$ kubectl scale --current-replicas=6 --replicas=8 deployment/checkout   # only if it is 6 now
$ kubectl wait --for=condition=Ready pod -l app=checkout --timeout=120s

kubectl wait gives up after 30 seconds by default, per its reference page, which is shorter than most image pulls. Always pass --timeout in CI.

Apply, diff and safe changes

code
$ kubectl diff -f ./k8s/                             # what would change, before it changes
$ kubectl apply -f ./k8s/                            # every manifest in the directory
$ kubectl apply -f ./k8s/ --dry-run=server           # full admission, nothing persisted
$ kubectl label pods checkout-7d9f8-abcde quarantine=true
$ kubectl annotate deployment/checkout team=payments

We run kubectl diff before every manual apply. It compares the live object with what the cluster would hold after the change, so drift someone introduced by hand shows up before you overwrite it.

Permissions, access and metrics

code
$ kubectl auth can-i create deployments -n payments
$ kubectl auth can-i --list --namespace=payments
$ kubectl auth can-i list pods --as=system:serviceaccount:ci:deployer -n payments
$ kubectl auth can-i get pods --subresource=log
$ kubectl port-forward svc/checkout 8080:80          # local 8080 to the Service
$ kubectl port-forward deploy/checkout 9090:9090     # a Pod picked from the Deployment
$ kubectl top node
$ kubectl top pod --containers --sort-by=memory

--as needs impersonation rights, and it is the fastest way to answer "why does the pipeline get Forbidden" without asking anyone for their token.

Output shaping: jsonpath and custom-columns

code
$ kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.phase}{"\n"}{end}'
$ kubectl get pods -o custom-columns='NAME:.metadata.name,IMAGE:.spec.containers[*].image'
$ kubectl get nodes -o custom-columns='NODE:.metadata.name,READY:.status.conditions[?(@.type=="Ready")].status'
$ kubectl get secret db-creds -o jsonpath='{.data.password}' | base64 -d
$ kubectl get pods -o json | jq -r '.items[] | select(.metadata.name | test("checkout-")).metadata.name'

kubectl's JSONPath does not support regular expressions; the docs say to pipe JSON into jq instead, which is the last line above.

Cleanup and node maintenance

code
$ kubectl delete pods,services -l app=old-checkout
$ kubectl delete pods --field-selector=status.phase=Failed -n payments
$ kubectl cordon worker-3                            # stop new scheduling
$ kubectl drain worker-3 --ignore-daemonsets         # evict, respecting PDBs
$ kubectl uncordon worker-3

Add --dry-run=client -o name to any delete first. It prints what the selector matches, and a selector that matches more than you expected is how namespaces get emptied.

The errors that mean you are pointed at the wrong thing

Error stringWhat it usually meansFirst check
The connection to the server localhost:8080 was refused - did you specify the right host or port?No kubeconfig loadedecho $KUBECONFIG, kubectl config view
error: You must be logged in to the server (Unauthorized)Expired token or cloud credentialsRe-run your provider's login
Error from server (Forbidden): pods is forbidden: User "..." cannot list resource "pods"RBAC, or the wrong namespacekubectl auth can-i list pods -n <ns>
error: Metrics API not availablemetrics-server not installed or not readykubectl get apiservices | grep metrics
exec: "tar": executable file not found in $PATHkubectl cp needs tar in the imageUse kubectl debug or exec ... cat

Where this breaks

This sheet assumes kubectl within one minor version of your cluster and RBAC that lets you read most things. Managed platforms add their own wrappers (oc, cloud CLIs for auth), and locked-down clusters will reject debug node/ and --as outright. On GitOps-managed namespaces, scale, set image and annotate are temporary: the controller reverts them on its next sync, so change Git instead.

Questions people ask

How do I switch namespace in kubectl permanently?

Run kubectl config set-context --current --namespace=<name>. It writes the namespace into your current context in kubeconfig, so every later command without -n uses it until you change it again. It is per context, so switching clusters with kubectl config use-context brings back whatever namespace that context had. Tools like kubens wrap the same call.

How do I see logs from a pod that crashed?

Use kubectl logs <pod> --previous, adding -c <container> for multi-container Pods. The flag returns output from the previous instance of the container, which is the one that crashed, while plain kubectl logs shows the fresh instance that may not have logged anything yet. Pair it with kubectl describe pod to see the exit code and reason.

What is the difference between kubectl apply and kubectl create?

kubectl create makes a resource and fails if it already exists. kubectl apply is declarative: it creates the resource when missing and patches it toward your manifest when present, recording what you last applied so later removals are detected. Use apply for anything you keep in Git, and run kubectl diff first so you see the change before it lands.

The call we'd make

Memorize the context block and the rollout block; look up the rest here. Pin a namespace per context, show the context in your prompt, and run kubectl diff before any manual apply. If you find yourself running scale or set image in production more than once a month, that change belongs in Git and a pipeline, not in your shell history.

Sources

Explore topics:KubernetesDevOps
React
Share this post
Cite this article
Plain text

Kiril Urbonas (2026). kubectl Cheat Sheet 2026: 60 Commands Grouped by Task. DevOpsNess. https://www.devopsness.com/blog/kubectl-cheatsheet

Markdown

[kubectl Cheat Sheet 2026: 60 Commands Grouped by Task](https://www.devopsness.com/blog/kubectl-cheatsheet) (Kiril Urbonas, DevOpsNess, 2026-10-31)

KU

Kiril Urbonas

AI Engineer

585 articles
View all articles by Kiril Urbonas

You might have missed

Evergreen posts worth revisiting.