The commands you reach for every day — and the ones you have to search every time. This reference covers everything from basic pod management to rolling updates, RBAC, and debugging.
Quick reference
The 25 commands that cover 90% of daily kubectl work.
| Command | What it does |
|---|---|
kubectl get pods |
List pods in current namespace |
kubectl get pods -A |
List pods in all namespaces |
kubectl get pods -w |
Watch pod status in real time |
kubectl describe pod <name> |
Full pod details + events |
kubectl logs <pod> |
Print pod logs |
kubectl logs -f <pod> |
Follow live logs |
kubectl exec -it <pod> -- bash |
Open shell in running pod |
kubectl apply -f manifest.yaml |
Create or update resources |
kubectl delete -f manifest.yaml |
Delete resources from file |
kubectl delete pod <name> |
Delete a specific pod |
kubectl get deployments |
List deployments |
kubectl rollout status deploy/<name> |
Watch rollout progress |
kubectl rollout undo deploy/<name> |
Roll back to previous version |
kubectl scale deploy/<name> --replicas=3 |
Scale deployment |
kubectl get services |
List services |
kubectl port-forward pod/<name> 8080:80 |
Forward local port to pod |
kubectl get configmaps |
List config maps |
kubectl get secrets |
List secrets |
kubectl get nodes |
List cluster nodes |
kubectl get namespaces |
List namespaces |
kubectl config get-contexts |
List kubeconfig contexts |
kubectl config use-context <name> |
Switch context |
kubectl top pods |
Show CPU/memory usage |
kubectl events --sort-by=.lastTimestamp |
Recent cluster events |
kubectl explain pod.spec |
Inline API docs for a field |
Pods
List and filter
kubectl get pods # Current namespace
kubectl get pods -n kube-system # Specific namespace
kubectl get pods -A # All namespaces
kubectl get pods -o wide # Include node + IP
kubectl get pods -l app=nginx # Filter by label
kubectl get pods --field-selector status.phase=Running
# Output as YAML or JSON
kubectl get pod <name> -o yaml
kubectl get pod <name> -o json
Describe and events
kubectl describe pod <name> # Details, conditions, events
kubectl describe pod <name> -n <ns> # In specific namespace
kubectl get events --field-selector involvedObject.name=<pod>
Logs
kubectl logs <pod> # All logs
kubectl logs <pod> -c <container> # Multi-container pod
kubectl logs -f <pod> # Follow (stream)
kubectl logs --previous <pod> # Logs from crashed previous container
kubectl logs <pod> --since=1h # Last hour
kubectl logs <pod> --tail=100 # Last 100 lines
kubectl logs -l app=nginx # Logs from all pods matching label
Exec into a pod
kubectl exec -it <pod> -- bash # bash shell
kubectl exec -it <pod> -- sh # sh (for Alpine/BusyBox)
kubectl exec -it <pod> -c <container> -- bash # specific container
kubectl exec <pod> -- env # Run a command without interactive
kubectl exec <pod> -- cat /etc/config # Read a file
Port forwarding
kubectl port-forward pod/<name> 8080:80 # local:pod
kubectl port-forward deployment/<name> 8080:80 # via deployment
kubectl port-forward service/<name> 8080:80 # via service
kubectl port-forward pod/<name> 8080:80 & # background
Copy files
kubectl cp <pod>:/app/log.txt ./log.txt # Pod → local
kubectl cp ./config.json <pod>:/app/ # Local → pod
kubectl cp <pod>:/app/ ./backup/ -c <container> # Specific container
Run temporary pods
# Debug with a throwaway pod
kubectl run debug --image=busybox --rm -it -- sh
# curl inside cluster
kubectl run curl --image=curlimages/curl --rm -it -- sh
# With environment variable
kubectl run myapp --image=nginx --env="ENV=staging"
Deployments
Create and update
kubectl create deployment nginx --image=nginx
kubectl apply -f deployment.yaml # Create or update from file
kubectl set image deploy/<name> nginx=nginx:1.27 # Update image
Scale
kubectl scale deployment <name> --replicas=5
kubectl scale --replicas=0 deployment/<name> # Scale to zero (pause)
kubectl autoscale deployment <name> --min=2 --max=10 --cpu-percent=80
Rollouts
kubectl rollout status deployment/<name> # Watch rollout
kubectl rollout history deployment/<name> # Revision history
kubectl rollout history deployment/<name> --revision=2 # Specific revision
kubectl rollout undo deployment/<name> # Roll back one step
kubectl rollout undo deployment/<name> --to-revision=2 # Roll back to specific
kubectl rollout restart deployment/<name> # Trigger fresh rollout
kubectl rollout pause deployment/<name> # Pause mid-rollout
kubectl rollout resume deployment/<name> # Resume paused rollout
Inspect
kubectl get deployment <name> -o yaml
kubectl describe deployment <name>
kubectl get replicasets # See underlying ReplicaSets
Services
kubectl get services # All services in namespace
kubectl get svc -A # All namespaces (shorthand: svc)
kubectl describe service <name>
kubectl expose deployment <name> --port=80 --type=ClusterIP
kubectl expose deployment <name> --port=80 --type=NodePort
kubectl expose deployment <name> --port=80 --type=LoadBalancer
kubectl delete service <name>
ConfigMaps and Secrets
ConfigMaps
kubectl create configmap my-config --from-literal=key=value
kubectl create configmap my-config --from-file=config.properties
kubectl create configmap my-config --from-env-file=.env
kubectl get configmap my-config -o yaml
kubectl describe configmap my-config
kubectl edit configmap my-config # Open in $EDITOR
kubectl delete configmap my-config
Secrets
kubectl create secret generic my-secret --from-literal=password=abc123
kubectl create secret generic my-secret --from-file=ssh-key=id_rsa
kubectl create secret docker-registry regcred \
--docker-server=registry.example.com \
--docker-username=user \
--docker-password=pass
kubectl get secret my-secret -o yaml # base64-encoded values
# Decode a secret value:
kubectl get secret my-secret -o jsonpath='{.data.password}' | base64 -d
Namespaces
kubectl get namespaces # List all namespaces (ns)
kubectl create namespace staging
kubectl delete namespace staging # Deletes ALL resources inside
# Set default namespace for current session
kubectl config set-context --current --namespace=staging
# Run any command in a specific namespace
kubectl get pods -n staging
kubectl get pods -n kube-system
Nodes
kubectl get nodes # List nodes
kubectl get nodes -o wide # With IPs, OS, kernel version
kubectl describe node <name> # Details + conditions + events
kubectl top nodes # CPU/memory (requires metrics-server)
kubectl cordon <node> # Mark unschedulable (no new pods)
kubectl uncordon <node> # Mark schedulable again
kubectl drain <node> --ignore-daemonsets --delete-emptydir-data # Evict pods
kubectl taint node <node> key=value:NoSchedule
kubectl taint node <node> key=value:NoSchedule- # Remove taint
Resource management
Apply, create, delete
kubectl apply -f manifest.yaml # Create or update (idempotent)
kubectl apply -f ./k8s/ # Apply whole directory
kubectl apply -f https://example.com/manifest.yaml
kubectl create -f manifest.yaml # Create only (fails if exists)
kubectl replace -f manifest.yaml # Replace (fails if not exists)
kubectl delete -f manifest.yaml # Delete from file
kubectl delete pod,service -l app=nginx # Delete by label
kubectl delete pods --all # Delete all pods in namespace
Dry run and diff
kubectl apply -f manifest.yaml --dry-run=client # Validate without applying
kubectl apply -f manifest.yaml --dry-run=server # Server-side validation
kubectl diff -f manifest.yaml # Show what would change
Patch
# Patch a field inline
kubectl patch deployment <name> -p '{"spec":{"replicas":3}}'
# Strategic merge patch from file
kubectl patch deployment <name> --patch-file patch.yaml
# JSON patch
kubectl patch pod <name> --type='json' \
-p='[{"op": "replace", "path": "/spec/containers/0/image", "value":"nginx:1.27"}]'
Contexts and config
kubectl config view # Show kubeconfig
kubectl config get-contexts # List all contexts
kubectl config current-context # Show active context
kubectl config use-context <name> # Switch context
kubectl config set-context --current --namespace=staging # Set default ns
# Merge multiple kubeconfigs
export KUBECONFIG=~/.kube/config:~/.kube/config2
kubectl config view --flatten > ~/.kube/merged-config
Labels and annotations
# Add or update labels
kubectl label pod <name> env=prod
kubectl label pod <name> env=staging --overwrite
# Remove label
kubectl label pod <name> env-
# Filter by label
kubectl get pods -l env=prod
kubectl get pods -l 'env in (prod,staging)'
kubectl get pods -l 'env notin (prod)'
# Annotations
kubectl annotate pod <name> description="main api"
kubectl annotate pod <name> description- # Remove
Resource quotas and limits
kubectl get resourcequota # Namespace quotas
kubectl get limitrange # Default limits
kubectl describe resourcequota default # Usage vs limits
kubectl top pods # Current CPU/memory (needs metrics-server)
kubectl top pods --sort-by=memory # Sort by memory
kubectl top pods -l app=nginx # Filter by label
RBAC
kubectl get roles # Namespace-scoped roles
kubectl get clusterroles # Cluster-wide roles
kubectl get rolebindings
kubectl get clusterrolebindings
kubectl describe role <name>
kubectl auth can-i create pods # Check own permissions
kubectl auth can-i list pods --as=user@example.com # Check another user
kubectl auth can-i --list # All permissions for current user
Debugging
Common debugging workflow
# 1. Check pod status
kubectl get pods
# 2. If CrashLoopBackOff or Error — check logs
kubectl logs <pod>
kubectl logs --previous <pod> # Crashed container logs
# 3. If Pending — check events and node resources
kubectl describe pod <pod>
kubectl get events --sort-by='.lastTimestamp'
# 4. If ImagePullBackOff — check image name and secret
kubectl describe pod <pod> | grep -A5 "Events:"
# 5. Exec in to investigate
kubectl exec -it <pod> -- sh
Ephemeral debug containers (Kubernetes 1.25+)
# Add a debug sidecar to a running pod (non-destructive)
kubectl debug -it <pod> --image=busybox --target=<container>
kubectl debug node/<node> -it --image=ubuntu # Debug a node
JSONPath queries
# Get a specific field
kubectl get pod <name> -o jsonpath='{.status.podIP}'
# Loop over all pods
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.phase}{"\n"}{end}'
# Pipe to jq for more complex queries
kubectl get pods -o json | jq '.items[] | {name: .metadata.name, status: .status.phase}'
Common mistakes
1. Forgetting -n for the right namespacekubectl get pods only shows the current namespace. Use -A or -n <ns> to search everywhere.
2. kubectl delete namespace deletes everything inside
Namespace deletion cascades to all pods, services, deployments, and secrets inside it. Always double-check before deleting.
3. kubectl apply vs kubectl replaceapply is idempotent and merges changes — use it almost always. replace deletes and recreates, losing annotations and state set by controllers.
4. kubectl exec command separator
Always use -- before the command: kubectl exec -it pod -- bash. Without --, flags like -n get interpreted by kubectl, not the shell.
5. kubectl scale --replicas=0 won't persist if HPA is set
A HorizontalPodAutoscaler will immediately scale the deployment back up. Suspend the HPA first: kubectl patch hpa <name> -p '{"spec":{"minReplicas":0}}'.
6. Editing live resources with kubectl edit
Changes saved via kubectl edit are applied immediately with no confirmation. Use --dry-run=server or kubectl diff first for anything risky.
FAQ
How do I connect to a specific cluster?
Use kubectl config use-context <context-name> to switch clusters. Run kubectl config get-contexts to see all available contexts from your kubeconfig file.
What is the difference between kubectl apply and kubectl create?create fails if the resource already exists. apply creates it if absent or merges changes if it exists — making it safe for CI/CD pipelines.
How do I check what image a running pod is using?kubectl get pod <name> -o jsonpath='{.spec.containers[*].image}' or kubectl describe pod <name> | grep Image:.
How do I see why a pod is stuck in Pending?
Run kubectl describe pod <name> and scroll to the Events section. Common causes: insufficient CPU/memory, no matching nodes (taint/toleration mismatch), or PVC not bound.
How do I restart a deployment without changing anything?kubectl rollout restart deployment/<name> — this triggers a rolling restart by adding an annotation with a timestamp.
Is there a kubectl autocomplete?
Yes. Add to ~/.bashrc: source <(kubectl completion bash) and alias k=kubectl && complete -o default -F __start_kubectl k. For zsh: source <(kubectl completion zsh).