kubectl — The Control Plane CLI
kubectl (pronounced "kube-control" or "kube-cuddle") is the official command-line interface for interacting with a Kubernetes cluster. Every operation you perform — creating workloads, inspecting logs, rolling back deployments — goes through kubectl, which translates your commands into API calls to the Kubernetes API server.
Based on kubernetes.io/docs/reference/kubectl/.
Installation & kubeconfig
Install kubectl with your package manager or download the binary directly:
# macOS (Homebrew)
brew install kubectl
# Linux — latest stable
curl -LO "https://dl.k8s.io/release/$(curl -Ls https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin/
# Windows (winget)
winget install Kubernetes.kubectl
kubectl reads cluster connection details from a file called
kubeconfig, found by default at
~/.kube/config. You can override this with the
KUBECONFIG environment variable or the
--kubeconfig flag.
The kubeconfig file contains three sections:
| Section | What it stores |
|---|---|
clusters |
API server URL and TLS certificate authority for each cluster |
users |
Credentials (client cert, token, or exec plugin) per user |
contexts |
Named binding of a cluster + user + default namespace |
Contexts & Clusters
A context is a shortcut that binds a cluster, a user, and a default namespace. Switching contexts lets you point kubectl at a different cluster without retyping credentials.
# list all contexts
kubectl config get-contexts
# show current context
kubectl config current-context
# switch to a different context
kubectl config use-context my-prod-cluster
# set a default namespace for the current context
kubectl config set-context --current --namespace=payments
# merge two kubeconfig files into one
KUBECONFIG=~/.kube/config:~/Downloads/new-cluster.yaml \
kubectl config view --flatten > ~/.kube/merged-config
Core Commands
get — list resources
# list all pods in current namespace
kubectl get pods
# list pods in a specific namespace
kubectl get pods -n kube-system
# list pods across all namespaces
kubectl get pods -A
# list multiple resource types at once
kubectl get pods,services,deployments
# include extra columns (node, IP, etc.)
kubectl get pods -o wide
describe — detailed information
kubectl describe shows full details including events,
which is the first place to look when something isn't working:
kubectl describe pod payments-api-7d4f8b9-xk2lm
kubectl describe node worker-1
kubectl describe deployment payments-api
apply — declarative updates
# apply a single manifest
kubectl apply -f pod.yaml
# apply all manifests in a directory
kubectl apply -f ./k8s/
# apply recursively
kubectl apply -R -f ./k8s/
# dry-run — preview changes without applying
kubectl apply -f deployment.yaml --dry-run=client
delete — remove resources
# delete by manifest (recommended — mirrors apply)
kubectl delete -f pod.yaml
# delete by name
kubectl delete pod payments-api-7d4f8b9-xk2lm
# delete all pods matching a label selector
kubectl delete pods -l app=payments-api
# delete a namespace (and everything inside it)
kubectl delete namespace staging
create vs apply
| Command | Behaviour | Use when |
|---|---|---|
kubectl create |
Creates resource; fails if it already exists | One-off imperative creation |
kubectl apply |
Creates or updates resource; idempotent | GitOps / CI/CD workflows |
Logs & Exec
# stream logs from a pod (single container)
kubectl logs -f payments-api-7d4f8b9-xk2lm
# logs from a specific container in a multi-container pod
kubectl logs payments-api-7d4f8b9-xk2lm -c sidecar
# logs from all pods matching a label
kubectl logs -l app=payments-api --all-containers
# previous container logs (after a crash/restart)
kubectl logs payments-api-7d4f8b9-xk2lm --previous
Open an interactive shell inside a running container:
# interactive shell
kubectl exec -it payments-api-7d4f8b9-xk2lm -- /bin/sh
# run a one-off command without TTY
kubectl exec payments-api-7d4f8b9-xk2lm -- env
# specify container in multi-container pod
kubectl exec -it payments-api-7d4f8b9-xk2lm -c api -- /bin/bash
Port-forward & Proxy
kubectl port-forward tunnels traffic from your local
machine to a pod or service — without exposing anything publicly.
Essential for testing internal services:
# local port 8080 → pod port 8080
kubectl port-forward pod/payments-api-7d4f8b9-xk2lm 8080:8080
# port-forward to a service (picks a random pod)
kubectl port-forward svc/payments-api 8080:80
# background the process; kill with: kill $(lsof -ti:8080)
kubectl port-forward svc/payments-api 8080:80 &
Output Formats
The -o flag controls output format:
| Flag | Output | Use case |
|---|---|---|
-o wide |
Extra columns (node, IP, nominated node) | Inspect scheduling |
-o yaml |
Full YAML of the live resource | Inspect or save current state |
-o json |
Full JSON | Pipe to jq |
-o name |
Resource name only (e.g. pod/my-pod) |
Scripts and loops |
-o jsonpath='{...}' |
Extract specific fields via JSONPath | Automation |
-o custom-columns=... |
Define your own column headers | Custom summaries |
# get the image of every container in every pod
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].image}{"\n"}{end}'
# all node names, one per line
kubectl get nodes -o name
Power-user Patterns
Watch mode
# refresh the pod list every 2 seconds
kubectl get pods -w
Rollout management
# watch a rollout in progress
kubectl rollout status deployment/payments-api
# view rollout history
kubectl rollout history deployment/payments-api
# roll back to the previous version
kubectl rollout undo deployment/payments-api
# roll back to a specific revision
kubectl rollout undo deployment/payments-api --to-revision=3
Editing live resources
# open resource YAML in your $EDITOR
kubectl edit deployment/payments-api
# patch a specific field without opening an editor
kubectl patch deployment/payments-api \
-p '{"spec":{"replicas":5}}'
Copying files
# copy from pod to local
kubectl cp payments-api-7d4f8b9-xk2lm:/app/logs/error.log ./error.log
# copy from local to pod
kubectl cp ./config.json payments-api-7d4f8b9-xk2lm:/app/config.json
Generate YAML stubs with --dry-run
Instead of writing manifests from scratch, let kubectl generate the boilerplate:
# generate a Deployment manifest without applying it
kubectl create deployment payments-api \
--image=payments-api:2.4.1 \
--replicas=3 \
--dry-run=client -o yaml > deployment.yaml
# generate a Service manifest
kubectl expose deployment payments-api \
--port=80 --target-port=8080 \
--dry-run=client -o yaml > service.yaml