Verified11 commandsAI-assisted

Core Resources

.md

Verified against kubectl v1.34.0 (client), flags verified via `kubectl <cmd> --help`, 2026-08-21 · official docs

Getting, describing, creating, and deleting the resources you touch every day — pods, deployments, services — plus applying manifests.

Listing resources#

kubectl get pods
kubectl get pods -o wide                       # + node, IP, and readiness columns
kubectl get pods -n my-namespace
kubectl get pods --all-namespaces
kubectl get deployments,services                # multiple resource types in one call
kubectl get pods -l app=nginx                    # filter by label selector
kubectl get pods -w                              # watch for changes live

Inspecting a resource in detail#

kubectl describe pod my-pod
kubectl describe deployment my-deployment
kubectl get pod my-pod -o yaml                  # full resource manifest as YAML
kubectl get pod my-pod -o json                  # full resource manifest as JSON

describe includes recent Events for the resource — often the fastest way to see why a pod is stuck (ImagePullBackOff, failed readiness probe, insufficient node resources) without a separate get events call.

Applying and creating resources#

kubectl apply -f deployment.yaml                # create or update to match the file (idempotent)
kubectl apply -f ./manifests/                   # apply every manifest in a directory
kubectl create -f pod.yaml                      # create only — fails if it already exists
kubectl create deployment my-app --image=nginx:1.27

apply is the standard for anything you'll re-run (it diffs against the last-applied state and only changes what differs); create is a one-shot, fails on a resource that already exists. Prefer apply for anything under version control.

Deleting resources#

kubectl delete pod my-pod
kubectl delete -f deployment.yaml
kubectl delete pods -l app=nginx                # delete everything matching a label
kubectl delete pod my-pod --grace-period=0 --force   # skip graceful termination (last resort)

Logs and exec#

kubectl logs my-pod
kubectl logs my-pod -c my-container             # a specific container in a multi-container pod
kubectl logs my-pod -f                          # stream/follow
kubectl logs deployment/my-deployment --all-pods=true
kubectl exec my-pod -- date                     # run a one-off command
kubectl exec -it my-pod -- /bin/bash            # interactive shell

-it (interactive + tty) is what makes exec behave like a real shell session instead of a single non-interactive command — forgetting it against a shell command leaves you unable to type.

Editing and scaling#

kubectl edit deployment my-deployment           # opens the live resource in $EDITOR
kubectl scale deployment my-deployment --replicas=5
kubectl set image deployment/my-deployment my-container=myrepo/app:v2   # roll a new image without editing YAML

Autoscaling a workload (HPA)#

kubectl autoscale deployment my-deployment --min=2 --max=10 --cpu-percent=70
kubectl get hpa                                 # list HorizontalPodAutoscalers and their current/target metrics
kubectl describe hpa my-deployment
kubectl delete hpa my-deployment

kubectl autoscale tries the autoscaling/v2 API first (CPU + memory + custom metrics) and falls back to v1 (CPU only) if the cluster doesn't support it — --cpu-percent alone always works, memory-based targets need v2. autoscale also works against a ReplicaSet or ReplicationController, not just a Deployment.

StatefulSets, DaemonSets, Jobs, and CronJobs#

kubectl get statefulsets
kubectl get daemonsets
kubectl scale statefulset my-db --replicas=3               # StatefulSets scale like Deployments...
kubectl rollout status statefulset/my-db                   # ...and support the same rollout commands
kubectl rollout restart daemonset/my-agent                  # roll every node's pod without a manifest change

kubectl create job my-job --image=busybox -- date            # one-off Job
kubectl create job my-job-from-cj --from=cronjob/my-cronjob   # run a CronJob's Job definition immediately, on demand
kubectl create cronjob my-cronjob --image=busybox --schedule="*/5 * * * *" -- date
kubectl get cronjobs
kubectl get jobs --field-selector status.successful=1        # completed Jobs only

There's no kubectl create statefulset/kubectl create daemonset shortcut the way there is for deployment/job/cronjob — StatefulSets and DaemonSets are manifest-only resources, created with kubectl apply -f (they need a volumeClaimTemplates/spec.selector shape that doesn't map cleanly onto CLI flags). Once created, though, get/describe/scale/rollout all work on them exactly like Deployments since they're all generic resource kinds.

Kustomize overlays#

kubectl apply -k ./overlays/production/       # build and apply a kustomization directory
kubectl kustomize ./overlays/production/       # render the final manifest to stdout without applying
kubectl diff -k ./overlays/production/         # preview what apply -k would change

apply -k is for a kustomization.yaml-based directory (patches/overlays layered on a base) — it can't be combined with -f or -R in the same call. kubectl kustomize (no apply) is the equivalent of a dry-run render, useful for reviewing the generated manifest in a PR before it ever touches the cluster.

Diffing before you apply#

kubectl diff -f deployment.yaml                 # unified diff between the live object and what apply would produce
kubectl diff -f ./manifests/

kubectl diff shells out to the system diff (or KUBECTL_EXTERNAL_DIFF if set, e.g. colordiff) and exits 1 if there are differences, 0 if none — script it into a CI gate the same way you'd use terraform plan's exit code.

Labels and annotations#

kubectl label pods my-pod tier=frontend                       # add a label
kubectl label pods my-pod tier=backend --overwrite             # change an existing label (fails without --overwrite)
kubectl label pods my-pod tier-                                 # remove a label (trailing "-")
kubectl label pods -l app=nginx --all env=prod                  # label everything matching a selector

kubectl annotate pods my-pod description="handles checkout"     # annotations can hold longer/structured values
kubectl annotate pods my-pod description-                       # remove an annotation (no --overwrite needed)

Labels are for selection (used by selectors on Services, Deployments, -l filters) and are capped at 63 characters; annotations are for arbitrary metadata (build SHAs, owner contacts, tool-specific config) that nothing selects on. Reach for a label only if something will actually query on it.