kubectl Cheatsheet — 100+ Kubernetes Commands with Pitfalls and YAML Templates
kubectl cheat sheet — 100+ Kubernetes commands with real examples, common pitfalls, and YAML snippets.
Runs locally
CategoryDeveloper & DevOps
Best forFormatting, validating, shrinking, or inspecting code-adjacent text.
176 commands
Cluster (22)
kubectl cluster-info
Print the API server URL and the cluster service endpoints (DNS, dashboard if installed).
⚠ Common pitfall: If this hangs, kubeconfig is pointing at a server you cannot reach (VPN down, wrong context). Check `kubectl config current-context` first.
Examples
kubectl cluster-info
kubectl cluster-info dump
kubectl get nodes
List all nodes with status, roles, age, version. Add -o wide to see internal/external IP and OS.
Examples
kubectl get nodes
kubectl get nodes -o wide
kubectl get nodes --show-labels
kubectl top nodes
Show CPU and memory usage per node (real numbers from metrics-server, not limits).
⚠ Common pitfall: Needs metrics-server installed and Ready. On bare clusters you get `error: Metrics API not available` until you helm install it.
Examples
kubectl top nodes
kubectl top nodes --sort-by=memory
kubectl describe node <node>
Deep view of a node: labels, taints, allocatable resources, conditions, running pods, events.
Examples
kubectl describe node ip-10-0-1-23
kubectl describe node | grep -A3 Taints
kubectl cordon <node>
Mark a node unschedulable — no new pods land there, existing ones keep running.
⚠ Common pitfall: Cordon alone does NOT move workloads off — pair with `drain` before maintenance, then `uncordon` after.
Examples
kubectl cordon ip-10-0-1-23
kubectl uncordon ip-10-0-1-23
kubectl drain <node>
Evict all pods from a node before maintenance. Respects PodDisruptionBudgets.
⚠ Common pitfall: Daemonsets block drain by default — pass `--ignore-daemonsets`. Local-storage pods need `--delete-emptydir-data` and that DATA IS GONE.
Print the kubeconfig context you are currently pointing at (cluster + namespace + user).
⚠ Common pitfall: After a wrong `kubectl delete`, the first question is "which cluster did I just hit?" — wire this into your shell prompt with kubectx or starship.
Examples
kubectl config current-context
kubectl config get-contexts
kubectl config use-context <name>
Switch to a different context defined in kubeconfig.
⚠ Common pitfall: For frequent switching, install `kubectx` — `kubectx prod` is shorter than the full command and shows interactive fzf list.
Print client and server version. Skew of >1 minor is unsupported.
Examples
kubectl version
kubectl version -o json
kubectl api-resources
List every resource type known to the API server with its short name, group, and namespaced flag.
Examples
kubectl api-resources
kubectl api-resources --namespaced=true
kubectl api-resources --api-group=apps
kubectl explain <resource>
Inline docs for any resource and its fields. Drill down with dotted paths.
Examples
kubectl explain pod
kubectl explain pod.spec.containers
kubectl explain deployment --recursive
kubectl get componentstatuses
Legacy command showing control-plane component health. Deprecated since 1.19 — replaced by `kubectl get --raw=/livez`.
⚠ Common pitfall: On managed Kubernetes (EKS, GKE, AKS) you cannot see control-plane state — the cloud provider handles it. This will return errors or empty.
Examples
kubectl get componentstatuses
kubectl get --raw=/livez?verbose
kubectl get --raw=/readyz?verbose
kubectl config view
Print the merged kubeconfig. Add --minify to show only the current context, --flatten to inline cert data.
⚠ Common pitfall: By default certs/tokens are redacted. Add --raw to dump real credentials. Never paste --raw output into a chat or issue.
Examples
kubectl config view --minify
kubectl config view --flatten -o yaml
kubectl config view --raw
kubectl config get-contexts
List every context in kubeconfig with a * marking the active one, plus its cluster, user, and namespace.
Examples
kubectl config get-contexts
kubectl config get-contexts -o name
kubectl config delete-context <name>
Remove a context entry from kubeconfig. Does not touch the cluster or user entries it referenced.
⚠ Common pitfall: Leaves orphaned cluster/user blocks behind. Run `kubectl config delete-cluster` and `delete-user` too if you want a clean file.
Examples
kubectl config delete-context old-prod
kubectl config delete-cluster old-prod
kubectl config delete-user old-prod-admin
kubectl uncordon <node>
Mark a node schedulable again after maintenance. The inverse of cordon.
Examples
kubectl uncordon ip-10-0-1-23
kubectl get nodes | grep SchedulingDisabled
kubectl taint nodes <node> <key>=<val>:<effect>
Add a taint so only pods with a matching toleration land on the node. Effects: NoSchedule, PreferNoSchedule, NoExecute.
⚠ Common pitfall: NoExecute also evicts already-running pods that lack the toleration. Remove a taint by appending a minus: `key=val:NoSchedule-`.
Label a node so pods can target it with nodeSelector or nodeAffinity (e.g. disk=ssd, zone=us-east-1a).
Examples
kubectl label nodes ip-10-0-1-23 disk=ssd
kubectl label nodes ip-10-0-1-23 disk-
kubectl get nodes -L disk,zone
kubectl get nodes -o wide
List nodes with extra columns: internal/external IP, OS image, kernel version, container runtime.
Examples
kubectl get nodes -o wide
kubectl get nodes -o custom-columns=NAME:.metadata.name,RUNTIME:.status.nodeInfo.containerRuntimeVersion
kubectl get --raw=/readyz?verbose
Hit the API server readiness endpoint directly, listing each health check and its status. The modern componentstatuses.
Examples
kubectl get --raw=/readyz?verbose
kubectl get --raw=/livez?verbose
kubectl get --raw=/healthz
kubectl api-versions
List every API group/version the server serves (e.g. apps/v1, batch/v1, networking.k8s.io/v1).
⚠ Common pitfall: Use this to confirm whether a deprecated apiVersion (extensions/v1beta1) still exists before an upgrade breaks your manifests.
Examples
kubectl api-versions
kubectl api-versions | grep networking
Pod (25)
kubectl get pods
List pods in the current namespace. Most common kubectl command.
Examples
kubectl get pods
kubectl get pods -A
kubectl get pods -o wide
kubectl get pods -w
kubectl get pods -l app=web
kubectl get pod <name>
Get a single pod. Add -o yaml/json for the full spec, or -o jsonpath= for surgical extraction.
Examples
kubectl get pod web-7d5 -o yaml
kubectl get pod web-7d5 -o jsonpath="{.status.phase}"
kubectl get pod web-7d5 -o json | jq .status
kubectl describe pod <name>
Human-readable deep view: spec, status, containers, volumes, events. First stop for any pod issue.
⚠ Common pitfall: Events at the bottom are the actual debugging gold — ImagePull errors, FailedScheduling reasons, OOMKilled, liveness/readiness failures all live there.
Examples
kubectl describe pod web-7d5
kubectl describe pod web-7d5 | tail -30
kubectl logs <pod>
Print stdout/stderr of a pod's main container.
⚠ Common pitfall: Multi-container pod? Add `-c <container>` or you get an error. App writing to a file in the container? `logs` is empty. Make 12-factor apps log to stdout.
Examples
kubectl logs web-7d5
kubectl logs web-7d5 -c sidecar
kubectl logs -l app=web --tail=50
kubectl logs -f <pod>
Stream new log lines as they appear. Like tail -f, but for the container.
Examples
kubectl logs -f web-7d5
kubectl logs -f web-7d5 --since=10m
kubectl logs -f deployment/web
kubectl logs --previous <pod>
Show logs from the previous container instance — the run that just crashed.
⚠ Common pitfall: For CrashLoopBackOff debugging, this is THE command. Without --previous you see the current restart's logs which are empty until it crashes again.
Examples
kubectl logs --previous web-7d5
kubectl logs -p -c app web-7d5
kubectl exec -it <pod> -- <cmd>
Open an interactive shell or run a command inside a running pod.
⚠ Common pitfall: Try `bash` first, fall back to `sh` — alpine has no bash, distroless has no shell at all (use `kubectl debug`). The `--` separates kubectl flags from container args.
Examples
kubectl exec -it web-7d5 -- bash
kubectl exec -it web-7d5 -- sh
kubectl exec web-7d5 -- ls /app
kubectl exec -it web-7d5 -c sidecar -- sh
kubectl port-forward <pod> <local>:<pod>
Tunnel a local port to a port inside a pod (or service). Great for poking at a private service from your laptop.
⚠ Common pitfall: Tunnel dies on idle, network flap, or pod restart. For long-running access use a proper bastion or `telepresence`, not port-forward.
Examples
kubectl port-forward pod/web-7d5 8080:80
kubectl port-forward svc/web 8080:80
kubectl port-forward deployment/web 8080:80
kubectl cp <pod>:<path> <local>
Copy files between a pod and your local machine. Either side can be the pod.
⚠ Common pitfall: Needs `tar` in the container. Many distroless images have none — bake one in or use a debug ephemeral container.
Examples
kubectl cp web-7d5:/var/log/app.log ./app.log
kubectl cp ./fix.patch web-7d5:/tmp/
kubectl cp web-7d5:/data ./data -c sidecar
kubectl attach <pod>
Attach your terminal to the main process of a running pod. Ctrl-C may kill the container.
⚠ Common pitfall: `attach` is NOT a shell — it joins the existing process. Unless you really need the original TTY, `exec -it ... -- sh` is what you want.
Examples
kubectl attach web-7d5
kubectl attach -it web-7d5 -c app
kubectl delete pod <name>
Delete one or more pods. If owned by a controller (Deployment etc.) a replacement spins up.
⚠ Common pitfall: For restarting a deployment, use `rollout restart` — it is the supported primitive. `delete pod` on a stuck Terminating pod needs `--grace-period=0 --force` (and may leak network endpoints).
Examples
kubectl delete pod web-7d5
kubectl delete pod web-7d5 --grace-period=0 --force
kubectl delete pods -l app=web
kubectl debug <pod> --image=<dbg>
Attach an ephemeral debug container (with curl, ps, tcpdump, whatever) to a running pod — even distroless.
⚠ Common pitfall: Needs Kubernetes ≥1.23 with EphemeralContainers stable. The debug container shares network and PID namespace, NOT the filesystem.
Show the last N lines. Use --tail=-1 to print all (the default sometimes hides old logs).
Examples
kubectl logs --tail=100 web-7d5
kubectl logs --tail=-1 web-7d5 > app.log
kubectl logs --all-containers <pod>
Stream logs from every container in the pod at once (app + sidecars), instead of picking one with -c.
⚠ Common pitfall: Lines from different containers interleave with no prefix by default. Add `--prefix` to tag each line with its pod/container name.
Examples
kubectl logs --all-containers web-7d5
kubectl logs --all-containers --prefix -l app=web
kubectl logs --timestamps <pod>
Prefix every log line with an RFC3339 timestamp from when the container emitted it.
Examples
kubectl logs --timestamps web-7d5
kubectl logs --timestamps --since=10m -f web-7d5
kubectl get pod <name> -o jsonpath=...
Extract exactly the field you want from a pod with a JSONPath expression. Scriptable, no jq needed.
⚠ Common pitfall: Wrap the expression in single quotes and add `range`/`end` to iterate over arrays like containers. A trailing `{"\n"}` adds a newline.
Examples
kubectl get pod web-7d5 -o jsonpath='{.status.podIP}'
kubectl get pod web-7d5 -o jsonpath='{range .spec.containers[*]}{.name}{"\t"}{.image}{"\n"}{end}'
kubectl get pods -o jsonpath='{.items[*].metadata.name}'
kubectl exec <pod> -- env
Dump the environment variables visible inside a running container. Fast way to verify injected config/secrets.
⚠ Common pitfall: This prints decoded secret values in plain text to your terminal/scrollback. Avoid on shared screens or recorded sessions.
Examples
kubectl exec web-7d5 -- env
kubectl exec web-7d5 -- env | grep DATABASE
kubectl exec web-7d5 -c app -- printenv LOG_LEVEL
kubectl exec <pod> -- cat /etc/resolv.conf
Read the DNS config a pod actually sees. First stop when in-cluster name resolution misbehaves.
⚠ Common pitfall: A wrong `ndots:5` (the default) makes every short name try 5 search-domain suffixes first, causing slow lookups. Compare nameserver against the kube-dns ClusterIP.
Launch a debug pod with host namespaces on a specific node — inspect the node filesystem at /host, run tcpdump, etc.
⚠ Common pitfall: The node root filesystem is mounted at `/host`, not `/`. To chroot into it: `chroot /host`. This needs privileges your RBAC may not grant.
List pods ordered by start time — the newest restarts float to the bottom. Spot flapping pods fast.
Examples
kubectl get pods --sort-by=.status.startTime
kubectl get pods --sort-by=.status.containerStatuses[0].restartCount
kubectl get pods -o custom-columns=...
Build a custom table from any fields — name, node, restart count, image — instead of the default columns.
Examples
kubectl get pods -o custom-columns=NAME:.metadata.name,NODE:.spec.nodeName,RESTARTS:.status.containerStatuses[0].restartCount
kubectl get pods -o custom-columns=POD:.metadata.name,IMAGE:.spec.containers[*].image
kubectl get pod <name> -o yaml | kubectl neat
Strip the server-injected noise (managedFields, status, default annotations) so the YAML is re-appliable. Needs the krew `neat` plugin.
⚠ Common pitfall: A raw `get -o yaml` is NOT re-appliable as-is — it carries status and managedFields that `apply` rejects or fights. `neat` (or manual trimming) fixes that.
Examples
kubectl get pod web-7d5 -o yaml | kubectl neat
kubectl krew install neat
Workload (25)
kubectl create deployment <name> --image=<img>
Imperative one-liner to create a Deployment. Fine for demos; use YAML + apply for real systems.
Examples
kubectl create deployment web --image=nginx
kubectl create deployment web --image=nginx --replicas=3 --port=80
kubectl get deployments
List Deployments with desired / current / ready / age. Short name: `deploy`.
Examples
kubectl get deployments
kubectl get deploy -A
kubectl get deploy web -o yaml
kubectl scale deployment <name> --replicas=<n>
Change the replica count of a Deployment (or ReplicaSet / StatefulSet). Takes effect immediately.
⚠ Common pitfall: Scaling to 0 is the supported "pause" — pods are gone but the spec is preserved. Scaling back up is instant.
Examples
kubectl scale deployment web --replicas=3
kubectl scale deployment web --replicas=0
kubectl scale --replicas=5 -f deployment.yaml
kubectl rollout status deployment/<name>
Block and watch a rollout until it succeeds, fails, or times out.
Examples
kubectl rollout status deployment/web
kubectl rollout status deployment/web --timeout=2m
kubectl rollout history deployment/<name>
Show past revisions of a Deployment. Add --revision=N for the diff of a specific one.
Examples
kubectl rollout history deployment/web
kubectl rollout history deployment/web --revision=3
kubectl rollout undo deployment/<name>
Roll back to the previous revision (or to a specific one with --to-revision).
⚠ Common pitfall: History depth defaults to 10. Once it scrolls off you cannot undo to it — pin critical revisions in git.
Trigger a rolling restart by bumping a template annotation. The right way to restart a Deployment.
⚠ Common pitfall: Use this instead of `delete pod` — proper rolling update, maxUnavailable honored, zero downtime, undo works. Available for Deployments, StatefulSets, DaemonSets since 1.15.
Create a HorizontalPodAutoscaler that scales the Deployment between min and max based on CPU.
⚠ Common pitfall: HPA needs metrics-server. Custom-metric HPA needs an adapter (prometheus-adapter etc.). Without metrics HPA shows `unknown` and never scales.
Examples
kubectl autoscale deployment web --min=2 --max=10 --cpu-percent=70
kubectl get hpa
kubectl describe hpa web
kubectl get replicaset
List ReplicaSets. Each Deployment revision creates a new ReplicaSet under the hood.
Examples
kubectl get rs
kubectl get rs -l app=web
kubectl describe rs web-7d5f44
kubectl get statefulset
List StatefulSets — for ordered, stable-network-ID workloads like databases.
⚠ Common pitfall: PVCs created by a StatefulSet are NOT deleted when the STS is deleted — explicit cleanup needed or your data persists forever.
Examples
kubectl get sts
kubectl describe sts db
kubectl delete sts db --cascade=orphan
kubectl get daemonset
List DaemonSets — pods that run one copy per matching node (log shippers, CNI agents, node exporters).
Examples
kubectl get ds
kubectl get ds -A
kubectl rollout restart ds/log-agent
kubectl get job
List Jobs (run-to-completion workloads). Add `cronjob` for scheduled ones.
Create a Service in front of an existing Deployment (or Pod / RS). One-liner for ClusterIP.
Examples
kubectl expose deployment web --port=80 --target-port=8080
kubectl expose deployment web --type=NodePort --port=80
kubectl expose deployment web --type=LoadBalancer --port=80
kubectl get hpa
List HorizontalPodAutoscalers with current / target metric, min, max, age.
Examples
kubectl get hpa
kubectl describe hpa web
kubectl delete hpa web
kubectl get pdb
List PodDisruptionBudgets. They cap voluntary disruptions (drains, rolling updates) so SLO is preserved.
⚠ Common pitfall: A PDB with minAvailable=N where current replicas=N causes `drain` to hang forever. Set realistic numbers or scale up before maintenance.
Deep dive on a Deployment: replicas, strategy, current ReplicaSet, events.
Examples
kubectl describe deployment web
kubectl describe deploy web | grep -A5 Conditions
kubectl set env deployment/<name> KEY=VAL
Add or change an environment variable on a Deployment, triggering a rolling update. Use KEY- to remove one.
⚠ Common pitfall: Like `set image`, this edits the live spec and drifts from your git YAML. Use `--from=configmap/<cm>` to pull all keys from a ConfigMap at once.
Examples
kubectl set env deployment/web LOG_LEVEL=debug
kubectl set env deployment/web LOG_LEVEL-
kubectl set env deployment/web --from=configmap/app-config
kubectl set resources deployment/<name> --limits=cpu=1,memory=512Mi
Patch CPU/memory requests and limits on a Deployment without editing YAML. Triggers a rolling update.
Examples
kubectl set resources deployment/web --limits=cpu=1,memory=512Mi --requests=cpu=200m,memory=256Mi
kubectl set resources deployment/web -c=app --limits=memory=1Gi
Imperatively create a CronJob with a cron schedule. The command after -- becomes the container command.
⚠ Common pitfall: CronJob times are in the kube-controller-manager timezone (usually UTC), not yours, unless you set `spec.timeZone` (stable since 1.27).
Watch a StatefulSet rollout. Pods update one at a time in reverse ordinal order by default.
⚠ Common pitfall: A StatefulSet with `updateStrategy: OnDelete` will NOT roll out on spec change — you must delete each pod manually for it to recreate with the new spec.
Examples
kubectl rollout status statefulset/db
kubectl rollout status sts/db --timeout=5m
kubectl scale statefulset <name> --replicas=<n>
Scale a StatefulSet. Pods are added/removed one at a time, in order, respecting readiness.
⚠ Common pitfall: Scaling down does NOT delete the PVCs of removed pods (unless persistentVolumeClaimRetentionPolicy is set, 1.27+). Data sticks around.
Examples
kubectl scale statefulset db --replicas=5
kubectl scale sts db --replicas=1
kubectl get cronjob
List CronJobs with their schedule, suspend flag, last-scheduled time, and active job count.
⚠ Common pitfall: A CronJob with SUSPEND=True never fires. Resume with `kubectl patch cronjob <cj> -p '{"spec":{"suspend":false}}'`.
kubectl get cronjob backup -o jsonpath='{.status.lastScheduleTime}'
kubectl describe hpa <name>
Show HPA decision-making: current vs target metrics, recent scaling events, and any "unable to fetch metrics" errors.
⚠ Common pitfall: The Events at the bottom explain WHY the HPA is or is not scaling. `FailedGetResourceMetric` there almost always means metrics-server is down.
Examples
kubectl describe hpa web
kubectl get hpa web -o yaml | grep -A10 conditions
kubectl rollout undo statefulset/<name>
Roll a StatefulSet back to its previous revision. Like Deployments, it keeps a revision history.
Examples
kubectl rollout undo statefulset/db
kubectl rollout history statefulset/db
Service & Ingress (11)
kubectl get services
List Services with type, cluster IP, external IP, ports, age. Short name: `svc`.
Examples
kubectl get svc
kubectl get svc -A
kubectl get svc -o wide
kubectl get endpoints <svc>
List the actual pod IPs behind a Service. Empty endpoints == broken selector or no ready pods.
⚠ Common pitfall: Service has clusterIP but `curl svc` hangs? `kubectl get endpoints <svc>` is the answer 90% of the time. Empty means the selector matched nothing or readinessProbe is failing.
Examples
kubectl get endpoints web
kubectl get endpointslices -l kubernetes.io/service-name=web
kubectl port-forward svc/<name> <local>:<svc>
Tunnel a local port to a Service. Goes through endpoints, not directly to a pod.
Examples
kubectl port-forward svc/web 8080:80
kubectl port-forward svc/db 5432:5432 -n staging
kubectl get ingress
List Ingress resources with hosts, paths, address, ports.
⚠ Common pitfall: An Ingress without an IngressClass annotation (`ingressClassName: nginx`) is invisible to controllers — looks created but nothing serves it.
Examples
kubectl get ingress
kubectl describe ingress web
kubectl get ingressclass
kubectl get networkpolicy
List NetworkPolicies that restrict pod-to-pod traffic. No policy = all traffic allowed (default).
⚠ Common pitfall: NetworkPolicy is enforced by the CNI plugin (Calico, Cilium, ...). On a CNI without policy support, NetworkPolicies are silently ignored — verify with `kubectl get ds -n kube-system`.
Examples
kubectl get netpol
kubectl describe netpol deny-all
kubectl get netpol -A
kubectl proxy
Start a local API server proxy on 127.0.0.1:8001 — use to access dashboard / API without auth handling.
Examples
kubectl proxy
kubectl proxy --port=9090
curl http://127.0.0.1:8001/api/v1/namespaces
kubectl describe ingress <name>
Show an Ingress with its rules, backend services, TLS, and controller-synced events at the bottom.
⚠ Common pitfall: If the ADDRESS column stays empty, no controller has claimed this Ingress — check ingressClassName and that the controller pod is running.
Examples
kubectl describe ingress web
kubectl get ingress web -o jsonpath='{.status.loadBalancer.ingress[0].ip}'
kubectl get endpointslices
List EndpointSlices — the scalable successor to Endpoints (default since 1.21). Each slice holds up to ~100 endpoints.
Examples
kubectl get endpointslices
kubectl get endpointslices -l kubernetes.io/service-name=web
kubectl describe endpointslice web-abc12
kubectl get svc <name> -o jsonpath=...
Pull a single field from a Service — the LoadBalancer external IP/hostname, the NodePort, or the ClusterIP.
⚠ Common pitfall: AWS NLBs publish a hostname, not an IP — read `.status.loadBalancer.ingress[0].hostname`, not `.ip`, or you get an empty string.
Examples
kubectl get svc web -o jsonpath='{.status.loadBalancer.ingress[0].hostname}'
kubectl get svc web -o jsonpath='{.spec.clusterIP}'
kubectl get svc web -o jsonpath='{.spec.ports[0].nodePort}'
kubectl create service clusterip <name> --tcp=<port>:<target>
Imperatively create a ClusterIP Service. Use --tcp=80:8080 to map service port to target port.
⚠ Common pitfall: This creates a Service with NO selector unless you add one afterward — useful for pointing at external endpoints, surprising if you expected pod routing.
Examples
kubectl create service clusterip web --tcp=80:8080
kubectl create service nodeport web --tcp=80:8080 --node-port=30080
kubectl get ingressclass
List installed IngressClasses and which is the default. An Ingress with no class falls back to the default-marked one.
Examples
kubectl get ingressclass
kubectl get ingressclass -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.annotations.ingressclass\.kubernetes\.io/is-default-class}{"\n"}{end}'
Create a ConfigMap from one file or a whole directory (each file becomes a key).
⚠ Common pitfall: Total size cap is ~1 MB (etcd limit). For larger config use a Secret/ConfigMap projected volume + an init container, or move to a config service.
Create a Secret from literal pairs. Values are base64-encoded at rest (NOT encrypted unless KMS is on).
⚠ Common pitfall: Secrets are base64, NOT encryption. Anyone with `get secrets` can decode. Enable encryption-at-rest in apiserver and consider Sealed Secrets / External Secrets for real safety.
Examples
kubectl create secret generic db --from-literal=password=s3cret
kubectl create secret generic api --from-literal=token=abc123
kubectl create secret docker-registry <name>
Create an imagePullSecret for a private registry. Reference it in pod spec with imagePullSecrets.
List PersistentVolumeClaims with status, capacity, access modes, storage class, age.
⚠ Common pitfall: PVC stuck in Pending = no matching PV / StorageClass. `describe pvc` shows the reason. Deleting a PVC may delete the underlying PV depending on reclaim policy.
Build a ConfigMap from a .env file — each KEY=VALUE line becomes a key. Different from --from-file (whole file as one key).
⚠ Common pitfall: Lines must be plain KEY=VALUE — no `export`, no quotes-with-spaces parsing, no inline comments after the value. Shell-style .env files often fail.
Read one key out of a ConfigMap directly, no -o yaml + manual scan. Great for shell scripts.
Examples
kubectl get configmap app-config -o jsonpath='{.data.LOG_LEVEL}'
kubectl get cm app-config -o jsonpath='{.data}'
kubectl edit secret <name>
Open a Secret in $EDITOR. Values shown are base64 — you must encode new values yourself before saving.
⚠ Common pitfall: Paste plaintext here and the value becomes double-mangled garbage. Use `kubectl create secret ... --dry-run=client -o yaml | kubectl apply -f -` instead to avoid manual base64.
Show a PVC's phase, bound PV, capacity, access mode, and — crucially — the Events explaining why it is Pending.
⚠ Common pitfall: Pending with `no persistent volumes available` means no StorageClass can provision, or you set a storageClassName that does not exist.
Examples
kubectl describe pvc data-db-0
kubectl get storageclass
kubectl get pvc -o wide
kubectl get storageclass
List StorageClasses and which is default (marked with (default)). PVCs with no storageClassName use the default.
⚠ Common pitfall: No default StorageClass means every PVC without an explicit class stays Pending forever. Many bare clusters ship with none.
List PersistentVolumes cluster-wide with capacity, access mode, reclaim policy, status, and the claim they are bound to.
⚠ Common pitfall: A PV stuck in Released (not Available) after its PVC was deleted will NOT rebind — reclaimPolicy=Retain keeps the data but blocks reuse until you clear `.spec.claimRef`.
Examples
kubectl get pv
kubectl get pv -o custom-columns=NAME:.metadata.name,STATUS:.status.phase,CLAIM:.spec.claimRef.name
Bind a Role to a ServiceAccount, User, or Group within a namespace.
⚠ Common pitfall: Role + RoleBinding are namespaced. For cluster-wide permissions you need ClusterRole + ClusterRoleBinding. Mixing them is a common silent failure.
Check whether the current user (or --as <name>) is allowed to perform an action. THE RBAC debug command.
⚠ Common pitfall: Add `--list` to dump every permission you have in the namespace. Add `--as system:serviceaccount:ns:sa` to test from a pod's perspective.
Examples
kubectl auth can-i delete pods
kubectl auth can-i --list -n staging
kubectl auth can-i get secrets --as system:serviceaccount:default:my-bot
kubectl create token <serviceaccount>
Request a time-bounded bearer token for a ServiceAccount (replaces legacy auto-created Secret tokens since 1.24).
⚠ Common pitfall: Since 1.24 SAs no longer auto-create Secret tokens — old scripts that read `kubectl get secret` for the token return nothing. Switch to `kubectl create token` or define a Secret of type kubernetes.io/service-account-token explicitly.
Examples
kubectl create token ci-bot
kubectl create token ci-bot --duration=1h
kubectl create token default -n ci > /tmp/token
kubectl create namespace <name>
Create a new namespace. The minimum unit of isolation in a cluster.
Print the username, groups, and extra attributes the API server attributes to your current credentials (stable since 1.28).
⚠ Common pitfall: Surprisingly useful when an OIDC/IAM token maps you to a different user than expected — RBAC denials often trace back to the wrong identity here.
Examples
kubectl auth whoami
kubectl auth whoami -o yaml
kubectl get clusterrolebinding
List cluster-wide RoleBindings. The place to audit who has cluster-admin or other powerful ClusterRoles.
⚠ Common pitfall: A binding to the `system:masters` group or `cluster-admin` ClusterRole is full god mode. Grep for these first in any security review.
Examples
kubectl get clusterrolebinding
kubectl get clusterrolebinding -o jsonpath='{range .items[?(@.roleRef.name=="cluster-admin")]}{.metadata.name}{"\n"}{end}'
kubectl describe clusterrole <name>
Show exactly which verbs on which resources a ClusterRole grants. Read before binding anyone to it.
Bind a (cluster-scoped) ClusterRole to a ServiceAccount but only within ONE namespace. Common least-privilege pattern.
⚠ Common pitfall: Using --clusterrole with a RoleBinding (not ClusterRoleBinding) scopes those permissions to the binding's namespace only — a deliberate and very useful narrowing.
Examples
kubectl create rolebinding ci-edit --clusterrole=edit --serviceaccount=ci:ci-bot -n ci
kubectl get rolebinding,clusterrolebinding -A -o wide
Wide listing of all bindings across namespaces, with the subjects (users/SAs/groups) shown in the output.
Examples
kubectl get rolebinding,clusterrolebinding -A -o wide
kubectl get clusterrolebinding -o wide | grep alice
Monitoring (13)
kubectl top pods
CPU + memory usage per pod (real numbers from metrics-server, not requests/limits).
⚠ Common pitfall: Needs metrics-server installed. Without it: `Metrics API not available`. Container-level breakdown: `top pods --containers`.
Examples
kubectl top pods
kubectl top pods --sort-by=memory
kubectl top pods --containers -A
kubectl get events
List recent cluster events. Add --sort-by to put the newest first.
⚠ Common pitfall: Default sort is by ResourceVersion which is meaningless to humans. ALWAYS add `--sort-by=.lastTimestamp` or `.metadata.creationTimestamp`.
Examples
kubectl get events --sort-by=.lastTimestamp
kubectl get events -A --sort-by=.lastTimestamp
kubectl get events --field-selector involvedObject.name=web-7d5
kubectl wait --for=condition=Ready pod/<name>
Block until a resource reaches a condition. Great for CI scripts after `apply`.
Watch mode: stream changes to pod state as they happen. Ctrl-C to stop.
Examples
kubectl get pods -w
kubectl get pods -w -l app=web
kubectl get pods -w -o wide
kubectl get pods --field-selector=status.phase=Failed
Filter pods by status. The classic "find every failed / pending pod" search.
Examples
kubectl get pods --field-selector=status.phase=Failed -A
kubectl get pods --field-selector=status.phase=Pending
kubectl get pods --field-selector=spec.nodeName=ip-10-0-1-23
kubectl get all
List pods + svc + deploy + rs + statefulset + daemonset in one shot. Good high-level glance.
⚠ Common pitfall: `all` does NOT include configmaps, secrets, ingresses, jobs, PVCs, CRDs — the name is misleading. For "really all", iterate api-resources.
Examples
kubectl get all
kubectl get all -A
kubectl get all -n staging -o wide
kubectl top pod <name> --containers
Break CPU/memory usage down per container within one pod — find which sidecar is the memory hog.
Examples
kubectl top pod web-7d5 --containers
kubectl top pod -l app=web --containers --sort-by=memory
kubectl get events --field-selector type=Warning
Show only Warning-level events (Normal events filtered out) — the actionable problems, not the routine noise.
Examples
kubectl get events --field-selector type=Warning --sort-by=.lastTimestamp
kubectl get events -A --field-selector type=Warning --sort-by=.lastTimestamp
kubectl get events --field-selector involvedObject.name=<name>
Scope events to a single object — see only what happened to this pod/deployment, not the whole namespace.
Examples
kubectl get events --field-selector involvedObject.name=web-7d5
kubectl get events --field-selector involvedObject.kind=Deployment,involvedObject.name=web
kubectl get pods -A -o wide --field-selector spec.nodeName=<node>
List every pod scheduled on a specific node, across all namespaces. Essential before draining a node.
Examples
kubectl get pods -A -o wide --field-selector spec.nodeName=ip-10-0-1-23
kubectl get pods -A --field-selector spec.nodeName=ip-10-0-1-23 -o name | wc -l
Stream only future changes (skip the initial full list). Pairs well with scripts that react to new events.
Examples
kubectl get pods --watch-only
kubectl get pods --watch-only -o json | jq .status.phase
kubectl top node --sort-by=cpu
Rank nodes by CPU (or memory) usage so the hottest node floats to the top. Capacity-planning at a glance.
Examples
kubectl top node --sort-by=cpu
kubectl top node --sort-by=memory
Apply pipeline (23)
kubectl apply -f <file-or-dir>
Declaratively create or update resources from YAML / JSON. The recommended workflow.
⚠ Common pitfall: Pass `-` to read from stdin: `helm template ... | kubectl apply -f -`. Apply tracks fields via last-applied-configuration annotation — manual `kubectl edit` of those fields can confuse the next apply.
Imperatively create resources from YAML. Fails if the resource already exists.
⚠ Common pitfall: `create` is one-shot; `apply` is idempotent. For anything you re-run (CI/CD, git ops) use `apply`. Use `create` for things that must NOT silently update (Jobs).
Examples
kubectl create -f job.yaml
kubectl create -f - <<EOF
...
EOF
kubectl replace -f <file>
Replace a resource with the contents of a YAML — must exist already. --force triggers delete+recreate.
⚠ Common pitfall: `replace --force` causes a brief outage — pod is deleted, then recreated. Avoid for live traffic — use `apply` and rely on rolling update.
Examples
kubectl replace -f svc.yaml
kubectl replace --force -f pod.yaml
kubectl patch <resource> <name> -p '<json>'
Apply a partial update to a live resource without editing files. Strategic merge by default.
⚠ Common pitfall: Three merge types: --type=strategic (default, container-aware), --type=merge (RFC 7396), --type=json (RFC 6902 ops). Strategic only works for known core types — use merge for CRDs.
Examples
kubectl patch deployment web -p '{"spec":{"replicas":5}}'
kubectl patch pod web -p '{"metadata":{"labels":{"env":"prod"}}}'
kubectl patch deployment web --type=json -p='[{"op":"replace","path":"/spec/replicas","value":3}]'
kubectl edit <resource> <name>
Open a resource in $EDITOR; on save, the diff is applied. Quick & dirty — use with care.
⚠ Common pitfall: Edits do NOT update your git YAML — production drifts. For anything tracked in git, change the source and apply. Use edit only for quick experiments.
Examples
kubectl edit deployment web
KUBE_EDITOR="code -w" kubectl edit cm app-config
kubectl diff -f <file>
Preview what `apply` would change — server-side diff against the live state.
Examples
kubectl diff -f deployment.yaml
kubectl diff -k ./overlays/prod
kubectl label <resource> <name> KEY=VAL
Add, change, or remove (KEY-) a label on a resource. Used by selectors everywhere.
Examples
kubectl label pods web-7d5 env=prod
kubectl label pods web-7d5 env-
kubectl label nodes ip-10-0-1-23 disk=ssd
kubectl annotate <resource> <name> KEY=VAL
Add / change / remove (KEY-) an annotation. Free-form metadata, not used for selectors.
Examples
kubectl annotate pods web-7d5 owner=team-foo
kubectl annotate svc web service.beta.kubernetes.io/aws-load-balancer-type=nlb
kubectl delete -f <file>
Delete all resources defined in a YAML file or directory.
⚠ Common pitfall: `delete -f` of a namespace YAML deletes EVERYTHING in that namespace. Always `diff -f` before delete on prod paths.
Examples
kubectl delete -f deployment.yaml
kubectl delete -k ./overlays/staging
kubectl apply --server-side -f <file>
Apply using server-side apply — fields are owned by managers, conflicts are surfaced explicitly. Modern replacement for client-side apply.
⚠ Common pitfall: Conflicts (multiple managers touching the same field) abort the apply unless you pass --force-conflicts. Read the conflict report before forcing.
Pause / resume a rollout so multiple `set` / `patch` operations land as a single revision.
Examples
kubectl rollout pause deployment/web
kubectl set image deployment/web app=nginx:1.27 && kubectl set env deployment/web LOG=info && kubectl rollout resume deployment/web
kubectl set image deployment/<name> <ctr>=<img>
Update just the image of a container. Triggers a rolling update without editing YAML.
⚠ Common pitfall: `set image` modifies the live spec — drift from your git YAML. For tracked Deployments change the source and apply, not `set`.
Examples
kubectl set image deployment/web app=nginx:1.27
kubectl set image deploy/web app=myorg/app@sha256:abc123
kubectl rollout status deployment/<name> -w
Watch a rollout in real time until done. Exits non-zero on failure — perfect for CI gates.
Examples
kubectl rollout status deployment/web -w
kubectl apply -f deploy.yaml && kubectl rollout status deployment/web --timeout=3m
kubectl apply -f <file> --dry-run=server
Send the manifest to the API server for full validation (admission webhooks, defaulting) without persisting it.
⚠ Common pitfall: --dry-run=server catches admission/webhook rejections that --dry-run=client (local only) misses entirely. Use server-side in CI gates.
Apply a directory AND delete any live object with the matching label that is no longer in the files. GitOps-style sync.
⚠ Common pitfall: Prune is powerful and dangerous — a wrong selector can delete unrelated resources. Always `--dry-run=client` first and pin the label tightly.
Generate clean YAML from imperative flags without creating anything. The "imperative-to-declarative" bridge.
⚠ Common pitfall: This is the canonical way to scaffold YAML you do not remember by heart: `kubectl create deployment ... --dry-run=client -o yaml > deploy.yaml`, then edit.
Examples
kubectl create deployment web --image=nginx --dry-run=client -o yaml > deploy.yaml
kubectl create configmap c --from-literal=k=v --dry-run=client -o yaml
kubectl get <resource> <name> -o yaml --show-managed-fields
Reveal the managedFields block (hidden by default since 1.21) — see exactly which manager owns which field under server-side apply.
⚠ Common pitfall: When two controllers fight over a field, this block names the culprits. Pair with `kubectl apply --server-side --force-conflicts` to resolve.
Examples
kubectl get deployment web -o yaml --show-managed-fields
kubectl get deployment web -o jsonpath='{.metadata.managedFields[*].manager}'
kubectl delete <resource> --all -n <ns>
Delete every object of a kind in a namespace. e.g. clear all pods so controllers recreate them fresh.
⚠ Common pitfall: --all is namespace-scoped, NOT cluster-wide — but it still nukes everything of that kind in the namespace. Double-check `-n` before pressing enter.
Strip the stale last-applied-configuration annotation so a fresh client-side apply re-establishes field ownership cleanly.
⚠ Common pitfall: Useful when a resource was created with `create` (no annotation) then later `apply`-ed and behaves oddly on field deletion. Or migrate to server-side apply instead.
Examples
kubectl annotate deployment web kubectl.kubernetes.io/last-applied-configuration-
Pod cannot pull its image. `describe pod` and read Events — almost always typo in tag, missing imagePullSecret, or registry DNS issue.
⚠ Common pitfall: BackOff is exponential — looks idle but is retrying with growing intervals. After fixing the cause, `kubectl delete pod` to reset the backoff timer immediately.
Examples
kubectl describe pod web-7d5 | tail -20
kubectl get events --sort-by=.lastTimestamp -n default
Container starts then exits. `kubectl logs <pod> --previous` shows the actual error. Check Exit Code in describe.
⚠ Common pitfall: Exit codes: 0 = CMD ran to completion (your "server" is not a server), 1 = app threw, 137 = OOMKilled, 143 = SIGTERM not handled fast enough. Each implies a different fix.
Examples
kubectl logs web-7d5 --previous
kubectl describe pod web-7d5 | grep -A2 "Last State"
kubectl get pod web-7d5 -o jsonpath="{.status.containerStatuses[*].lastState}"
Evicted
Kubelet kicked the pod off the node — usually due to node pressure (disk full, memory pressure). Move to a healthier node and add requests/limits.
⚠ Common pitfall: Evicted pods pile up in `kubectl get pods` until cleaned — `kubectl delete pods --field-selector=status.phase=Failed` to bulk reap.
Examples
kubectl get pods --field-selector=status.phase=Failed -A
kubectl delete pods --field-selector=status.phase=Failed -A
137 = 128 + SIGKILL(9). Kernel OOM killer reaped the container. Either bump memory limit or fix the leak.
⚠ Common pitfall: Set requests.memory close to typical use, limits.memory at the ceiling you can afford. JVM apps need `-XX:MaxRAMPercentage` or they ignore limits and eventually OOM.
Examples
kubectl get pod web-7d5 -o jsonpath="{.status.containerStatuses[*].lastState.terminated.reason}"
kubectl describe pod web-7d5 | grep -A2 "Limits:"
kubectl top pod web-7d5 --containers
Pending (unschedulable)
No node can satisfy the pod's requests / nodeSelector / taints. `describe pod` shows `FailedScheduling` with the reason.
⚠ Common pitfall: Common reasons: insufficient cpu/memory, no node with the right label, taints not tolerated, no PV available for a PVC. Each needs a different fix.
Examples
kubectl describe pod web-7d5 | grep -A5 Events
kubectl get nodes -o custom-columns=NAME:.metadata.name,CPU:.status.allocatable.cpu,MEM:.status.allocatable.memory
kubectl get nodes --show-labels
Terminating (stuck)
Pod is stuck in Terminating forever — almost always a finalizer that nothing is processing. Force-delete is the escape hatch.
⚠ Common pitfall: `kubectl delete pod web --grace-period=0 --force` skips graceful shutdown — endpoints may leak briefly. The right long-term fix is removing the finalizer via `kubectl patch`.
Examples
kubectl delete pod web-7d5 --grace-period=0 --force
kubectl patch pod web-7d5 -p '{"metadata":{"finalizers":null}}' --type=merge
kubectl get pod web-7d5 -o yaml | grep finalizers -A3
Init:0/N (stuck)
A pod's init container is failing or never finishing. `kubectl logs <pod> -c <init-name>` to see why.
Examples
kubectl logs web-7d5 -c wait-for-db
kubectl describe pod web-7d5 | grep -A5 "Init Containers"
ErrImagePull / no such host
A registry DNS variant of ImagePullBackOff. Your cluster DNS cannot resolve the registry hostname.
⚠ Common pitfall: Check `kubectl run dnsutils --rm -it --image=busybox -- nslookup ghcr.io`. If it fails, your CoreDNS or upstream is broken. Private registries often need an in-cluster DNS hostAlias.
Examples
kubectl run dnsutils --rm -it --image=busybox -- nslookup ghcr.io
kubectl get pods -n kube-system -l k8s-app=kube-dns
CreateContainerConfigError
The container cannot start because a referenced ConfigMap/Secret key is missing. `describe pod` names the exact key.
⚠ Common pitfall: Different from ImagePullBackOff — the image pulled fine. It is a config wiring error: a `secretKeyRef`/`configMapKeyRef` points at a key that does not exist yet.
Examples
kubectl describe pod web-7d5 | grep -A3 Events
kubectl get secret db -o jsonpath='{.data}'
kubectl get cm app-config -o jsonpath='{.data}'
CreateContainerError
Kubelet failed to create the container — often a bad command, missing mount path, or a read-only root fs conflict.
⚠ Common pitfall: Read the message after the reason: "exec: no such file" = wrong command/entrypoint; "mkdir read-only file system" = the container tried to write where it cannot.
Examples
kubectl describe pod web-7d5 | grep -A2 "State:"
kubectl get pod web-7d5 -o jsonpath='{.status.containerStatuses[0].state.waiting.message}'
ContainerCreating (stuck)
Pod sits in ContainerCreating for minutes — usually a volume that will not mount, or an image still pulling.
⚠ Common pitfall: `FailedMount` in events = PVC not bound or a CSI driver issue. `FailedAttachVolume` on cloud = the EBS/PD volume is still attached to another (dead) node.
Examples
kubectl describe pod web-7d5 | grep -A5 Events
kubectl get pvc
kubectl get volumeattachment
exec format error
The container image was built for a different CPU architecture than the node (e.g. arm64 image on amd64 node).
⚠ Common pitfall: Classic on Apple Silicon — you build locally on arm64 and push to an amd64 cluster. Build multi-arch with `docker buildx build --platform linux/amd64,linux/arm64`.
Examples
kubectl logs web-7d5 --previous
kubectl get pod web-7d5 -o jsonpath='{.spec.nodeName}'
kubectl get node ip-10-0-1-23 -o jsonpath='{.status.nodeInfo.architecture}'
connection refused (probe failing)
Liveness/readiness probe keeps failing so the pod restarts or never gets traffic. The app is not listening on the probe port yet.
⚠ Common pitfall: Common cause: probe `port` does not match the actual listen port, or `initialDelaySeconds` is too short for a slow-booting app. Check the probe spec vs the real port.
Examples
kubectl describe pod web-7d5 | grep -A3 -i probe
kubectl get pod web-7d5 -o jsonpath='{.spec.containers[0].readinessProbe}'
A pod stays Pending because every candidate node has a taint the pod does not tolerate (e.g. a control-plane or GPU node).
⚠ Common pitfall: Add a matching `tolerations` block to the pod spec, or target untainted nodes. Control-plane nodes carry `node-role.kubernetes.io/control-plane:NoSchedule` by default.
Examples
kubectl describe pod web-7d5 | grep -A5 Events
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.taints}{"\n"}{end}'
error: unable to upgrade connection (exec/logs)
kubectl exec/logs/port-forward fails to open the streaming connection — usually the kubelet is unreachable from the API server.
⚠ Common pitfall: On managed clusters this often means a security-group/firewall blocks apiserver→kubelet (port 10250), or the node is NotReady. Check node status and the SG rules.
kubectl get pods -A --field-selector spec.nodeName=ip-10-0-1-23
NotReady (node)
A node reports NotReady — kubelet stopped posting status. Pods on it get marked Unknown then evicted after the toleration window.
⚠ Common pitfall: Common causes: kubelet crashed, disk/PID pressure, network partition, or the container runtime died. `describe node` Conditions and `journalctl -u kubelet` on the box tell the story.
Standard Deployment template with 3 replicas, rolling update strategy, probes, and resources.
⚠ Common pitfall: Missing readinessProbe + a slow-starting app = traffic hits the pod before it is ready = 502s on every rollout. Always add a real readinessProbe.
ClusterIP Service in front of a Deployment selected by label.
⚠ Common pitfall: targetPort can be a name (e.g. "http") matching a containerPort name — safer than a number when ports change between versions.
Examples
apiVersion: v1
kind: Service
metadata:
name: web
spec:
type: ClusterIP
selector: { app: web }
ports:
- name: http
port: 80
targetPort: 80
ConfigMap + envFrom usage
A ConfigMap plus a Deployment snippet showing how to inject all its keys as env vars.
⚠ Common pitfall: ConfigMap changes do NOT auto-restart pods. After editing, `kubectl rollout restart deployment/<name>` to pick up the new values.
Examples
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
LOG_LEVEL: info
DATABASE_HOST: db.local
---
# In your Deployment template.spec.containers[0]:
envFrom:
- configMapRef:
name: app-config
Ingress YAML (nginx class)
Ingress routing a host + path to a Service. Uses the nginx IngressClass.
⚠ Common pitfall: Without `ingressClassName: nginx` (or matching annotation) no controller picks it up — it sits there looking created but does nothing.
A CronJob skeleton with schedule, concurrency policy, history limits, and a single-container job template.
⚠ Common pitfall: Without `concurrencyPolicy: Forbid` a slow job can overlap with the next scheduled run. Without history limits, completed Jobs pile up forever.
A run-to-completion Job with parallelism, completions, a backoff limit, and an activeDeadline timeout.
⚠ Common pitfall: restartPolicy MUST be Never or OnFailure for a Job (Always is rejected). backoffLimit caps total retries before the Job is marked Failed.
An autoscaling/v2 HPA targeting CPU and memory utilization, with explicit min/max and a scale-down stabilization window.
⚠ Common pitfall: autoscaling/v2 (not v2beta2) is stable since 1.23. Multiple metrics mean the HPA scales on whichever demands the MOST replicas. Needs metrics-server.
A PVC requesting storage from a named StorageClass with an access mode. Mount it in a pod via volumes + volumeMounts.
⚠ Common pitfall: ReadWriteOnce binds to ONE node at a time — two pods on different nodes cannot share it. For shared access you need ReadWriteMany and a backing store that supports it (NFS, EFS, CephFS).
A default-deny-ingress policy plus an allow rule that only lets pods labeled role=frontend reach this app on port 8080.
⚠ Common pitfall: NetworkPolicies are additive (allow-only) and require a CNI that enforces them. An empty `podSelector: {}` with no ingress rules = deny ALL ingress to the namespace.
A ServiceAccount, a namespaced Role granting pod read access, and a RoleBinding wiring them together. Least-privilege starter.
⚠ Common pitfall: The RoleBinding subject `kind: ServiceAccount` needs the SA's namespace in `subjects[].namespace`, or the binding silently grants nothing.
Searchable kubectl cheat sheet covering the 100+ commands SREs and
platform engineers actually run on a real cluster — not the toy
"hello-minikube" list. Ten categories: cluster (cluster-info, get
nodes, top nodes, config use-context, version, api-resources),
pod (get pods, describe, logs -f, exec -it, port-forward, cp,
attach, delete, debug ephemeral container), workload (deployment
/ replicaset / daemonset / statefulset create, scale, rollout
status / history / undo / restart, autoscale, expose), service
& ingress (expose, get svc, endpoints, port-forward, ingress
class hint), config (configmap and secret create from-file /
from-literal, get, decode), RBAC (get sa, create role /
rolebinding / clusterrole / clusterrolebinding, auth can-i,
namespaces), monitoring (top pods, events --sort-by, wait
--for=condition), apply pipeline (apply, create, replace, patch
strategic / json / merge, edit, diff, kustomize, label, annotate),
pitfall fixes for the eight states that actually break your day
(ImagePullBackOff, ErrImagePull, CrashLoopBackOff, Evicted,
OOMKilled, Pending unschedulable, Terminating stuck, Init:0/N
stuck), and 5 ready-to-paste YAML templates (Pod, Deployment,
Service, ConfigMap, Ingress). Every entry shows full syntax,
bilingual EN/ZH description, the trap people actually hit
("--grace-period=0 leaves dangling endpoints", "exec defaults to
sh — alpine has no bash", "rollout restart is preferred over
delete pod", "kubectl apply -f - reads from stdin"), and one to
three copy-ready examples. Search filters across command +
description + pitfall + example simultaneously, category chips
scope the list, one-click copy on every command. Fully
client-side, no cluster access, no upload, no telemetry. Pair
with our Docker and Git Cheatsheets, and reach for kubectx /
kubens / k9s / helm / stern when the raw CLI feels heavy.
Tool details
Input
Files + Text
The page exposes text boxes, numeric controls, file pickers, or structured inputs depending on the tool.
Output
Live result + Copy + Preview
The result area focuses on usable output, with copy, download, or preview actions when supported.
Privacy
Browser-side processing
The main tool logic does not call an external API, so inputs normally stay in the current tab.
Save / share
No account required
Open the page and use it; whether results survive refresh depends on the tool.
Performance budget
Initial JS <= 30 KB
No WASM budget is declared, keeping the tool quick to open on mobile.
Best fit
Developer & DevOps · Developer
Category and role tags drive related tools, internal links, and quick fit checks.
How to use
1
1. Input
Paste or drop your content into the tool panel.
2
2. Process
Click the button. All processing is local in your browser.
3
3. Copy / Download
Copy the result or download to disk in one click.
How kubectl Cheatsheet fits into your work
Use it in the small gaps between coding, reviewing, debugging, and shipping.
Developer jobs
Formatting, validating, shrinking, or inspecting code-adjacent text.
Preparing snippets for documentation, tickets, commits, or handoff.
Checking a small payload quickly without switching tools.
Developer checks
Run irreversible transforms like minify or obfuscate on a copy.
Keep secrets out of pasted snippets unless the tool explicitly stays local.
Use your normal tests or linter before shipping transformed code.
Good next steps
These links move the current task into a more complete workflow.
A pod went CrashLoopBackOff at 2am and you need the exit code fast
On-call, no time to think. Search "137" to jump straight to the
OOMKilled entry, copy `kubectl logs <pod> --previous` to read the
last run before the crash, then copy `describe pod` to read the
Exit Code line. Three clicks, no man-page detour, and you know
whether to bump the memory limit or fix your CMD.
Onboarding a junior who has never touched a cluster
Filter to Pod and Workload, hand them the fifteen day-one
commands top to bottom: get pods, describe, logs -f, exec -it,
port-forward, rollout restart, rollout status. Each carries the
pitfall inline, so they learn "exec defaults to sh, alpine has no
bash" before they hit a 127 in front of the whole team.
Piping a Helm template straight into apply on a locked-down jump host
You cannot install helm on the bastion but you can render locally.
Grab the `apply -f -` entry, read the "reads from STDIN" note, and
run `helm template release ./chart | kubectl apply -f -`. The
cheat sheet confirms the dash means stdin so you do not waste a
round trip guessing whether kubectl wants a real file path.
Restarting a single-replica deployment without dropping to zero
A teammate is about to `kubectl delete pod` on a 1-replica
service in prod. Search "restart", copy `rollout restart
deployment/<name>`, and the entry explains why: delete briefly
hits 0 replicas and leaves no rollout history, while restart
honors maxUnavailable and keeps `rollout undo` available.
Common pitfalls
Running `kubectl logs <pod>` on a crashed pod shows the new container, not the crash; add `--previous` to see the run that actually failed.
Using `kubectl exec -it pod -- bash` on alpine or distroless returns exit 127; try `sh` first, or `kubectl debug` for images with no shell at all.
Forcing `delete pod --grace-period=0 --force` to unstick Terminating leaves dangling endpoints; fix the finalizer or stuck volume instead of force-killing.
Privacy
This cheat sheet is a single static page. Your search terms, the
commands you copy, and any YAML you read stay in the browser tab and
run against an in-memory array. Nothing touches your kubeconfig, no
cluster is contacted, and no search text enters the URL. Open DevTools
Network while you type and you will see zero requests, so it is safe
on air-gapped jump hosts and bastion-only clusters.
FAQ
Related tools
Hand-picked utilities that pair well with this one.