Kubernetes Debugging Skill
Inspect pod logs, analyze resource quotas, trace network policies, check deployment rollout status, run cluster health checks for Kubernetes. Use this skill when diagnosing Kubernetes cluster issues, debugging failing pods, investigating network connectivity problems, analyzing resource usage, troubleshooting deployments, performing cluster health checks.
npx skills add github:pantheon-org/tekhne --skill infrastructure--k8s--debugMindset
Mental Model: Kubernetes debugging follows a layered approach—start broad (cluster health), narrow to affected components (pods, services), then drill into specific failures (logs, events, resource constraints). A pod’s status is always a summary, never the diagnosis — CrashLoopBackOff and ImagePullBackOff name the symptom, not the root cause, and you must read events and logs before acting on the label alone.
Decision Framework:
- Gather context before jumping to solutions. Check
kubectl get eventsanddescriberesources first — this step is mandatory, never optional, even when the fix seems obvious. - Verify assumptions about selectors, labels, and namespaces—label mismatches are the most common root cause and must never be assumed away.
- Test hypotheses systematically: network → resource → configuration → application.
- Document findings as you go—Kubernetes issues often involve multiple interacting failures, and an undocumented fix is one nobody else can verify. A common pitfall: treating a restart as a fix when it only cleared a transient symptom — the same gotcha resurfaces on the next scheduling cycle if the root cause was never found.
When to use this skill:
- Pods stuck in Pending, CrashLoopBackOff, ImagePullBackOff, or Error states
- Services not routing traffic despite healthy pods
- Resource exhaustion (OOMKilled, CPU throttling)
- Deployments failing to roll out or stuck in progress
- Network policies blocking expected traffic
When NOT to use this skill:
- The failure is already fully explained by a known recent change (a deploy minutes ago introduced a bad config) — roll back directly rather than running the full diagnostic funnel.
- The question is capacity planning (steady-state resource sizing, autoscaler tuning) rather than an active failure — that is a design decision, not a debugging session.
- You lack read access to the affected namespace — request access first; guessing from an adjacent namespace produces false leads.
Quick Diagnostic Patterns
Pod Not Starting
# Quick assessment
kubectl get pod <pod-name> -n <namespace>
kubectl describe pod <pod-name> -n <namespace> # Events section is key
# Detailed diagnostics
python3 scripts/pod_diagnostics.py <pod-name> -n <namespace>
# Check previous logs if CrashLoopBackOff
kubectl logs <pod-name> -n <namespace> --previous
Service Connectivity Issues
# Verify service endpoints match pod IPs
kubectl get svc <service-name> -n <namespace>
kubectl get endpoints <service-name> -n <namespace>
# Network diagnostics
./scripts/network_debug.sh <namespace> <pod-name>
# Test from debug pod
kubectl run tmp-shell --rm -i --tty --image nicolaka/netshoot -- /bin/bash
Performance Degradation
# Resource usage by container
kubectl top pods -n <namespace> --containers
# Check for OOMKilled
kubectl get pod <pod-name> -n <namespace> -o yaml | grep -A 10 lastState
# Review recent logs
kubectl logs <pod-name> -n <namespace> --tail=100 --timestamps
Cluster Health Check
# Comprehensive health report
./scripts/cluster_health.sh > cluster-health-$(date +%Y%m%d-%H%M%S).txt
Key Debugging Commands
Focus on non-obvious flags and patterns most useful during debugging:
Pod Debugging
# Cross-namespace pod overview
kubectl get pods -A -o wide --field-selector=status.phase!=Running
# Previous container logs (post-crash)
kubectl logs <pod-name> -n <namespace> --previous
# Multi-container pod: target specific container
kubectl logs <pod-name> -n <namespace> -c <container>
# Stream logs with timestamps
kubectl logs <pod-name> -n <namespace> -f --timestamps
# Describe for Events section — most useful first stop
kubectl describe pod <pod-name> -n <namespace>
# Full pod YAML including status conditions
kubectl get pod <pod-name> -n <namespace> -o yaml
Service and Network Debugging
# Confirm endpoint IPs match running pod IPs (label selector mismatch shows empty)
kubectl get endpoints <service-name> -n <namespace>
# Test DNS from within the cluster
kubectl exec <pod-name> -n <namespace> -- nslookup kubernetes.default
# Sort events by time to find recent failures
kubectl get events -n <namespace> --sort-by='.lastTimestamp'
Resource Monitoring
# Per-container resource usage (reveals which container is the culprit)
kubectl top pod <pod-name> -n <namespace> --containers
# Resource quota consumption vs. limits
kubectl describe resourcequota -n <namespace>
Emergency Operations
⚠️ These commands are destructive or disruptive. Follow the verification steps before and after each operation.
Restart Deployment
# Verify current rollout state first
kubectl rollout status deployment/<name> -n <namespace>
# Restart
kubectl rollout restart deployment/<name> -n <namespace>
# Verify rollout completes successfully
kubectl rollout status deployment/<name> -n <namespace> --timeout=120s
Rollback Deployment
# Check rollout history to pick the correct revision
kubectl rollout history deployment/<name> -n <namespace>
# Rollback to previous revision
kubectl rollout undo deployment/<name> -n <namespace>
# Confirm rollback success and pods are running
kubectl rollout status deployment/<name> -n <namespace>
kubectl get pods -n <namespace> -l app=<name>
Force Delete Stuck Pod
# Confirm the pod is genuinely stuck (not just slow to terminate)
kubectl get pod <pod-name> -n <namespace> -w # Watch for 60s before proceeding
# Force delete only if pod remains Terminating with no progress
kubectl delete pod <pod-name> -n <namespace> --force --grace-period=0
# Verify the pod is gone and not rescheduled with an error state
kubectl get pod <pod-name> -n <namespace>
Drain Node (Maintenance)
# Review what will be evicted before draining
kubectl get pods --all-namespaces --field-selector spec.nodeName=<node-name>
# Cordon first to prevent new scheduling
kubectl cordon <node-name>
# Drain (evicts pods gracefully)
kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data
# Verify node is drained and no workloads remain
kubectl get pods --all-namespaces --field-selector spec.nodeName=<node-name>
# After maintenance, uncordon to restore scheduling
kubectl uncordon <node-name>
kubectl get node <node-name> # Confirm status returns to Ready
Common Anti-Patterns
NEVER: Jump to Solutions Without Context
BAD:
# Immediately restarting without investigation
kubectl rollout restart deployment/app
GOOD:
# Gather diagnostic context first
kubectl describe deployment/app
kubectl get events --sort-by='.lastTimestamp' | tail -20
kubectl logs -l app=app --tail=50
# THEN decide if restart is appropriate
NEVER: Ignore Namespace Context
BAD:
# Assuming default namespace
kubectl get pods
kubectl logs my-pod
GOOD:
# Always specify namespace explicitly
kubectl get pods -n production
kubectl logs my-pod -n production
# Or use -A to search all namespaces
kubectl get pods -A | grep my-pod
NEVER: Force Delete as First Resort
BAD:
# Immediate force delete
kubectl delete pod stuck-pod --force --grace-period=0
GOOD:
# Investigate why pod is stuck first
kubectl describe pod stuck-pod
kubectl get pod stuck-pod -o yaml | grep -A 10 finalizers
# Try normal delete first
kubectl delete pod stuck-pod
# Wait 60s, watch for termination
# Force delete only if confirmed stuck
NEVER: Debug in Production Directly
BAD:
# Exec into production pod and make changes
kubectl exec -it prod-pod -- /bin/bash
GOOD:
# Create debug copy for investigation
kubectl debug prod-pod --copy-to=debug-pod --share-processes
# Or use ephemeral debug container (K8s 1.23+)
kubectl debug prod-pod -it --image=nicolaka/netshoot
ALWAYS: Check Labels and Selectors First
Service connectivity issues are almost always label mismatches:
# Verify service selector matches pod labels
kubectl get svc my-service -o jsonpath='{.spec.selector}'
kubectl get pods -l app=my-app --show-labels
kubectl get endpoints my-service # Should show pod IPs
ALWAYS: Use –previous Flag for CrashLoopBackOff
# Current logs may be empty if container crashed immediately
kubectl logs failing-pod --previous
Advanced Debugging Techniques
Debug Containers (Kubernetes 1.23+)
# Attach ephemeral debug container
kubectl debug <pod-name> -n <namespace> -it --image=nicolaka/netshoot
# Create debug copy of pod
kubectl debug <pod-name> -n <namespace> -it --copy-to=<debug-pod-name> --container=<container>
Port Forwarding for Testing
# Forward pod port to local machine
kubectl port-forward pod/<pod-name> -n <namespace> <local-port>:<pod-port>
# Forward service port
kubectl port-forward svc/<service-name> -n <namespace> <local-port>:<service-port>
Proxy for API Access
# Start kubectl proxy
kubectl proxy --port=8080
# Access API
curl http://localhost:8080/api/v1/namespaces/<namespace>/pods/<pod-name>
Custom Column Output
# Custom pod info
kubectl get pods -o custom-columns=NAME:.metadata.name,STATUS:.status.phase,IP:.status.podIP
# Node taints
kubectl get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints
Verification and Validation
After any debugging intervention:
-
Confirm the fix: Don’t assume—verify pods are Running and Ready
kubectl get pods -n <namespace> -w kubectl rollout status deployment/<name> -
Check for side effects: Ensure fix didn’t break other components
kubectl get events --sort-by='.lastTimestamp' | tail -20 -
Test functionality: Validate the application works end-to-end
kubectl port-forward svc/<service> 8080:80 curl http://localhost:8080/healthz -
Document the root cause: Add annotations to resources for future reference
kubectl annotate deployment/<name> debug.issue="ImagePullBackOff due to missing secret"
Anti-Patterns
NEVER exec into a running production pod before checking logs
- WHY: Interactive exec changes the live state and may affect running workloads; logs and describe output are safe to read without impact and usually contain the root cause.
- BAD: Immediately running
kubectl exec -it pod-name -- bashon a production pod for any issue. - GOOD: Start with
kubectl logs pod-name --previousandkubectl describe pod pod-nameto gather context before considering exec.
NEVER delete and recreate pods to fix issues without understanding the cause
- WHY: Blindly recycling pods hides the root cause and may leave a resource in a broken state for the next incident.
- BAD:
kubectl delete pod pod-nameas a first troubleshooting step. - GOOD: Diagnose with logs and events first; identify whether the issue is a crash loop, OOM kill, config error, or node failure before taking corrective action.
NEVER use kubectl get pods without -n or --all-namespaces in multi-tenant clusters
- WHY: Missing pods often means you are looking in the wrong namespace; always specify scope explicitly to avoid false negatives.
- BAD:
kubectl get podsreturning “No resources found” and assuming the workload does not exist. - GOOD:
kubectl get pods -n <namespace>orkubectl get pods -A | grep <app>
NEVER port-forward to a single pod as a proxy for full service testing
- WHY: Port-forwarding targets one pod; issues may be pod-specific or service-routing-specific and require testing both paths independently.
- BAD: Testing all application behavior via
kubectl port-forward pod/name 8080:80and assuming the result represents the service. - GOOD: Use pod port-forward to isolate pod-specific behavior; use
kubectl port-forward svc/<name>to test service routing separately.
References
Detailed Troubleshooting Guides
See references/troubleshooting_workflow.md for:
- Step-by-step workflows for each issue type
- Decision trees for diagnosis
- Command sequences for systematic debugging
- Quick reference command cheat sheet
Common Issues Database
See references/common_issues.md for:
- Detailed explanations of each common issue (ImagePullBackOff, CrashLoopBackOff, OOMKilled, etc.)
- Symptoms and root causes
- Specific debugging steps
- Solutions and fixes
- Prevention strategies
Explicit NEVER/WHY/consequence triplets with side-by-side bad/good examples. Generic warnings score low — concrete failure modes with real impact (security, correctness, performance) score high.
Runtime validation via eval scenarios proving the skill actually changes agent behaviour. Requires evals/ directory, instructions.json, ≥3 scenarios, and ≥80% instruction coverage in summary.json.
Appropriate rigidity for the skill type: strict rules for critical/security skills, balanced steps for process skills, flexible options for tool skills. Mismatched calibration (too rigid or too loose) reduces score.
Expert-only knowledge the AI couldn't derive on its own — domain-specific patterns, production gotchas, decision frameworks, and non-obvious tool behaviour. High scores mean <5% redundancy with what the model already knows.
A clear philosophy plus numbered step-by-step workflows with explicit entry/exit points. Should answer: what is the core principle, how to execute it, and when (and when not) to apply it.
Rich activation keywords and trigger scenarios in the description so the skill fires when needed. Best descriptions read like an exhaustive list of the tasks and concepts that should invoke this skill.
Copy-paste-ready code, complete runnable examples, real file paths and commands. Pseudocode and abstract descriptions score low — concrete, executable content scores high.
SKILL.md as a <100-line navigation hub pointing to focused references/ files. Content should be lazy-loaded on demand, not front-loaded. Includes actionable 'When to Use' conditions per reference.
Proper frontmatter, single-task focus, activation keywords, and cross-harness portability. Skills must work across 40+ agentic harnesses without hardcoded paths or agent-specific references.
Explicit NEVER/WHY/consequence triplets with side-by-side bad/good examples. Generic warnings score low — concrete failure modes with real impact (security, correctness, performance) score high.
Runtime validation via eval scenarios proving the skill actually changes agent behaviour. Requires evals/ directory, instructions.json, ≥3 scenarios, and ≥80% instruction coverage in summary.json.
Appropriate rigidity for the skill type: strict rules for critical/security skills, balanced steps for process skills, flexible options for tool skills. Mismatched calibration (too rigid or too loose) reduces score.
Expert-only knowledge the AI couldn't derive on its own — domain-specific patterns, production gotchas, decision frameworks, and non-obvious tool behaviour. High scores mean <5% redundancy with what the model already knows.
A clear philosophy plus numbered step-by-step workflows with explicit entry/exit points. Should answer: what is the core principle, how to execute it, and when (and when not) to apply it.
Rich activation keywords and trigger scenarios in the description so the skill fires when needed. Best descriptions read like an exhaustive list of the tasks and concepts that should invoke this skill.
Copy-paste-ready code, complete runnable examples, real file paths and commands. Pseudocode and abstract descriptions score low — concrete, executable content scores high.
SKILL.md as a <100-line navigation hub pointing to focused references/ files. Content should be lazy-loaded on demand, not front-loaded. Includes actionable 'When to Use' conditions per reference.
Proper frontmatter, single-task focus, activation keywords, and cross-harness portability. Skills must work across 40+ agentic harnesses without hardcoded paths or agent-specific references.
Expert-only knowledge the AI couldn't derive on its own — domain-specific patterns, production gotchas, decision frameworks, and non-obvious tool behaviour. High scores mean <5% redundancy with what the model already knows.
A clear philosophy plus numbered step-by-step workflows with explicit entry/exit points. Should answer: what is the core principle, how to execute it, and when (and when not) to apply it.
Explicit NEVER/WHY/consequence triplets with side-by-side bad/good examples. Generic warnings score low — concrete failure modes with real impact (security, correctness, performance) score high.
Proper frontmatter, single-task focus, activation keywords, and cross-harness portability. Skills must work across 40+ agentic harnesses without hardcoded paths or agent-specific references.
SKILL.md as a <100-line navigation hub pointing to focused references/ files. Content should be lazy-loaded on demand, not front-loaded. Includes actionable 'When to Use' conditions per reference.
Appropriate rigidity for the skill type: strict rules for critical/security skills, balanced steps for process skills, flexible options for tool skills. Mismatched calibration (too rigid or too loose) reduces score.
Rich activation keywords and trigger scenarios in the description so the skill fires when needed. Best descriptions read like an exhaustive list of the tasks and concepts that should invoke this skill.
Copy-paste-ready code, complete runnable examples, real file paths and commands. Pseudocode and abstract descriptions score low — concrete, executable content scores high.
Runtime validation via eval scenarios proving the skill actually changes agent behaviour. Requires evals/ directory, instructions.json, ≥3 scenarios, and ≥80% instruction coverage in summary.json.
No eval scenarios available.
Common Kubernetes Issues and Troubleshooting
Pod Issues
CrashLoopBackOff
Symptoms:
- Pod repeatedly crashes and restarts
- Status shows
CrashLoopBackOff - Increasing restart count
Common Causes:
- Application error causing immediate exit
- Missing environment variables or configuration
- Insufficient resources (memory/CPU)
- Failed health checks (liveness probe)
- Missing dependencies or volumes
Debugging Steps:
# Check pod events
kubectl describe pod <pod-name> -n <namespace>
# View current logs
kubectl logs <pod-name> -n <namespace>
# View previous container logs (from crashed container)
kubectl logs <pod-name> -n <namespace> --previous
# Check resource limits
kubectl get pod <pod-name> -n <namespace> -o yaml | grep -A 5 resources
# Check liveness/readiness probes
kubectl get pod <pod-name> -n <namespace> -o yaml | grep -A 10 livenessProbe
Solutions:
- Fix application code causing crashes
- Add missing environment variables via ConfigMap/Secret
- Increase resource limits
- Adjust or remove overly aggressive liveness probes
- Ensure all required volumes are mounted and accessible
ImagePullBackOff / ErrImagePull
Symptoms:
- Pod status shows
ImagePullBackOfforErrImagePull - Pod fails to start
- Events show image pull errors
Common Causes:
- Image doesn’t exist or wrong image name/tag
- Private registry requires authentication
- Network issues accessing registry
- Image pull secrets missing or incorrect
- Registry rate limiting
Debugging Steps:
# Check exact error message
kubectl describe pod <pod-name> -n <namespace>
# Verify image name and tag
kubectl get pod <pod-name> -n <namespace> -o yaml | grep image:
# Check image pull secrets
kubectl get pod <pod-name> -n <namespace> -o yaml | grep imagePullSecrets -A 2
# List secrets in namespace
kubectl get secrets -n <namespace>
# Test image pull manually on node
docker pull <image-name>
Solutions:
- Verify image exists in registry:
docker pull <image> - Create image pull secret:
kubectl create secret docker-registry <secret-name> --docker-server=<registry> --docker-username=<user> --docker-password=<pass> - Add imagePullSecrets to pod spec
- Use correct image tag (avoid
latestin production) - Check registry credentials and permissions
Pending Pods
Symptoms:
- Pod stuck in
Pendingstate - Pod never gets scheduled
Common Causes:
- Insufficient cluster resources (CPU/memory)
- No nodes match pod’s node selector
- Taints on nodes prevent scheduling
- PersistentVolumeClaim not bound
- Pod affinity/anti-affinity rules cannot be satisfied
Debugging Steps:
# Check scheduling events
kubectl describe pod <pod-name> -n <namespace>
# Check node resources
kubectl top nodes
kubectl describe nodes
# Check PVC status
kubectl get pvc -n <namespace>
# Check node selectors and taints
kubectl get pod <pod-name> -n <namespace> -o yaml | grep -A 5 nodeSelector
kubectl get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints
Solutions:
- Add more nodes to cluster or free up resources
- Remove/adjust node selectors
- Add tolerations for taints
- Create or fix PersistentVolume for PVC
- Adjust affinity/anti-affinity rules
- Check resource quotas:
kubectl get resourcequota -n <namespace>
OOMKilled (Out of Memory)
Symptoms:
- Pod restarts with exit code 137
- Last state shows
OOMKilled - Container was killed due to memory
Debugging Steps:
# Check pod status and last state
kubectl get pod <pod-name> -n <namespace> -o yaml | grep -A 10 lastState
# Check memory limits
kubectl get pod <pod-name> -n <namespace> -o yaml | grep -A 5 resources
# Check actual memory usage
kubectl top pod <pod-name> -n <namespace> --containers
Solutions:
- Increase memory limits
- Fix memory leaks in application
- Optimize application memory usage
- Add memory requests/limits if missing
Service and Networking Issues
Service Not Accessible
Symptoms:
- Cannot connect to service from within or outside cluster
- Connection timeout or refused
Common Causes:
- Service selector doesn’t match pod labels
- Target port mismatch
- Network policies blocking traffic
- Service type incorrect (ClusterIP vs LoadBalancer)
- Endpoints not created
Debugging Steps:
# Check service configuration
kubectl get svc <service-name> -n <namespace> -o yaml
# Check endpoints
kubectl get endpoints <service-name> -n <namespace>
# Check pod labels
kubectl get pods -n <namespace> --show-labels
# Test from another pod
kubectl run tmp-shell --rm -i --tty --image nicolaka/netshoot -- /bin/bash
# Inside pod: curl <service-name>.<namespace>.svc.cluster.local
# Check network policies
kubectl get networkpolicies -n <namespace>
Solutions:
- Ensure service selector matches pod labels exactly
- Verify port and targetPort are correct
- Check network policies allow traffic
- Use correct service type for use case
- Ensure pods are running and ready
DNS Resolution Failures
Symptoms:
- Pods cannot resolve service names
nslookupordigcommands fail- DNS timeouts
Common Causes:
- CoreDNS not running properly
- DNS service not accessible
- Pod DNS config incorrect
- Network policies blocking DNS
Debugging Steps:
# Check CoreDNS pods
kubectl get pods -n kube-system -l k8s-app=kube-dns
# Check CoreDNS logs
kubectl logs -n kube-system -l k8s-app=kube-dns
# Test DNS from pod
kubectl exec <pod-name> -n <namespace> -- nslookup kubernetes.default
# Check pod DNS config
kubectl exec <pod-name> -n <namespace> -- cat /etc/resolv.conf
# Check DNS service
kubectl get svc -n kube-system kube-dns
Solutions:
- Restart CoreDNS:
kubectl rollout restart deployment/coredns -n kube-system - Verify DNS service endpoints exist
- Check network policies allow port 53
- Verify kubelet DNS settings
Volume and Storage Issues
PersistentVolumeClaim Pending
Symptoms:
- PVC stuck in
Pendingstate - Pod cannot start due to volume mount
Debugging Steps:
# Check PVC status
kubectl describe pvc <pvc-name> -n <namespace>
# List available PVs
kubectl get pv
# Check storage class
kubectl get storageclass
Solutions:
- Create matching PersistentVolume
- Verify storage class exists and is correct
- Check volume provisioner is working
- Ensure sufficient storage available
Resource and Configuration Issues
ConfigMap/Secret Not Found
Symptoms:
- Pod fails to start
- Events show volume mount errors
- Missing environment variables
Debugging Steps:
# List ConfigMaps
kubectl get configmaps -n <namespace>
# List Secrets
kubectl get secrets -n <namespace>
# Check pod configuration
kubectl get pod <pod-name> -n <namespace> -o yaml | grep -A 10 env
Solutions:
- Create missing ConfigMap/Secret
- Verify names match exactly (case-sensitive)
- Check namespace matches
- Ensure keys referenced exist in ConfigMap/Secret
Performance Issues
High CPU/Memory Usage
Debugging Steps:
# Check resource usage
kubectl top nodes
kubectl top pods -n <namespace>
# Check resource requests/limits
kubectl describe pod <pod-name> -n <namespace> | grep -A 5 Limits
# Get detailed metrics
kubectl get --raw /apis/metrics.k8s.io/v1beta1/namespaces/<namespace>/pods/<pod-name>
Solutions:
- Optimize application code
- Adjust resource requests/limits
- Scale horizontally with more replicas
- Implement caching or performance improvements
Deployment Issues
Deployment Stuck/Not Rolling Out
Symptoms:
- New version not deployed
- Old pods still running
- Rollout stuck
Debugging Steps:
# Check rollout status
kubectl rollout status deployment/<deployment-name> -n <namespace>
# Check rollout history
kubectl rollout history deployment/<deployment-name> -n <namespace>
# Check replica sets
kubectl get rs -n <namespace>
# Check events
kubectl get events -n <namespace> --sort-by='.lastTimestamp'
Solutions:
- Check if new pods are failing (CrashLoopBackOff, ImagePullBackOff)
- Verify readiness probes are passing
- Check deployment strategy settings
- Rollback if needed:
kubectl rollout undo deployment/<deployment-name> -n <namespace>
Kubernetes Troubleshooting Workflows
General Debugging Workflow
When facing any Kubernetes issue, follow this systematic approach:
1. Identify the Problem Layer
Kubernetes issues typically fall into these categories:
Application Layer → Application crashes, errors, bugs
Pod Layer → Pod not starting, restarting, pending
Service Layer → Network connectivity, DNS issues
Node Layer → Node not ready, resource exhaustion
Cluster Layer → Control plane issues, API problems
Storage Layer → Volume mount failures, PVC issues
Configuration Layer → ConfigMap, Secret, RBAC issues
2. Gather Initial Information
# What's the current state?
kubectl get pods -n <namespace>
kubectl get events -n <namespace> --sort-by='.lastTimestamp'
# Quick status check
kubectl describe pod <pod-name> -n <namespace>
3. Drill Down Based on State
Follow the appropriate workflow based on pod state:
- Pending → Resource/Scheduling Workflow
- ImagePullBackOff → Image Pull Workflow
- CrashLoopBackOff → Application Crash Workflow
- Running but not working → Service/Network Workflow
- Error/Unknown → Node/Cluster Workflow
Pod Lifecycle Troubleshooting
Pod Pending Workflow
1. kubectl describe pod → Check events section
↓
2. Check scheduling issues:
- Insufficient resources? → kubectl top nodes
- Node selector issues? → Check nodeSelector in pod spec
- Taints/tolerations? → kubectl get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints
- PVC pending? → kubectl get pvc -n <namespace>
↓
3. Take action:
- Add nodes or free resources
- Adjust node selector
- Add tolerations
- Fix PVC/PV binding
Pod CrashLoopBackOff Workflow
1. kubectl logs <pod> --previous
↓
2. Analyze crash reason:
- Application error? → Fix code/config
- Missing dependencies? → Check env vars, volumes, secrets
- Resource limits? → kubectl describe pod → Check OOMKilled
- Failed health checks? → Check liveness/readiness probe settings
↓
3. Common checks:
kubectl get pod <pod> -o yaml | grep -A 10 env
kubectl get pod <pod> -o yaml | grep -A 10 volumeMounts
kubectl get pod <pod> -o yaml | grep -A 10 livenessProbe
↓
4. Fix and verify:
- Update deployment/pod spec
- kubectl apply -f updated-config.yaml
- Watch: kubectl get pods -w
Pod ImagePullBackOff Workflow
1. kubectl describe pod → Find exact error
↓
2. Verify image:
- Does image exist? → docker pull <image> (test locally)
- Correct tag? → Check deployment spec
- Private registry? → Check imagePullSecrets
↓
3. Fix authentication (if needed):
kubectl create secret docker-registry <secret> \
--docker-server=<server> \
--docker-username=<user> \
--docker-password=<pass>
↓
4. Update pod spec with imagePullSecrets
↓
5. Verify:
kubectl get pods -w
Network Troubleshooting Workflow
Service Connectivity Workflow
1. Verify service exists:
kubectl get svc <service-name> -n <namespace>
↓
2. Check endpoints:
kubectl get endpoints <service-name> -n <namespace>
↓
No endpoints? → Check selector matches pod labels
↓
3. Test DNS resolution:
kubectl run tmp-shell --rm -i --tty --image nicolaka/netshoot -- /bin/bash
nslookup <service-name>.<namespace>.svc.cluster.local
↓
DNS fails? → Check CoreDNS pods and logs
↓
4. Test connectivity:
curl <service-name>.<namespace>.svc.cluster.local:<port>
↓
Connection fails? → Check:
- Network policies: kubectl get networkpolicies -n <namespace>
- Target port matches pod port
- Pod is ready: kubectl get pods -n <namespace>
↓
5. Check from outside cluster (if applicable):
- LoadBalancer service? → Check external IP assigned
- Ingress? → kubectl get ingress -n <namespace>
- NodePort? → Access via <node-ip>:<nodePort>
DNS Issues Workflow
1. Test DNS from problem pod:
kubectl exec <pod> -n <namespace> -- nslookup kubernetes.default
↓
2. Check CoreDNS health:
kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl logs -n kube-system -l k8s-app=kube-dns
↓
3. Verify DNS service:
kubectl get svc -n kube-system kube-dns
kubectl get endpoints -n kube-system kube-dns
↓
4. Check pod DNS config:
kubectl exec <pod> -n <namespace> -- cat /etc/resolv.conf
↓
5. Fix if needed:
- Restart CoreDNS: kubectl rollout restart -n kube-system deployment/coredns
- Check network policies allow DNS (port 53)
- Verify kubelet configuration
Resource and Performance Workflow
High Resource Usage Investigation
1. Identify resource hog:
kubectl top nodes
kubectl top pods --all-namespaces
↓
2. Check specific pod:
kubectl top pod <pod-name> -n <namespace> --containers
kubectl describe pod <pod-name> -n <namespace> | grep -A 10 "Limits"
↓
3. Analyze application:
- Memory leak? → Check logs for errors
- CPU spike? → Profile application
- Check resource requests/limits appropriate?
↓
4. Take action:
- Increase limits if legitimate usage
- Fix application if bug/leak
- Implement HPA if scaling needed
- Add resource quotas to prevent overconsumption
Node Resource Exhaustion Workflow
1. Check node status:
kubectl get nodes
kubectl describe node <node-name>
↓
2. Look for pressure conditions:
- MemoryPressure
- DiskPressure
- PIDPressure
↓
3. Check node resources:
kubectl top node <node-name>
↓
4. Find resource consumers:
kubectl describe node <node-name> | grep -A 20 "Allocated resources"
↓
5. Actions:
- Evict non-critical pods
- Add more nodes
- Adjust resource requests/limits
- Clean up disk space if DiskPressure
Storage Troubleshooting Workflow
PVC Binding Issues Workflow
1. Check PVC status:
kubectl get pvc -n <namespace>
kubectl describe pvc <pvc-name> -n <namespace>
↓
2. Check for matching PV:
kubectl get pv
↓
No matching PV? → Check:
- Storage class exists: kubectl get storageclass
- Dynamic provisioner working
- Manual PV needed?
↓
3. Verify storage class:
kubectl describe storageclass <class-name>
↓
4. Check provisioner logs (if dynamic):
kubectl logs -n kube-system <provisioner-pod>
↓
5. Fix:
- Create matching PV (static)
- Fix storage class configuration (dynamic)
- Verify provisioner is running
Deployment and Rollout Workflow
Stuck Deployment Workflow
1. Check rollout status:
kubectl rollout status deployment/<name> -n <namespace>
↓
2. Check replica sets:
kubectl get rs -n <namespace>
kubectl describe rs <new-replicaset> -n <namespace>
↓
3. Check new pod status:
kubectl get pods -n <namespace> -l app=<app-label>
↓
Pods failing? → Follow pod troubleshooting workflow
↓
4. Check rollout strategy:
kubectl get deployment <name> -n <namespace> -o yaml | grep -A 10 strategy
↓
5. Options:
- Fix pod issues and rollout will continue
- Pause rollout: kubectl rollout pause deployment/<name>
- Rollback: kubectl rollout undo deployment/<name>
- Check revision history: kubectl rollout history deployment/<name>
Quick Reference Commands
Essential Debug Commands
# Pod debugging
kubectl get pods -n <namespace> -o wide
kubectl describe pod <pod> -n <namespace>
kubectl logs <pod> -n <namespace> [-c container]
kubectl logs <pod> -n <namespace> --previous
kubectl exec <pod> -n <namespace> -it -- /bin/sh
# Service debugging
kubectl get svc -n <namespace>
kubectl get endpoints -n <namespace>
kubectl describe svc <service> -n <namespace>
# Events
kubectl get events -n <namespace> --sort-by='.lastTimestamp'
# Resource usage
kubectl top nodes
kubectl top pods -n <namespace>
# Network debugging
kubectl run tmp-shell --rm -i --tty --image nicolaka/netshoot -- /bin/bash
# Cluster health
kubectl get nodes
kubectl cluster-info
kubectl get componentstatuses
Emergency Commands
# Delete stuck pod
kubectl delete pod <pod> -n <namespace> --force --grace-period=0
# Restart deployment
kubectl rollout restart deployment/<name> -n <namespace>
# Rollback deployment
kubectl rollout undo deployment/<name> -n <namespace>
# Cordon node (prevent new pods)
kubectl cordon <node-name>
# Drain node (evict pods)
kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data