Toolmingo
Guides9 min read

kubectl Cheat Sheet: Every Command You Actually Need

A complete kubectl cheat sheet — pods, deployments, services, namespaces, config maps, secrets, logs, exec, port-forward, and rollouts. Copy-ready commands for daily Kubernetes work.

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 namespace
kubectl 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 replace
apply 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).

Related tools

Keep reading

All Toolmingotools are free & run in your browser

No sign-up, no upload, no watermark. Your files never leave your device.

Browse all tools