On this page
In the previous lessons you connected kubectl to a cluster and used it to look at nodes. Now you will learn the everyday commands that work on every kind of Kubernetes object, from Pods to Deployments to Services.
Think of kubectl as a Swiss Army knife. A handful of blades (get, describe, apply, delete, logs and exec) cover most of your work, and each one behaves the same way whatever the object type.
Learn them once and every later lesson gets easier, because you will already know how to create, inspect, debug and clean up whatever you build.
What you will learn
- How kubectl commands are built and how they map to the Kubernetes API
- How to work with namespaces, and save a default namespace in a context
- How to view, create, update, label and delete objects
- How to debug workloads with logs, exec, port-forward, events and top
- How to take a node out of service safely with cordon, drain and uncordon
How kubectl commands work
Everything is an API object
Everything in Kubernetes is a RESTful resource, also called a Kubernetes object. Each object lives at its own HTTP path on the API server.
For example, a Pod named my-pod in the default namespace lives at /api/v1/namespaces/default/pods/my-pod. When you run a kubectl command, kubectl makes HTTP requests to paths like this for you.
Raise the log level with -v=6 to watch it happen:
Among the log lines you will see the GET request kubectl sent to /api/v1/namespaces/default/pods/my-pod and the 200 OK it got back, followed by the normal table.
The shape of a command
Most kubectl commands follow the same pattern:
| Part | Examples |
|---|---|
| verb | get, describe, apply, delete, logs, exec |
| type | pods (or pod, po), deployments (deploy), services (svc), nodes (no) |
| name | my-pod. Leave it out to act on every object of that type |
| flags | -n dev, -o yaml, --watch |
Run kubectl api-resources to see every type your cluster knows, with its short name.
Namespaces
Namespaces are like folders inside your cluster. They group objects into logical sets, for example one per team or one per environment (dev, staging, production).
kubectl works in the default namespace unless you say otherwise. Target another namespace with --namespace, or its short form -n:
To see objects in every namespace at once, use --all-namespaces, or its short form -A:
Namespaces are objects too, so you create and list them with the same verbs:
Contexts: save your default namespace
Typing -n mystuff on every command gets tedious. A context remembers the cluster, the user and the default namespace for you. Contexts live in your kubeconfig file, usually $HOME/.kube/config.
The kubeconfig lesson covers contexts in depth. Here you only need two moves. The quickest is to change the default namespace of the context you are using right now:
Or create a separate context for that namespace and switch to it. A new context needs a cluster and a user too, so copy their names from kubectl config get-contexts:
From now on every command targets mystuff by default, with no -n needed.
kubectl config set-context my-context --namespace=mystuff on its own creates a context with only a namespace. Switch to it and kubectl no longer knows which cluster to call, so you get errors like The connection to the server localhost:8080 was refused. Use --current, or pass --cluster and --user.Viewing objects
List and get
kubectl get lists objects. Give it a type to list all of them in the current namespace, or a type and a name for one object:
Choose the output format
The -o flag changes what get prints. The default is a short table.
| Flag | What you get |
|---|---|
-o wide | The table plus extra columns, such as the Pod IP and node |
-o yaml | The full object definition in YAML |
-o json | The full object definition in JSON |
-o jsonpath='{...}' | Only the fields you pick |
--no-headers | The table without its header row, handy when you pipe the output into other commands |
JSONPath pulls out a single field. This prints only the Pod's IP address:
Expected output (your IP will differ):
Describe, explain and watch
kubectl describe prints a detailed, human-readable view of one object, including its recent events. It is usually the first command to run when something looks wrong:
kubectl explain documents the fields a resource type supports, straight from your cluster's API. Add a field path to drill down:
--watch (or -w) keeps the command running and prints a new line every time the object changes. Press Ctrl+C to stop:
Creating, updating and deleting objects
Declarative and imperative
Kubernetes encourages a declarative approach: you describe the desired state in a YAML file, and Kubernetes works out how to get there.
kubectl apply is the main tool for this. It creates objects that do not exist yet and updates the ones that do, so you can run it again and again with the same file.
Imperative commands such as kubectl create only create. They fail if the object already exists.
kubectl apply. The files then always describe what is running, and anyone can recreate the setup from them.Preview before you change
Add --dry-run=client to see what apply would do without sending any change to the cluster:
--dry-run=server goes one step further: the API server fully validates the request but still saves nothing. kubectl diff shows exactly which fields would change on the live object:
Edit a live object
kubectl edit opens the live object in your default editor (set by KUBE_EDITOR or EDITOR). Saving and closing the file applies the change:
Changes made this way are not in your YAML files, so the next apply of a file can undo them. Use edit for quick experiments, not as your normal workflow.
View the last applied configuration
Every kubectl apply saves the configuration you sent in an annotation on the object (kubectl.kubernetes.io/last-applied-configuration). Read it back with apply view-last-applied:
Delete objects
Delete an object with the same file that created it, or by type and name:
kubectl delete does not ask for confirmation. The object is gone as soon as you press Enter, and deleting a namespace deletes everything inside it. Check your context with kubectl config current-context first, and add --interactive (-i) if you want kubectl to ask before it deletes.Labels and annotations
Labels are key-value pairs that identify objects so you can select them, for example env=demo or app=web.
Annotations are key-value pairs too, but they hold non-identifying metadata such as build information or a contact address. You can add, change and remove both from the command line.
| Labels | Annotations | |
|---|---|---|
| Purpose | Identify and group objects | Attach extra information |
| Used to select objects | Yes, with -l | No |
| Example | color=red | description="my test pod" |
Labels pay off when you filter by them with -l (short for --selector). --show-labels adds a LABELS column to the table:
Debugging commands
Read logs
When a container keeps crashing, add --previous to read the logs of the run before the last restart.
Run commands inside a container
kubectl exec runs a command in a running container. With -it you get an interactive shell. Everything after -- is the command to run:
Small images often have no bash. Use sh instead: kubectl exec -it my-pod -- sh.
kubectl attach connects your terminal to the container's main process instead of starting a new one:
Copy files
kubectl cp needs the tar binary inside the container, so it does not work with every minimal image.
Forward a port
kubectl port-forward opens a tunnel from a port on your machine to a Pod or a Service, so you can test it without exposing it publicly. Here local port 8080 goes to port 80:
Watch cluster events
Events are not listed in time order by default. Add --sort-by=.metadata.creationTimestamp to read them oldest first. The cluster keeps events for about one hour.
Check resource usage
kubectl top needs metrics-server. Without it you get error: Metrics API not available. On minikube, run minikube addons enable metrics-server; many managed clusters install it for you.Cluster management: cordon, drain and uncordon
Sometimes you need to take a node out of service for maintenance, repairs or an upgrade. Three commands handle the whole cycle:
| Command | What it does |
|---|---|
kubectl cordon | Marks the node unschedulable. No new Pods land on it, but existing Pods keep running. |
kubectl drain | Cordons the node, then evicts its Pods so their controllers recreate them on other healthy nodes. Use it before maintenance or before removing a machine. |
kubectl uncordon | Makes the node schedulable again once the maintenance is done. |
Without --ignore-daemonsets, drain stops with an error on almost every node, because DaemonSet Pods such as kube-proxy belong on every node and cannot be moved. --delete-emptydir-data confirms you accept losing data in emptyDir volumes.
Drain also refuses to evict bare Pods that no controller manages, because nothing would recreate them. --force evicts them anyway, and they are gone for good.
Working faster
Command autocompletion
Tab completion fills in commands, flags and even object names from your cluster. For bash, install the bash-completion package first:
Activate kubectl completion for your current terminal session:
Make it permanent by adding it to your shell profile:
macOS and many Linux setups use zsh by default. zsh needs no extra package:
If zsh reports command not found: compdef, add autoload -Uz compinit && compinit near the top of ~/.zshrc.
Getting help
Hands-on: a complete workflow
Now put it all together: create a namespace and a context, run a Pod, label it, inspect it, debug it and clean up.
Step 1 — Create a namespace and a context
Create a demo namespace and a context that defaults to it. Replace minikube with your own cluster and user names from kubectl config get-contexts (for kind they are kind-kind):
Step 2 — Write a Pod manifest
Save this as nginx-pod.yaml:
The image is pinned to nginx:1.27 rather than latest, so the Pod behaves the same every time you run it.
Step 3 — Create the Pod
Expected output:
Step 4 — Verify the Pod is running
Expected output:
If STATUS shows ContainerCreating, the image is still downloading. Add --watch and wait for Running.
Step 5 — Add a label and filter by it
Expected output:
Step 6 — Inspect the Pod
Check the Events at the bottom. You should see the Pod being scheduled, the image being pulled and the container being started.
Step 7 — Read the logs
nginx prints its startup messages here, and later one line per request it serves.
Step 8 — Open a shell inside the container
Look around, for example with ls /usr/share/nginx/html, then type exit to leave the shell.
Step 9 — Forward a port and test it
Open http://localhost:8080 in your browser. You should see the nginx welcome page. Press Ctrl+C to stop forwarding, then run kubectl logs nginx again to see your request in the log.
apply, get, label, describe, logs, exec and port-forward work the same way for every object you will meet in later lessons.Step 10 — Clean up
Further reading
- kubectl Reference Documentation
- kubectl Quick Reference (cheat sheet)
- Namespaces
- Organizing Cluster Access Using kubeconfig Files
- Debug Applications
Summary
A small set of kubectl commands works on every Kubernetes object. Learn the pattern once (kubectl <verb> <type> <name> <flags>) and you can manage anything in the cluster.
- Namespaces group objects. Use
-nto target one namespace and-Ato see all of them. - Contexts save your default namespace, cluster and user;
kubectl config set-context --current --namespace=<ns>is the quick way. kubectl getlists objects,describeshows details andexplaindocuments fields;-o wide,-o yamland-o jsonpathshape the output.kubectl apply -fcreates or updates objects declaratively; preview with--dry-runorkubectl diff.kubectl deleteremoves objects without asking, so check your context first.kubectl labelandkubectl annotateattach metadata, and-lselects objects by label.- For debugging,
logs,exec,port-forward,get eventsandtopare your best friends. - For maintenance,
cordon,drainanduncordontake nodes out of service and back safely. - Tab completion saves a lot of typing.
With these commands in hand, the next lessons can focus on the objects themselves: Pods, Deployments and Services.