Containers & Kubernetes20 min

kubectl — Kubernetes CLI Cheat Sheet

Complete kubectl reference — context management, pods, deployments, services, config maps, secrets, logs, debugging, and exam-critical commands.

Contexts & Cluster Config

# List clusters/contexts/users
kubectl config get-contexts
kubectl config get-clusters
kubectl config get-users

# Switch context
kubectl config use-context my-cluster
kubectl config use-context gke_project_region_cluster

# Show current context
kubectl config current-context

# Set namespace for current context
kubectl config set-context --current --namespace=my-namespace

# Merge kubeconfigs
export KUBECONFIG=~/.kube/config:~/.kube/other-config
kubectl config view --merge --flatten > ~/.kube/merged-config

# Useful aliases
alias k=kubectl
alias kn='kubectl config set-context --current --namespace'

Get / Describe Resources

# Syntax: kubectl get <resource> [name] [flags]
kubectl get pods
kubectl get pods -n kube-system           # specific namespace
kubectl get pods -A                        # all namespaces
kubectl get pods -o wide                  # + node and IP
kubectl get pods -o yaml                  # full YAML
kubectl get pods -o json                  # JSON
kubectl get pods --watch                  # watch for changes
kubectl get pods -l app=nginx             # filter by label
kubectl get pods --field-selector status.phase=Running

# All resources at once
kubectl get all
kubectl get all -n my-namespace
kubectl api-resources                     # list all resource types

# Describe (human-readable with events)
kubectl describe pod my-pod
kubectl describe node worker-01
kubectl describe deployment my-deploy

# Explain resource fields
kubectl explain pod.spec.containers
kubectl explain deployment --recursive

Pods

# Run a pod (imperative — for testing)
kubectl run nginx --image=nginx:latest
kubectl run debug --image=busybox:latest --rm -it -- sh   # ephemeral debug pod
kubectl run nginx --image=nginx --port=80 --env="MY_VAR=value"

# Delete pod
kubectl delete pod my-pod
kubectl delete pod my-pod --grace-period=0 --force  # immediate

# Exec into pod
kubectl exec -it my-pod -- /bin/bash
kubectl exec -it my-pod -c sidecar -- sh      # specific container

# Copy files
kubectl cp my-pod:/app/logs/app.log ./app.log
kubectl cp ./config.yaml my-pod:/app/config.yaml

# Port forwarding
kubectl port-forward pod/my-pod 8080:80
kubectl port-forward service/my-svc 8080:80

Logs

kubectl logs my-pod                              # All logs
kubectl logs my-pod -f                           # Follow live
kubectl logs my-pod --tail=100                   # Last 100 lines
kubectl logs my-pod --since=1h                   # Last hour
kubectl logs my-pod -c my-container              # Specific container
kubectl logs my-pod --previous                   # Previous container (after crash)

# Logs from all pods matching a label
kubectl logs -l app=nginx --all-containers=true
kubectl logs -l app=nginx -f --max-log-requests 10

Deployments

# Create deployment (imperative)
kubectl create deployment my-deploy --image=nginx:latest --replicas=3

# Scale
kubectl scale deployment my-deploy --replicas=5
kubectl autoscale deployment my-deploy --min=2 --max=10 --cpu-percent=70

# Update image (triggers rolling update)
kubectl set image deployment/my-deploy nginx=nginx:1.25
kubectl set image deployment/my-deploy app=myapp:v2 --record

# Rollout status / history
kubectl rollout status deployment/my-deploy
kubectl rollout history deployment/my-deploy
kubectl rollout history deployment/my-deploy --revision=2

# Rollback
kubectl rollout undo deployment/my-deploy
kubectl rollout undo deployment/my-deploy --to-revision=2

# Pause / resume rolling update
kubectl rollout pause deployment/my-deploy
kubectl rollout resume deployment/my-deploy

# Restart pods (rolling restart)
kubectl rollout restart deployment/my-deploy

Services

# Expose a deployment
kubectl expose deployment my-deploy --port=80 --target-port=8080 --type=ClusterIP
kubectl expose deployment my-deploy --port=80 --type=NodePort
kubectl expose deployment my-deploy --port=80 --type=LoadBalancer

# Create service imperatively
kubectl create service clusterip my-svc --tcp=80:8080
kubectl create service nodeport my-svc --tcp=80:8080

# Get service endpoints
kubectl get endpoints my-svc
kubectl get service my-svc -o yaml

# Delete
kubectl delete service my-svc

ConfigMaps & Secrets

# ConfigMap
kubectl create configmap my-config --from-literal=key1=val1 --from-literal=key2=val2
kubectl create configmap my-config --from-file=./config.properties
kubectl create configmap my-config --from-file=./config-dir/

kubectl get configmap my-config -o yaml
kubectl describe configmap my-config

# Secret
kubectl create secret generic my-secret --from-literal=password=s3cr3t
kubectl create secret generic my-secret --from-file=./tls.crt --from-file=./tls.key
kubectl create secret docker-registry regcred \
  --docker-server=myregistry.io \
  --docker-username=myuser \
  --docker-password=mypass

kubectl get secret my-secret -o yaml
# Decode secret value
kubectl get secret my-secret -o jsonpath='{.data.password}' | base64 -d

Namespaces

kubectl get namespaces
kubectl create namespace my-ns
kubectl delete namespace my-ns

# Run command in namespace
kubectl get pods -n my-ns
kubectl -n my-ns exec -it my-pod -- sh

# Set default namespace for session
kubectl config set-context --current --namespace=my-ns

Apply / Create / Delete (Declarative)

# Apply (create or update)
kubectl apply -f manifest.yaml
kubectl apply -f ./k8s/                  # apply entire directory
kubectl apply -f https://raw.githubusercontent.com/org/repo/main/deploy.yaml

# Dry run (validate without applying)
kubectl apply -f manifest.yaml --dry-run=client
kubectl apply -f manifest.yaml --dry-run=server

# Delete
kubectl delete -f manifest.yaml
kubectl delete deployment,service -l app=myapp

# Diff (show what would change)
kubectl diff -f updated-manifest.yaml

Labels & Annotations

# Label management
kubectl label pod my-pod env=production
kubectl label pod my-pod env=staging --overwrite
kubectl label pod my-pod env-                    # Remove label

# Annotations
kubectl annotate pod my-pod note="deployed by CI"

# Select by label
kubectl get pods -l env=production
kubectl get pods -l 'env in (production,staging)'
kubectl get pods -l 'env notin (dev)'

Node Management

kubectl get nodes
kubectl get nodes -o wide
kubectl describe node worker-01

# Cordon / uncordon (prevent new pods)
kubectl cordon worker-01
kubectl uncordon worker-01

# Drain (evict pods for maintenance)
kubectl drain worker-01 --ignore-daemonsets --delete-empty-dir-data

# Taint / toleration
kubectl taint nodes worker-01 key=value:NoSchedule
kubectl taint nodes worker-01 key:NoSchedule-     # Remove taint

Output Formatting & JSONPath

# Get pod IPs
kubectl get pods -o jsonpath='{.items[*].status.podIP}'

# Get image for each pod
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[0].image}{"\n"}{end}'

# Custom columns
kubectl get pods -o custom-columns='NAME:.metadata.name,IMAGE:.spec.containers[0].image,STATUS:.status.phase'

# Sort by field
kubectl get pods --sort-by=.status.startTime

# Filter with grep
kubectl get pods -A | grep -v Running

Quick Generator Patterns (--dry-run + -o yaml)

# Generate pod YAML without applying
kubectl run nginx --image=nginx --dry-run=client -o yaml > pod.yaml

# Generate deployment YAML
kubectl create deployment my-deploy --image=nginx --dry-run=client -o yaml > deploy.yaml

# Generate service YAML
kubectl create service clusterip my-svc --tcp=80:8080 --dry-run=client -o yaml > svc.yaml

# Generate configmap YAML
kubectl create configmap my-config --from-literal=key=val --dry-run=client -o yaml > cm.yaml