When you first meet Kubernetes, you quickly notice you do almost everything with a single tool: kubectl. So how does kubectl work, how does the command you type reach the cluster, and which kubectl commands do you actually need day to day? In this post we look behind the curtain first, then collect the useful commands in tables. If you're completely new to Kubernetes, we suggest reading our What is Kubernetes post first.
What Is kubectl?
kubectl is the official command-line tool for managing Kubernetes clusters. Listing pods, deploying apps, reading logs, getting a shell inside a pod, scaling... it's all done with kubectl. The community still hasn't agreed on how to pronounce it; some say "kube-control", some "kube-c-t-l", some even "kube-cuttle". Whichever you pick, everyone gets it.
How Does kubectl Work?
An important detail: kubectl doesn't connect to the cluster's servers directly. The only thing it does is talk to the Kubernetes API server (kube-apiserver) over HTTPS. When you type a command, roughly this happens behind the scenes:
- kubeconfig is read: kubectl learns which cluster to connect to, and as which user, from
~/.kube/config. - The request is built: A command like
kubectl get podsis turned into a REST request to the API server (e.g.GET /api/v1/namespaces/default/pods). - Authentication: The API server checks who you are with a certificate or token.
- Authorization (RBAC): It checks whether you're allowed to do this.
- Storage: For requests that change something (apply, scale, delete), the new "desired state" is written to etcd, the cluster's database.
- Execution: The scheduler places new pods on suitable nodes, controllers reconcile desired and actual state, and the kubelet on each node starts the containers.
So kubectl is really a smart API client. Knowing this also answers questions like "why did the command finish instantly but the pod is still Pending?": kubectl hands off the request and returns, while the real work continues in the background.
-v=6 to any command to see which requests kubectl sends to the API server. Really useful for learning.The kubeconfig File and Contexts
A kubeconfig file has three main sections:
- clusters: the API server address and certificate,
- users: credentials (certificates, tokens, etc.),
- contexts: a pairing of "connect to this cluster, as this user, in this namespace".
If you work with more than one cluster (e.g. test and prod), you switch between contexts:
kubectl config get-contexts # list defined contexts
kubectl config current-context # which context you're in now
kubectl config use-context prod-cluster # switch to another cluster
kubectl config set-context --current --namespace=myapp # change the default namespace
Running a command in the wrong context on prod is unfortunatly one of the most common mistakes. Make checking current-context a habit before you type.
Installing kubectl
kubectl runs on macOS, Linux and Windows. On macOS use brew install kubectl, on Linux use the official package repository or download the single binary, and on Windows use winget/choco. To check the install:
kubectl version --client
It's recommended that your kubectl version is within one minor version of your cluster.
kubectl Command Structure
Almost every command follows the same pattern:
kubectl [command] [resource-type] [name] [flags]
# example:
kubectl get pods web-7d4b9 -n myapp -o wide
Here get is the command, pods the resource type, web-7d4b9 the resource name, and -n and -o are flags.
The Most Used kubectl Commands
Getting Information
| Command | What it does |
|---|---|
kubectl get pods | Lists pods (-A for all namespaces) |
kubectl get all | Shows the core resources in a namespace together |
kubectl describe pod <name> | Shows a resource's details and recent events; the first stop when debugging |
kubectl logs <pod> | Shows container logs (-f to follow, --previous for the crashed container) |
kubectl get events --sort-by=.lastTimestamp | Lists recent cluster events in order |
kubectl top pods / top nodes | Shows CPU and RAM usage (needs metrics-server) |
Creating and Updating
| Command | What it does |
|---|---|
kubectl apply -f app.yaml | Creates or updates the resources in a YAML file (the most used) |
kubectl create deployment web --image=nginx | Quickly creates a deployment |
kubectl edit deploy/web | Opens the resource in an editor for live editing |
kubectl patch deploy/web -p '{...}' | Changes only specific fields of a resource |
kubectl set image deploy/web web=nginx:1.27 | Updates the container image |
kubectl scale deploy/web --replicas=5 | Changes the number of replicas |
Deleting
| Command | What it does |
|---|---|
kubectl delete -f app.yaml | Deletes the resources defined in the YAML |
kubectl delete pod <name> | Deletes a pod; if it belongs to a deployment, a new one replaces it |
kubectl delete deploy/web | Deletes the deployment and its pods |
Debugging
| Command | What it does |
|---|---|
kubectl exec -it <pod> -- sh | Opens a shell inside a running container |
kubectl port-forward svc/web 8080:80 | Forwards the service to port 8080 on your machine |
kubectl cp <pod>:/path ./local | Copies files between a pod and your machine |
kubectl debug -it <pod> --image=busybox | Attaches a temporary debug container to a pod |
Rollout Management
| Command | What it does |
|---|---|
kubectl rollout status deploy/web | Follows the progress of an update |
kubectl rollout history deploy/web | Lists previous revisions |
kubectl rollout undo deploy/web | Rolls back to the previous revision |
kubectl rollout restart deploy/web | Restarts pods one by one (no downtime) |
Output Formats
| Flag | What you get |
|---|---|
-o wide | Extra columns (node name, IP, etc.) |
-o yaml / -o json | The full resource definition |
-o name | Just resource names (handy in scripts) |
-o jsonpath='{.items[*].metadata.name}' | Picks out exactly the fields you want |
-w | Watches changes live |
Resource Short Names
Instead of typing long names every time, you can use short names:
| Resource | Short name | Resource | Short name |
|---|---|---|---|
| pods | po | configmaps | cm |
| services | svc | ingresses | ing |
| deployments | deploy | persistentvolumeclaims | pvc |
| namespaces | ns | nodes | no |
Imperative or Declarative?
There are two ways to work with kubectl: telling it directly "do this" with a command (imperative), or saying "this is how it should be" in YAML and running apply (declarative).
| Imperative (commands) | Declarative (YAML + apply) | |
|---|---|---|
| Example | kubectl create deployment, kubectl scale | kubectl apply -f app.yaml |
| Speed | Very fast for one-off tasks | Takes a bit longer to write at first |
| Repeatability | Low, what was done isn't recorded | High, the file tells the whole story |
| Git / CI/CD fit | Weak | Excellent (the basis of GitOps) |
| When? | Testing, experiments, emergency fixes | Production and team work |
The Difference Between apply, create and replace
| Command | If the resource doesn't exist | If it exists | When to use |
|---|---|---|---|
kubectl create | Creates it | Errors out | Resources created once |
kubectl apply | Creates it | Updates by merging the differences | Daily use, GitOps |
kubectl replace | Errors out | Replaces the whole resource with the new one | When you deliberately want to overwrite the full definition |
A Few Tips That Make Life Easier
- Set an alias: With
alias k=kubectlyou type 1 letter instead of 7 every time. - Autocompletion:
source <(kubectl completion bash)(orcompletion zsh) lets you Tab-complete resource names. - Don't write YAML from scratch:
kubectl create deployment web --image=nginx --dry-run=client -o yaml > web.yamlgives you a ready template. - Learn what fields do:
kubectl explain deployment.spec.strategylets you read the docs for any field right in your terminal. - Filter with labels:
kubectl get pods -l app=webreturns only pods with that label.
A Ready Cluster to Try kubectl
Reading these commands is one thing, trying them is another. If you don't want to set up a cluster on your own machine, VECDC Kubernetes Server packages come with Kubernetes pre-installed, start at $6/month, and thanks to automated setup your kubeconfig lands in your inbox in about 5 minutes. Save it as ~/.kube/config and you can try every command in this post right away. If you need a multi-node setup for production, our Kubernetes consulting team can help.
Frequently Asked Questions
What's the difference between kubectl and kubeadm?
kubeadm is used to set up a Kubernetes cluster (bootstrapping the control plane, joining nodes). kubectl is the client tool for managing a running cluster: listing pods, deploying, reading logs and so on.
Where does the kubeconfig file live?
By default it's ~/.kube/config in your home directory. To use a different file, set the KUBECONFIG environment variable or use the --kubeconfig flag.
Should I use kubectl apply or kubectl create?
kubectl apply is recommended for daily use and production: it creates the resource if it doesn't exist and updates it by merging differences if it does, which fits managing YAML files in Git. create errors out if the resource already exists.
How do I avoid running commands on the wrong cluster?
Check which cluster you're on with kubectl config current-context before running commands, use separate contexts and namespaces for prod and test, and use a shell prompt that shows the active context to greatly reduce this mistake.
In Short
kubectl is a command-line tool that sends requests to the Kubernetes API server using the details in your kubeconfig. The cluster does the real work; kubectl just passes on what you want. Bookmark the tables in this post, they cover most of the day to day work. If you get stuck anywhere, drop us a message, were glad to help.