Skip to main content

Frequently Used kubectl Commands

· 6 min read

Working with Kubernetes clusters day to day, almost everything goes through kubectl. The commands themselves aren't hard — the hard part is remembering them when you actually need them, especially the low-frequency but critical ones like node maintenance and force deletion. This post organizes the commands I use most, grouped by scenario, so I can come back and look them up whenever I forget.

Every kubectl operation is essentially a REST request to kube-apiserver: viewing is a GET, applying a config is a declarative update of desired state, and deleting removes the object from etcd, after which the controllers converge the actual state. Once you understand this, the behavior of most commands becomes easy to explain.

Start with the basics. When you're not sure how to write a flag, the help output is always the first place to check:

# Show help; also works for subcommands, e.g. kubectl get --help
kubectl --help

Inspecting the Cluster and Nodes

# List cluster nodes and their status (Ready / NotReady)
kubectl get nodes

# Show detailed node information: pods on the node and hardware resource usage
# Commonly used when diagnosing insufficient node resources or unschedulable Pods
kubectl describe node <node-name>

In the describe node output, the Conditions, Allocated resources, and Events sections carry the most information — check those first when a node is misbehaving.

Inspecting Namespaces and Pods

Kubernetes uses namespaces for resource isolation. Most query commands need -n to specify a namespace; without it, they default to default:

# List namespaces
kubectl get namespace

# List pods in a given namespace
kubectl get pod -n <namespace>

# List pods across all namespaces; -A is short for --all-namespaces
kubectl get pods -A

# List pods across all namespaces (the full flag is --all-namespaces)
kubectl get pod --all-namespace

Once you've located a specific Pod, troubleshooting mainly relies on two commands — describe for events, logs for output:

# Show detailed information about one or more resource objects
# Scheduling failures, image pull failures, etc. all show up under Events
kubectl describe

# Print the logs of a container in a pod
# Multi-container Pods need -c to specify the container name
kubectl logs

A rule of thumb: if a Pod won't start, describe it first and read the events; if it starts but misbehaves, then check the logs. Doing it the other way around often wastes half your time.

Creating and Deleting Resources

kubectl manages resources in two styles: create is imperative — you tell the cluster exactly what to create; apply is declarative — you submit the desired state described in a yaml file, and existing resources get incrementally updated. For day-to-day config maintenance, apply is the way to go, since the same file can be run repeatedly.

# Create a resource object from a yaml/json file or stdin
kubectl create

# Apply a pod config file to set up resources; if already applied, does an incremental update
kubectl apply -f <pod.yaml>

# Un-apply a pod config file, deleting its resources
kubectl delete -f <pod.yaml>

# Delete a Deployment in a given namespace
# Note: deleting a Deployment cascades to the ReplicaSets and Pods it manages
kubectl delete Deployments -n <namespace> <deployment-name>

A few commands for bulk cleanup and force deletion, in increasing order of destructiveness:

# Force-delete a pod stuck in Terminating
# --grace-period=0 skips the graceful termination wait
kubectl delete pod <podname> -n <namespace> --force --grace-period=0

# Delete all pods in a namespace
# Pods managed by controllers like Deployments will be recreated automatically
kubectl delete --all pods --namespace=<namespace>

# Delete the namespace itself; everything in it is cascade-deleted
kubectl delete ns <namespace>

There are also two modification commands, for labeling resources and making ad-hoc config changes:

# Set resource labels; labels are how Services select backends and how node affinity scheduling works
kubectl label

# Edit a server-side resource object in the default editor; saving takes effect immediately
kubectl edit

edit is handy for emergency debugging, but the change is not synced back to your local yaml file. Remember to fold the change back into your config file afterward, or the next apply will overwrite it.

Node Maintenance

The standard procedure for taking a node offline for maintenance (kernel upgrades, hardware swaps) is cordon first, then drain: cordon only marks the node unschedulable, leaving existing Pods untouched; drain goes further and evicts the Pods on the node, letting controllers recreate them elsewhere.

# Cordon a node: mark it unschedulable so new Pods stop landing on it
kubectl cordon <node-name>

# Evict pods from a node
kubectl drain

# Evict all pods on the node
# --ignore-daemonsets: skip Pods managed by DaemonSets (they run one per node and would be recreated anyway)
# --delete-local-data: also delete Pods using emptyDir local data
kubectl drain <node-name> --delete-local-data --force --ignore-daemonsets

# After maintenance is done, remove the node from the cluster
kubectl delete nodes <node-name>

Exporting Resource Configs

When a resource has been modified by hand in production and you want to capture its current state as a yaml file, use -o yaml with a redirect:

# Export an existing pod's yaml config to a file
kubectl get deployment -n <namespace> <pod-name> -o yaml > <filename>.yaml

The exported yaml carries cluster runtime fields like status, resourceVersion, and uid. Strip those out before applying it elsewhere — keep only the spec-related parts.

Pitfalls and Caveats

  1. --all-namespace is easy to misremember — the full flag is --all-namespaces (with an s). In daily use, just stick with the -A shorthand.

  2. --force --grace-period=0 only makes the API Server remove the object immediately; the container process may not actually have exited. Use with caution on stateful services — you could end up with two copies of the same instance running in a split-brain fashion.

  3. Deleting a namespace is a cascade operation: all Deployments, Services, and ConfigMaps inside it disappear together. Run kubectl get all -n <namespace> first to confirm what's still in there.

  4. Without --ignore-daemonsets, drain errors out and aborts the moment it hits a DaemonSet-managed Pod. Also, --delete-local-data has been renamed to --delete-emptydir-data in newer versions — if the old flag errors, switch to the new name.

warning

drain really does evict workload Pods. Before running it in production, confirm you have enough replicas and spare capacity on other nodes, so service capacity doesn't drop off a cliff.

Wrapping Up

This list covers four high-frequency scenarios: inspecting, creating and deleting, node maintenance, and config export. It's fine not to memorize every command — two workflows are enough to remember: for troubleshooting, go get → describe → logs; for taking a node offline, go cordon → drain → delete node. For everything else, --help is always there.

COMMENTS