Home DevOps Kubernetes Troubleshooting — Complete Guide
Intermediate 5 min · July 12, 2026

Kubernetes Troubleshooting — Complete Guide

Learn Kubernetes Troubleshooting — Complete Guide with plain-English explanations and real examples..

N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Notes here come from systems that actually shipped.

Follow
Verified
production tested
July 12, 2026
last updated
2,073
articles · all by Naren
Before you start⏱ 25 min
  • Kubernetes cluster (v1.18+), kubectl installed and configured, basic understanding of pods, services, deployments, and nodes, familiarity with YAML, access to cluster with sufficient permissions (cluster-admin or equivalent), optional: metrics-server, krew plugin manager.
✦ Definition~90s read
What is Kubernetes Troubleshooting?

Kubernetes troubleshooting is the systematic process of diagnosing and resolving issues in a Kubernetes cluster, from pod crashes and networking failures to resource exhaustion and misconfigurations. It matters because Kubernetes' distributed nature creates complex failure modes that can cascade across services, making root cause analysis non-trivial.

Think of Kubernetes Troubleshooting — Complete Guide like a tool in your DevOps toolkit — once you understand what it does and when to reach for it, managing Kubernetes clusters becomes second nature.

Use it when pods are stuck in CrashLoopBackOff, services are unreachable, or cluster performance degrades. The goal is to restore stability with minimal downtime by applying structured debugging techniques.

Plain-English First

Think of Kubernetes Troubleshooting — Complete Guide like a tool in your DevOps toolkit — once you understand what it does and when to reach for it, managing Kubernetes clusters becomes second nature.

Welcome to Kubernetes Troubleshooting — Complete Guide. We'll break this down from first principles.

1. Understanding the Kubernetes Troubleshooting Hierarchy

Kubernetes troubleshooting follows a layered approach: start from the bottom (pods) and work up to the cluster level. Most issues manifest as pod failures, but the root cause often lies in the control plane, networking, or resource constraints. The hierarchy includes: Pods → Services/Ingress → Nodes → Control Plane → Storage/Networking. Always check pod logs and events first, then examine node health, and finally inspect cluster-level components like kube-apiserver or etcd. This prevents wasted effort on symptoms rather than causes. For example, a CrashLoopBackOff might be due to a missing ConfigMap, which is a pod-level config issue, but if all pods on a node fail, suspect a node problem. Use kubectl get events --all-namespaces to see cluster-wide events quickly.

check-events.shBASH
1
kubectl get events --all-namespaces --sort-by='.lastTimestamp' | tail -20
Output
NAMESPACE LAST SEEN TYPE REASON OBJECT MESSAGE
default 5m Warning BackOff pod/my-app-7d4f8b6c9-abcde Back-off restarting failed container
default 10m Normal Pulled pod/my-app-7d4f8b6c9-abcde Successfully pulled image "my-app:latest"
kube-system 15m Warning NodeHasDiskPressure node/worker-1 Node worker-1 has disk pressure
💡Start with Events
Always run kubectl get events before diving into logs. Events often contain the exact reason for failures, saving you from guessing.
📊 Production Insight
In production, we once spent hours debugging a service mesh issue only to find it was a node with a full disk. Events would have shown NodeHasDiskPressure immediately.
🎯 Key Takeaway
Follow the troubleshooting hierarchy: pods → services → nodes → control plane to isolate root causes efficiently.

2. Diagnosing Pod Failures: CrashLoopBackOff and ImagePullBackOff

Pod failures are the most common Kubernetes issues. CrashLoopBackOff means the container starts but crashes repeatedly. ImagePullBackOff means the container image cannot be pulled. For CrashLoopBackOff, check logs with kubectl logs <pod> --previous to see the last crash's output. Common causes: missing environment variables, misconfigured secrets, or application bugs. For ImagePullBackOff, verify the image name, tag, and registry credentials. Use kubectl describe pod <pod> to see the exact error. If the image is private, ensure the imagePullSecret is correctly configured. Also check if the node has disk space issues preventing image extraction. A systematic approach: describe the pod, check logs, then inspect the node's disk and network.

debug-pod.shBASH
1
2
3
4
5
6
7
8
# Get pod details
kubectl describe pod my-app-7d4f8b6c9-abcde

# View logs from previous crash
kubectl logs my-app-7d4f8b6c9-abcde --previous

# Check image pull secret
kubectl get secret my-registry-key -o yaml
Output
Name: my-app-7d4f8b6c9-abcde
Namespace: default
Priority: 0
Node: worker-1/192.168.1.10
Start Time: Mon, 12 Jul 2026 10:00:00 UTC
Labels: app=my-app
Annotations: <none>
Status: CrashLoopBackOff
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 10m default-scheduler Successfully assigned default/my-app-7d4f8b6c9-abcde to worker-1
Normal Pulled 10m kubelet Successfully pulled image "my-app:latest"
Normal Created 10m kubelet Created container my-app
Normal Started 10m kubelet Started container my-app
Warning BackOff 5m kubelet Back-off restarting failed container
⚠ Check Previous Logs
When a pod is in CrashLoopBackOff, the current container may not have logs. Use --previous to see the last container's output.
📊 Production Insight
We once had a CrashLoopBackOff caused by a missing database migration. The logs showed a connection refused, but the real issue was the app starting before the DB was ready. Adding an init container fixed it.
🎯 Key Takeaway
For pod failures, always start with kubectl describe and kubectl logs --previous to get the error details.
kubernetes-troubleshooting THECODEFORGE.IO Kubernetes Pod Failure Diagnosis Flow Step-by-step process to diagnose and resolve pod failures Check Pod Status Use kubectl get pods to see status Describe Pod kubectl describe pod for events Inspect Logs kubectl logs to find errors Check Resource Limits Verify CPU/memory requests and limits Verify Configurations Check ConfigMaps, Secrets, and volumes Restart or Debug Use kubectl debug or delete pod ⚠ CrashLoopBackOff often due to missing dependencies Always check init containers and sidecar logs THECODEFORGE.IO
thecodeforge.io
Kubernetes Troubleshooting

3. Debugging Services and Endpoints

When a service is unreachable, the problem often lies in endpoint configuration or network policies. First, verify the service exists and has endpoints: kubectl get svc and kubectl get endpoints. If endpoints are empty, the selector doesn't match any pods. Check pod labels: kubectl get pods --show-labels. Also ensure the service port matches the container port. For headless services, endpoints should list pod IPs. If endpoints exist but the service is unreachable, test connectivity from a pod: kubectl exec -it <pod> -- curl <service-name>:<port>. Network policies might block traffic; check with kubectl describe networkpolicy. Also verify kube-proxy is running on nodes and iptables rules are correct.

debug-service.shBASH
1
2
3
4
5
6
7
8
9
# Check service and endpoints
kubectl get svc my-service
kubectl get endpoints my-service

# Test connectivity from a pod
kubectl run test-pod --image=busybox --rm -it --restart=Never -- sh -c "wget -qO- http://my-service:8080"

# Check network policies
kubectl get networkpolicy -n default
Output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-service ClusterIP 10.96.0.1 <none> 8080/TCP 1h
NAME ENDPOINTS AGE
my-service 10.244.0.5:8080 1h
Connecting to my-service:8080 (10.96.0.1:8080)
wget: can't connect to remote host (10.96.0.1): Connection refused
🔥Empty Endpoints? Check Labels
If endpoints are empty, your service selector doesn't match any pods. Run kubectl get pods --show-labels and compare labels.
📊 Production Insight
In production, a service was unreachable because a deployment update changed pod labels but the service selector wasn't updated. We caught it by noticing zero endpoints.
🎯 Key Takeaway
Service issues are usually selector mismatches or network policies; verify endpoints and test connectivity from within the cluster.

4. Node-Level Troubleshooting: Disk, Memory, and Network

Node issues can cause widespread pod failures. Common problems: disk pressure, memory pressure, or network unavailability. Check node status with kubectl get nodes and kubectl describe node <node>. Look for conditions like DiskPressure, MemoryPressure, or PIDPressure. For disk pressure, check disk usage on the node via SSH or use kubectl debug node/<node> -it --image=busybox to run a debug pod. Memory pressure may require adjusting resource limits or adding nodes. Network issues can be diagnosed with kubectl get nodes -o wide to see internal IPs and then ping from another node. Also check kubelet logs: journalctl -u kubelet -n 100 on the node. If the node is NotReady, restart kubelet or check the container runtime.

debug-node.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
# Check node status
kubectl get nodes
kubectl describe node worker-1

# Debug node with ephemeral container
kubectl debug node/worker-1 -it --image=busybox -- chroot /host

# Check disk usage inside node debug pod
df -h

# Check kubelet logs (on the node)
journalctl -u kubelet -n 50 --no-pager
Output
NAME STATUS ROLES AGE VERSION
master Ready master 30d v1.28.0
worker-1 Ready <none> 30d v1.28.0
worker-2 NotReady <none> 30d v1.28.0
Conditions:
Type Status LastHeartbeatTime LastTransitionTime Reason Message
---- ------ ----------------- ------------------ ------ -------
MemoryPressure False Mon, 12 Jul 2026 12:00:00 UTC Mon, 12 Jul 2026 11:00:00 UTC KubeletHasSufficientMemory kubelet has sufficient memory available
DiskPressure True Mon, 12 Jul 2026 12:00:00 UTC Mon, 12 Jul 2026 11:30:00 UTC KubeletHasDiskPressure kubelet has disk pressure
PIDPressure False Mon, 12 Jul 2026 12:00:00 UTC Mon, 12 Jul 2026 11:00:00 UTC KubeletHasSufficientPID kubelet has sufficient PID available
⚠ Disk Pressure Evicts Pods
When a node has DiskPressure, kubelet will evict pods to free space. Check which pods are evicted with kubectl get pods --field-selector=status.phase=Failed.
📊 Production Insight
We had a node go NotReady because the container runtime (containerd) crashed due to a corrupted image cache. Restarting containerd and cleaning /var/lib/containerd resolved it.
🎯 Key Takeaway
Node issues often manifest as pod evictions; check node conditions and disk usage first.

5. Control Plane Troubleshooting: API Server, Scheduler, and Controller Manager

Control plane failures affect the entire cluster. Symptoms: kubectl commands hang or return errors, pods not being scheduled, or resources not being reconciled. Check control plane pod status: kubectl get pods -n kube-system. Common issues: etcd leader election failures, API server certificate expiration, or scheduler misconfiguration. For API server issues, check its logs: kubectl logs -n kube-system kube-apiserver-master. If the API server is down, you can't use kubectl; SSH into the master node and check the kube-apiserver process. For scheduler issues, check if pending pods exist: kubectl get pods --field-selector=status.phase=Pending. If pods are pending but nodes are available, the scheduler might be stuck. Restarting the scheduler pod often helps.

debug-control-plane.shBASH
1
2
3
4
5
6
7
8
9
10
11
# Check control plane pods
kubectl get pods -n kube-system | grep -E 'apiserver|scheduler|controller|etcd'

# Check API server logs
kubectl logs -n kube-system kube-apiserver-master --tail=50

# Check pending pods
kubectl get pods --all-namespaces --field-selector=status.phase=Pending

# Check etcd cluster health (from master node)
etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/healthcheck-client.crt --key=/etc/kubernetes/pki/etcd/healthcheck-client.key endpoint health
Output
NAME READY STATUS RESTARTS AGE
etcd-master 1/1 Running 0 30d
kube-apiserver-master 1/1 Running 1 30d
kube-controller-manager-master 1/1 Running 0 30d
kube-scheduler-master 1/1 Running 0 30d
https://127.0.0.1:2379 is healthy: successfully committed proposal: took = 2.345ms
💡Certificate Expiry
API server certificates expire after one year by default. Check expiry with kubeadm certs check-expiration or openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -dates.
📊 Production Insight
We once had a cluster-wide outage because the API server certificate expired. The kubelet couldn't authenticate, and all nodes became NotReady. Renewing certificates and restarting kubelet fixed it.
🎯 Key Takeaway
Control plane issues are critical; check pod status and logs in kube-system namespace, and verify etcd health.

6. Networking Troubleshooting: DNS, CNI, and Ingress

Networking issues are notoriously tricky. Common problems: DNS resolution failures, CNI plugin misconfiguration, or Ingress controller not routing traffic. For DNS, check CoreDNS pods: kubectl get pods -n kube-system -l k8s-app=kube-dns. If they are running, test DNS from a pod: kubectl exec -it <pod> -- nslookup kubernetes.default.svc.cluster.local. If DNS fails, check CoreDNS logs and ConfigMap. For CNI issues, check if pods get IPs: kubectl get pods -o wide and see if IPs are assigned. If pods have no IP, the CNI plugin (Calico, Flannel, etc.) might be misconfigured. Check CNI daemonset logs. For Ingress, verify the Ingress resource and controller logs: kubectl logs -n ingress-nginx ingress-nginx-controller-xxxxx.

debug-networking.shBASH
1
2
3
4
5
6
7
8
9
10
11
# Test DNS resolution
kubectl run dns-test --image=busybox --rm -it --restart=Never -- nslookup kubernetes.default.svc.cluster.local

# Check CoreDNS logs
kubectl logs -n kube-system -l k8s-app=kube-dns --tail=20

# Check pod IPs
kubectl get pods -o wide

# Check Ingress controller logs
kubectl logs -n ingress-nginx deployment/ingress-nginx-controller --tail=50
Output
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: kubernetes.default.svc.cluster.local
Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local
NAME READY STATUS RESTARTS AGE IP NODE
my-app-7d4f8b6c9-abcde 1/1 Running 0 1h 10.244.0.5 worker-1
my-app-7d4f8b6c9-xyzde 1/1 Running 0 1h 10.244.1.3 worker-2
🔥CoreDNS Auto-Scaling
If CoreDNS is under heavy load, it may drop queries. Consider using cluster-proportional-autoscaler to scale CoreDNS based on cluster size.
📊 Production Insight
We had a DNS outage because CoreDNS was configured with a small cache and high query rate. Adding more replicas and increasing cache size resolved it.
🎯 Key Takeaway
Networking issues often stem from DNS or CNI; test DNS resolution and check pod IP assignment.

7. Storage Troubleshooting: PersistentVolumeClaims and Mount Issues

Storage issues cause pods to fail to start or become unresponsive. Common problems: PVC stuck in Pending, pod unable to mount volume, or volume permissions errors. Check PVC status: kubectl get pvc. If Pending, the StorageClass might not exist or the provisioner is unavailable. Verify StorageClass: kubectl get storageclass. If the PVC is Bound but pod can't mount, check the pod events: kubectl describe pod <pod>. Common mount errors include wrong filesystem type or permission denied. For NFS or cloud volumes, ensure the node has the necessary drivers. Also check if the volume is already mounted by another pod (ReadWriteOnce). Use kubectl get pv to see the underlying volume.

debug-storage.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
# Check PVC status
kubectl get pvc
kubectl describe pvc my-pvc

# Check StorageClass
kubectl get storageclass

# Check pod events for mount errors
kubectl describe pod my-app-7d4f8b6c9-abcde | grep -A5 Mount

# Check PV details
kubectl get pv
kubectl describe pv pvc-xxxxx
Output
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
my-pvc Bound pvc-abcde-12345 10Gi RWO standard 1h
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 1h default-scheduler Successfully assigned default/my-app-7d4f8b6c9-abcde to worker-1
Warning FailedMount 1h kubelet MountVolume.SetUp failed for volume "pvc-abcde-12345" : rpc error: code = Internal desc = mount failed: exit status 32
Mounting command: mount
Mounting arguments: -t ext4 /dev/disk/by-id/virtio-xxxxx /var/lib/kubelet/pods/.../volumes/...
Output: mount: /var/lib/kubelet/pods/.../volumes/...: wrong fs type, bad option, bad superblock.
⚠ ReadWriteOnce Conflicts
If a PVC is ReadWriteOnce, it can only be mounted by one pod at a time. If multiple pods try to use it, only one will succeed.
📊 Production Insight
We had a pod stuck in ContainerCreating because the volume was formatted as XFS but the node expected ext4. Reformatting the volume resolved it.
🎯 Key Takeaway
Storage issues are often due to missing StorageClass, wrong filesystem, or access mode conflicts; check PVC and pod events.
kubernetes-troubleshooting THECODEFORGE.IO Kubernetes Troubleshooting Stack Layers Component hierarchy from application to infrastructure Application Layer Pods | Deployments | Services Control Plane API Server | Scheduler | Controller Manager Networking Layer CNI Plugin | DNS | Ingress Controller Storage Layer PersistentVolume | PersistentVolumeClaim | StorageClass Node Layer Kubelet | Container Runtime | OS Infrastructure Layer Disk | Memory | Network THECODEFORGE.IO
thecodeforge.io
Kubernetes Troubleshooting

8. Using kubectl Debug and Ephemeral Containers

Kubernetes 1.18+ introduced ephemeral containers for debugging running pods without restarting them. This is invaluable for troubleshooting production issues where you can't modify the pod spec. Use kubectl debug to add an ephemeral container to a running pod. For example, to debug a pod with a network issue: kubectl debug -it <pod> --image=nicolaka/netshoot --target=<container>. The ephemeral container shares the same network namespace, so you can run curl, tcpdump, etc. You can also debug nodes: kubectl debug node/<node> -it --image=busybox. This creates a pod with host access. Ephemeral containers are temporary and removed when the pod is deleted.

debug-ephemeral.shBASH
1
2
3
4
5
6
7
8
9
10
11
# Debug a running pod with netshoot
kubectl debug -it my-app-7d4f8b6c9-abcde --image=nicolaka/netshoot --target=my-app -- sh

# Inside the ephemeral container
curl http://my-service:8080

# Debug a node
kubectl debug node/worker-1 -it --image=busybox -- chroot /host

# Check processes on the node
ps aux | grep kubelet
Output
Defaulting debug container name to debugger-xxxxx.
If you don't see a command prompt, try pressing enter.
/ # curl http://my-service:8080
<html><body><h1>It works!</h1></body></html>
/ # exit
Session ended, ephemeral container deleted.
💡Use Netshoot Image
The nicolaka/netshoot image contains curl, tcpdump, dig, and other network tools. It's the Swiss Army knife for network debugging.
📊 Production Insight
We used ephemeral containers to debug a pod that was crashing every 5 minutes. By attaching netshoot, we ran tcpdump and found a misconfigured database connection pool.
🎯 Key Takeaway
Ephemeral containers allow debugging without restarting pods; use kubectl debug for network and node issues.

9. Logging and Monitoring: Centralized Logs and Metrics

Centralized logging and monitoring are essential for proactive troubleshooting. Use tools like Prometheus for metrics and Loki/Elasticsearch for logs. In Kubernetes, common patterns: Fluentd or Filebeat to ship logs, and Prometheus Operator for metrics. For quick ad-hoc monitoring, use kubectl top to see resource usage: kubectl top pods and kubectl top nodes. If metrics aren't available, ensure metrics-server is installed. For logs, use kubectl logs --tail=100 --follow for real-time streaming. In production, set up alerts for common failure modes: pod restarts, node pressure, and API server latency. Use kubectl get events --watch to monitor cluster events in real-time.

monitoring.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
# Check resource usage
kubectl top pods
kubectl top nodes

# Stream logs from multiple pods
kubectl logs -l app=my-app --tail=10 --follow

# Watch cluster events
kubectl get events --watch --all-namespaces

# Check metrics-server
kubectl get deployment metrics-server -n kube-system
Output
NAME CPU(cores) MEMORY(bytes)
my-app-7d4f8b6c9-abcde 25m 128Mi
my-app-7d4f8b6c9-xyzde 30m 140Mi
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
master 500m 25% 2Gi 50%
worker-1 1.2Gi 60% 8Gi 80%
Events:
...
🔥Metrics-Server Required
kubectl top requires metrics-server to be installed. If not present, deploy it: kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml.
📊 Production Insight
We set up Prometheus alerts for pod restarts and node disk pressure. This caught a memory leak before it caused a full outage.
🎯 Key Takeaway
Centralized logging and metrics are crucial for proactive troubleshooting; use kubectl top and log streaming for quick insights.

10. Common Pitfalls and Anti-Patterns

Avoid these common mistakes: 1) Ignoring resource limits — pods without limits can starve other pods. 2) Using latest tag — leads to unpredictable behavior. 3) Not setting pod disruption budgets — causes downtime during node maintenance. 4) Overlooking network policies — default allow-all can be a security risk. 5) Skipping health checks — liveness and readiness probes prevent routing traffic to unhealthy pods. 6) Using hostNetwork without understanding the implications. 7) Not backing up etcd — without backups, cluster recovery is impossible. 8) Manually editing pods — always use deployments. 9) Ignoring pod anti-affinity — can cause all replicas to land on the same node. 10) Not using namespaces — leads to resource conflicts.

resource-limits.yamlYAML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
apiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  containers:
  - name: my-app
    image: my-app:1.0.0
    resources:
      requests:
        memory: "256Mi"
        cpu: "250m"
      limits:
        memory: "512Mi"
        cpu: "500m"
    livenessProbe:
      httpGet:
        path: /healthz
        port: 8080
      initialDelaySeconds: 5
      periodSeconds: 10
    readinessProbe:
      httpGet:
        path: /ready
        port: 8080
      initialDelaySeconds: 5
      periodSeconds: 10
⚠ Always Set Resource Limits
Without limits, a single pod can consume all node resources, causing other pods to be evicted. Always set both requests and limits.
📊 Production Insight
We once had a production outage because a developer used latest tag and the image was overwritten with a broken version. Pinning to a specific tag prevented recurrence.
🎯 Key Takeaway
Avoid common anti-patterns: set resource limits, use specific tags, configure probes, and backup etcd.

11. Advanced Troubleshooting: Using kubectl plugin and krew

Kubectl plugins extend its functionality. Install krew, the plugin manager: kubectl krew install <plugin>. Essential plugins: kubectl-neat to clean up YAML output, kubectl-tree to show resource ownership hierarchy, kubectl-oom to find pods killed by OOM, kubectl-whisper for secret management, and kubectl-sniff to capture network traffic. For example, kubectl sniff <pod> -p <port> starts a remote tcpdump. kubectl oom lists pods that have been OOMKilled. These plugins save time and provide deeper insights. To install krew: kubectl krew install sniff oom tree neat.

install-plugins.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Install krew (if not installed)
(
  set -x; cd "$(mktemp -d)" &&
  OS="$(uname | tr '[:upper:]' '[:lower:]')" &&
  ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/arm64/aarch64/')" &&
  KREW="krew-${OS}_${ARCH}" &&
  curl -fsSLO "https://github.com/kubernetes-sigs/krew/releases/latest/download/${KREW}.tar.gz" &&
  tar zxvf "${KREW}.tar.gz" &&
  ./"${KREW}" install krew
)

# Add krew to PATH
export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH"

# Install plugins
kubectl krew install sniff oom tree neat

# Use plugins
kubectl sniff my-pod -p 8080
kubectl oom
kubectl tree deployment my-app
Output
Installing plugin: sniff
Installed plugin: sniff
Installing plugin: oom
Installed plugin: oom
Installing plugin: tree
Installed plugin: tree
Installing plugin: neat
Installed plugin: neat
💡kubectl-sniff for Network Debugging
kubectl sniff runs tcpdump remotely on the pod and streams the output to Wireshark on your local machine. Great for debugging network issues.
📊 Production Insight
Using kubectl sniff, we captured traffic between a pod and a database and found the app was sending malformed queries, causing high latency.
🎯 Key Takeaway
Kubectl plugins via krew extend troubleshooting capabilities; install sniff, oom, tree, and neat for advanced debugging.
kubectl Debug vs Ephemeral Containers Comparison of debugging approaches in Kubernetes kubectl Debug Ephemeral Containers Purpose Create debugging pod Add container to running pod Persistence Temporary pod Ephemeral container in pod Network Namespace Shared with target pod Same as target pod Tool Availability Custom image with tools Any image with tools Kubernetes Version v1.18+ v1.23+ (alpha) Use Case Debugging without affecting pod Debugging inside running pod THECODEFORGE.IO
thecodeforge.io
Kubernetes Troubleshooting

12. Building a Troubleshooting Runbook

A runbook standardizes troubleshooting steps, reducing MTTR. Start with a decision tree: Is the issue pod-level? Node-level? Cluster-level? For each, list commands and expected outputs. Include sections for common scenarios: CrashLoopBackOff, service unreachable, node NotReady, etc. Document escalation paths and contact information. Use tools like Backstage or GitBook to host the runbook. Keep it version-controlled and update it after every incident. Example structure: 1) Initial checks (events, top, describe), 2) Pod issues (logs, previous, debug), 3) Service issues (endpoints, connectivity), 4) Node issues (conditions, disk, kubelet), 5) Control plane (apiserver, etcd), 6) Escalation. Automate common checks with scripts or chatbots.

runbook-template.yamlYAML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Runbook: Pod CrashLoopBackOff
# Step 1: Check events
kubectl get events --field-selector involvedObject.kind=Pod --sort-by='.lastTimestamp'
# Step 2: Describe pod
kubectl describe pod <pod-name>
# Step 3: Check logs
kubectl logs <pod-name> --previous
# Step 4: Check resource usage
kubectl top pod <pod-name>
# Step 5: Check node resources
kubectl top node <node-name>
# Step 6: If image pull issue, check secret
kubectl get secret <image-pull-secret>
# Step 7: If all else fails, escalate to SRE team
# Contact: #sre-oncall
🔥Automate with ChatOps
Integrate your runbook with Slack or Teams using chatbots. For example, a bot can run kubectl describe and return results when you type /k8s describe pod my-pod.
📊 Production Insight
After a major outage, we created a runbook with exact commands and expected outputs. New team members could resolve issues in minutes instead of hours.
🎯 Key Takeaway
A well-structured runbook reduces MTTR; document step-by-step procedures for common issues and keep it version-controlled.
⚙ Quick Reference
12 commands from this guide
FileCommand / CodePurpose
check-events.shkubectl get events --all-namespaces --sort-by='.lastTimestamp' | tail -201. Understanding the Kubernetes Troubleshooting Hierarchy
debug-pod.shkubectl describe pod my-app-7d4f8b6c9-abcde2. Diagnosing Pod Failures
debug-service.shkubectl get svc my-service3. Debugging Services and Endpoints
debug-node.shkubectl get nodes4. Node-Level Troubleshooting
debug-control-plane.shkubectl get pods -n kube-system | grep -E 'apiserver|scheduler|controller|etcd'5. Control Plane Troubleshooting
debug-networking.shkubectl run dns-test --image=busybox --rm -it --restart=Never -- nslookup kubern...6. Networking Troubleshooting
debug-storage.shkubectl get pvc7. Storage Troubleshooting
debug-ephemeral.shkubectl debug -it my-app-7d4f8b6c9-abcde --image=nicolaka/netshoot --target=my-a...8. Using kubectl Debug and Ephemeral Containers
monitoring.shkubectl top pods9. Logging and Monitoring
resource-limits.yamlapiVersion: v110. Common Pitfalls and Anti-Patterns
install-plugins.sh(11. Advanced Troubleshooting
runbook-template.yamlkubectl get events --field-selector involvedObject.kind=Pod --sort-by='.lastTime...12. Building a Troubleshooting Runbook

Key takeaways

1
Follow the hierarchy
Start troubleshooting from pods, then services, nodes, and control plane to isolate root causes efficiently.
2
Use kubectl describe and logs
These commands provide the most immediate insight into failures; always check events and previous logs.
3
Leverage ephemeral containers
Debug running pods without restarting them using kubectl debug with tools like netshoot.
4
Build and maintain a runbook
Standardize troubleshooting steps to reduce MTTR and ensure consistency across the team.
INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01JUNIOR
What is the first command I should run when a pod is failing?
Q02JUNIOR
How do I debug a service that is not reachable?
Q03JUNIOR
What causes ImagePullBackOff and how do I fix it?
Q01 of 03JUNIOR

What is the first command I should run when a pod is failing?

ANSWER
Run kubectl describe pod <pod-name> to see events and status, then kubectl logs <pod-name> --previous to get the last crash log.
FAQ · 6 QUESTIONS

Frequently Asked Questions

01
What is the first command I should run when a pod is failing?
02
How do I debug a service that is not reachable?
03
What causes ImagePullBackOff and how do I fix it?
04
How do I troubleshoot a node that is NotReady?
05
What is the best way to debug network issues in a pod?
06
How do I recover from an etcd failure?
N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Notes here come from systems that actually shipped.

Follow
Verified
production tested
July 12, 2026
last updated
2,073
articles · all by Naren
🔥

That's Kubernetes. Mark it forged?

5 min read · try the examples if you haven't

Previous
Kubernetes Security — Pod Security Standards and PSA
31 / 38 · Kubernetes
Next
Kubernetes Namespaces and ResourceQuotas