# kubectl Cheat Sheet — Debugging & Troubleshooting

> **Tool:** kubectl
> **Category:** Containers & Orchestration
> **Verified against:** kubectl v1.34.0 (client), flags verified via `kubectl <cmd> --help`, 2026-08-21
> **Official docs:** https://kubernetes.io/docs/reference/kubectl/

Events, resource usage, copying files, rollout status/rollback, and ephemeral debug containers — the toolkit for "why is this pod broken."

## Events

```bash
kubectl get events                                        # events in the current namespace
kubectl get events --sort-by='{.lastTimestamp}'            # oldest-to-newest, so the latest is at the bottom
kubectl get events --field-selector involvedObject.name=my-pod
kubectl get events --field-selector type=Warning           # only warnings/errors
```

`kubectl get events` is unsorted by default and truncates to the last hour by cluster policy in most setups — `--sort-by` and `--field-selector` are what make it actually useful instead of a wall of noise.

## Resource usage

```bash
kubectl top pod                             # CPU/memory for all pods in the current namespace
kubectl top pod --containers                # break down by container within each pod
kubectl top pod -l app=nginx
kubectl top node                            # CPU/memory for cluster nodes
```

`top` requires the metrics-server add-on running in the cluster — if it returns "error: Metrics API not available," that's a cluster config gap, not a typo in your command.

## Copying files to/from a pod

```bash
kubectl cp ./local-file.txt my-namespace/my-pod:/tmp/local-file.txt
kubectl cp my-namespace/my-pod:/var/log/app.log ./app.log
```

`kubectl cp` requires `tar` to exist inside the target container's image — a distroless or scratch-based image will fail silently-ish with a tar-not-found error. `kubectl exec ... -- tar | tar` (piping through exec directly) is the fallback when the image has no tar binary.

## Rollout status and rollback

```bash
kubectl rollout status deployment/my-deployment            # watch a rollout until it completes or fails
kubectl rollout history deployment/my-deployment            # list revisions
kubectl rollout history deployment/my-deployment --revision=3   # what changed in a specific revision
kubectl rollout undo deployment/my-deployment                # roll back to the previous revision
kubectl rollout undo deployment/my-deployment --to-revision=3
```

## Ephemeral debug containers

```bash
kubectl debug my-pod -it --image=busybox                        # attach a debug container to a running pod
kubectl debug my-pod -it --image=busybox --copy-to=my-pod-debug  # debug on a copy instead of the live pod
kubectl debug node/my-node -it --image=busybox                   # debug a node directly
```

`kubectl debug` solves the distroless-image problem from a different angle than `cp`/`exec`: instead of needing shell/tar tools already inside the target container, it attaches a *separate* debug container (with whatever tools you choose) sharing the same pod/process namespace — the standard way to inspect a minimal production image without rebuilding it with debug tools baked in.

## Discovering what resources exist

```bash
kubectl api-resources                                    # every resource kind the API server supports, with short names
kubectl api-resources --namespaced=true                   # namespaced kinds only
kubectl api-resources --api-group=rbac.authorization.k8s.io   # scoped to one API group
kubectl api-resources -o wide                              # + which verbs (get/list/watch/...) each kind supports

kubectl api-versions                                       # every group/version the server has enabled, e.g. apps/v1
```

`api-resources` is the fastest way to find a resource's short name (`kubectl get po` instead of `pods`) or confirm a CRD actually registered — if `kubectl get <thing>` errors with "the server doesn't have a resource type," check it against `api-resources` before assuming a typo.
