By Fatskills Exam Guides Team — the exam nerds behind 28,500+ quizzes and 2.1M practice questions across 500+ global exams.
(kubectl describe, logs, exec, Telepresence)
You’re on-call at 3 AM. A critical microservice in your Kubernetes cluster is returning 503 errors. The dashboard shows CPU spiking, but the logs are a firehose of noise. How do you find the root cause in minutes, not hours?
503
This guide is your battle-tested toolkit for debugging Kubernetes (and Docker) in production. You’ll learn: - kubectl describe: The "X-ray" for pods, nodes, and services—showing events, conditions, and configuration in real time.- kubectl logs: How to filter, tail, and aggregate logs from multiple containers (without drowning in them).- kubectl exec: Your "SSH into a container" lifeline—when you need to run commands inside a running pod.- Telepresence: The "wormhole" that lets you debug a remote Kubernetes service locally (as if it were running on your laptop).
kubectl describe
kubectl logs
kubectl exec
Why this matters in production:- Downtime = lost revenue. Every minute a service is broken costs money (and sleep).- Logs lie. Raw logs are useless if you can’t filter, correlate, or access them when pods crash.- Debugging blind is slow. Without exec or Telepresence, you’re guessing instead of diagnosing.- Incidents escalate. If you can’t quickly isolate a failing pod, you’ll waste time redeploying or rolling back blindly.
exec
Real-world scenario:You inherit a legacy Kubernetes cluster where a payment service is failing intermittently. The logs show Connection refused errors, but the service’s pod looks healthy. How do you:1. Check if the pod is actually receiving traffic? 2. Verify if its dependencies (like a Redis cache) are reachable? 3. Debug the service locally without redeploying?
Connection refused
This guide gives you the exact steps.
CrashLoopBackOff
describe
Events:
FailedScheduling: 0/3 nodes are available
Conditions:
Ready=False
ContainersNotReady
Last State:
docker logs
--previous
-f
--tail=100
--since=5m
-c <container>
docker exec
curl
kubectl exec -it pod -- sh
telepresence connect
telepresence intercept <service>
stdout
kubectl logs -c <sidecar>
Init:Error
Init:CrashLoopBackOff
kubectl describe pod
livenessProbe
readinessProbe
/health
MemoryPressure
DiskPressure
PIDPressure
kubectl describe node
kubectl
kubectl get nodes
Scenario: You deploy an Nginx pod, but it’s stuck in CrashLoopBackOff. Let’s debug it.
kubectl get pods
Expected output:
NAME READY STATUS RESTARTS AGE nginx-7cdbd8cdc9-abc12 0/1 CrashLoopBackOff 3 2m
What this tells you:- The pod is not Running.- It’s crashing and restarting (CrashLoopBackOff).- It’s been restarted 3 times.
Running
kubectl describe pod nginx-7cdbd8cdc9-abc12
Key things to look for:- Events: Shows scheduling failures, image pull errors, etc.- Last State: Exit code and reason for the crash.- Containers: Command, args, and environment variables.
Containers:
Example output (truncated):
Name: nginx-7cdbd8cdc9-abc12 ...Containers: nginx: ... Last State: Terminated Reason: Error Exit Code: 1 Started: Wed, 01 Jan 2023 00:00:00 +0000 Finished: Wed, 01 Jan 2023 00:00:01 +0000 ...Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 2m default-scheduler Successfully assigned default/nginx-7cdbd8cdc9-abc12 to node-1 Normal Pulled 2m kubelet Successfully pulled image "nginx:1.25.0" Warning BackOff 1m (x3 over 2m) kubelet Back-off restarting failed container
What this tells you:- The container exited with code 1 (generic error).- The image was pulled successfully, so it’s not an image issue.- The BackOff event confirms the crash loop.
BackOff
kubectl logs nginx-7cdbd8cdc9-abc12 --previous
Why --previous? Because the current container is already dead, but the previous instance’s logs might show why it crashed.
Example output:
2023/01/01 00:00:00 [emerg] 1#1: no "events" section in configuration nginx: [emerg] no "events" section in configuration
What this tells you:- Nginx failed to start because the config file is invalid (missing events section).
events
bash kubectl apply -f nginx-deployment.yaml
bash kubectl get pods -w
Scenario: Your app is running, but it’s returning 500 errors. You suspect a misconfigured environment variable.
500
kubectl exec -it nginx-7cdbd8cdc9-abc12 -- sh
What this does:- Opens an interactive shell (sh) inside the container.- -it = interactive terminal.
sh
-it
env | grep DB_
DB_HOST=postgres.default.svc.cluster.local DB_PORT=5432 DB_USER=admin DB_PASSWORD= # <-- Empty! This is the bug.
What this tells you:- The DB_PASSWORD environment variable is missing or empty.
DB_PASSWORD
# Check if a config file exists ls /etc/nginx/nginx.conf # Test a connection to a dependency curl http://redis:6379/ping
Why this matters:- You can verify if files exist, permissions are correct, or dependencies are reachable.
exit
Scenario: Your app works locally but fails in Kubernetes. You suspect it’s because it can’t reach a Redis cache in the cluster.
# On macOS/Linux curl -fL https://app.getambassador.io/download/tel2oss/releases/download/v2.14.0/telepresence-darwin-amd64 -o telepresence chmod +x telepresence sudo mv telepresence /usr/local/bin/ # On Windows (PowerShell) Invoke-WebRequest https://app.getambassador.io/download/tel2oss/releases/download/v2.14.0/telepresence-windows-amd64.exe -OutFile telepresence.exe
Verify:
telepresence version
What this does:- Creates a two-way network tunnel between your local machine and the Kubernetes cluster.
telepresence intercept my-service --port 8080
What this does:- Redirects traffic from my-service in the cluster to your local process (running on port 8080).
my-service
8080
# Example: Run a Python app locally python app.py
What this lets you do:- Your local app can now talk to real cluster dependencies (e.g., Redis, databases).- You can debug with your local IDE, set breakpoints, etc.
telepresence leave my-service telepresence quit
kubectl logs --ignore-errors
--mechanism=vpn-tcp
--mechanism=inject-tcp
kubectl logs --since=1h
--docker-run
app
env
version
yaml metadata: labels: app: my-service env: prod version: v1.2.3
kubectl debug
bash kubectl debug -it my-pod --image=busybox --target=my-container
kube_pod_container_status_restarts_total
Pending
5xx
kubectl logs --previous
latest
nginx:1.25.0
"How do you see logs from the previous instance of a crashed pod?"
Debugging probes:
"A pod is Running but not receiving traffic. What’s likely misconfigured?"
Telepresence use cases:
"Your app works locally but fails in Kubernetes. How do you debug it without deploying?"
Sidecar debugging:
-c <sidecar>
logs
kubectl get
get
"A pod is stuck in Pending state. What are the most likely causes, and how do you debug them?" Answer:1. Insufficient resources: Check kubectl describe pod for FailedScheduling events.2. NodeSelector/tolerations mismatch: Verify the pod’s nodeSelector matches node labels.3. PersistentVolumeClaim issues: Check kubectl get pvc for Pending status.4. Taints/tolerations: Run kubectl describe node to see if the node has taints the pod doesn’t tolerate.
FailedScheduling
nodeSelector
kubectl get pvc
You deploy a pod with the following YAML:
apiVersion: v1 kind: Pod metadata: name: debug-me spec: containers: - name: app image: busybox command: ["sh", "-c", "echo 'Hello' && sleep 3600"] - name: sidecar image: busybox command: ["sh", "-c", "while true; do echo 'Sidecar log'; sleep 5; done"]
The pod is Running, but when you run kubectl logs debug-me, you only see logs from the sidecar container. How do you see logs from the app container?
kubectl logs debug-me
sidecar
kubectl logs debug-me -c app
Why it works:- By default, kubectl logs shows logs from the first container in the pod.- -c app explicitly specifies the app container.
-c app
kubectl describe pod <pod>
-n <namespace>
kubectl logs <pod>
kubectl exec -it <pod> -- <cmd>
Join 4M+ learners. Unlock unlimited quizzes, wrong-answer tracking, flashcards + reminders, study guides, and 1-on-1 challenges.