kubectl
03 / 03

Debugging, Scaling & Advanced Operations

kubectl: Debugging, Scaling & Advanced Operations

Logs & Exec

# Pod logs
kubectl logs my-pod
kubectl logs my-pod -c container-name       # specific container in multi-container pod
kubectl logs my-pod --previous              # logs from previous (crashed) container
kubectl logs my-pod -f                      # follow (stream)
kubectl logs my-pod --tail=100              # last 100 lines
kubectl logs my-pod --since=1h              # last hour
kubectl logs -l app=nginx                   # logs from all pods with label

# Exec into container
kubectl exec -it my-pod -- bash
kubectl exec -it my-pod -c sidecar -- sh   # specific container
kubectl exec my-pod -- ls /app             # one-off command

# Copy files
kubectl cp my-pod:/app/config.yaml ./config.yaml   # pod → local
kubectl cp ./data.sql my-pod:/tmp/data.sql          # local → pod

Port Forwarding & Proxy

# Forward local port to pod
kubectl port-forward pod/my-pod 8080:80
kubectl port-forward deployment/my-deploy 8080:80
kubectl port-forward service/my-svc 8080:80

# Access background
kubectl port-forward svc/postgres 5432:5432 &

# Proxy to API server (all kubectl API accessible at localhost:8001)
kubectl proxy
# then: curl http://localhost:8001/api/v1/namespaces/default/pods

# Debug with ephemeral containers (K8s 1.23+)
kubectl debug -it my-pod --image=busybox --target=app
kubectl debug node/worker-1 -it --image=ubuntu

Resource Usage & Events

# Resource usage (requires metrics-server)
kubectl top pods
kubectl top pods -n production -l app=nginx
kubectl top nodes

# Events (sorted by time)
kubectl get events --sort-by=.lastTimestamp
kubectl get events -n staging
kubectl get events --field-selector reason=BackOff

# Resource requests/limits
kubectl describe pod my-pod | grep -A3 Requests
kubectl describe node worker-1 | grep -A10 "Allocated resources"

JSONPath & Custom Output

# JSONPath queries
kubectl get pod my-pod -o jsonpath='{.status.podIP}'
kubectl get pods -o jsonpath='{.items[*].metadata.name}'
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.phase}{"\n"}{end}'

# Custom columns
kubectl get pods -o custom-columns=NAME:.metadata.name,STATUS:.status.phase,NODE:.spec.nodeName

# Sort output
kubectl get pods --sort-by=.metadata.creationTimestamp
kubectl get pods --sort-by=.status.containerStatuses[0].restartCount

# All resources across a namespace (for audit)
kubectl api-resources --verbs=list --namespaced -o name |   xargs -I{} kubectl get {} -n default 2>/dev/null

Helpful Plugins & Tips

  • kubectx / kubens (ahmetb): instantly switch contexts and namespaces — brew install kubectx.

  • krew: kubectl plugin manager — kubectl krew install <plugin>.

  • kubectl neat: strips clutter from -o yaml output (managedFields, status) — great for diffing.

  • kubecolor: colorized kubectl output — drop-in alias for kubectl.

  • k9s: terminal UI for Kubernetes — real-time cluster view with logs, exec, and port-forward.

  • stern: tail logs from multiple pods simultaneously, with regex filtering.

  • kubectl diff -f file.yaml: preview what apply would change without applying.

  • kubectl explain pod.spec.containers: built-in API field documentation without leaving the terminal.

# Useful aliases
alias k=kubectl
alias kgp='kubectl get pods'
alias kgs='kubectl get svc'
alias kgd='kubectl get deploy'
alias kl='kubectl logs -f'
alias ke='kubectl exec -it'

# Shell completion
source <(kubectl completion bash)    # bash
source <(kubectl completion zsh)     # zsh
# or add to ~/.bashrc / ~/.zshrc

# Dry-run (validate without applying)
kubectl apply -f app.yaml --dry-run=client
kubectl apply -f app.yaml --dry-run=server   # validates against cluster API

# Generate YAML from imperative command
kubectl create deployment nginx --image=nginx --dry-run=client -o yaml > deployment.yaml
kubectl expose deployment nginx --port=80 --dry-run=client -o yaml >> deployment.yaml

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free