Inspect Pods and Container Logs
Learn to inspect pods and view container logs with kubectl in this Kubernetes for Python Developers tutorial — hands-on steps, troubleshooting, and what to study next.
Focus: inspect pods and container logs with kubectl
You've deployed your first pods, maybe even a Deployment, but when something goes wrong in your Python service — a 500 error, a slow response, a crash loop — you're staring at a black box. You can't SSH into a pod like a VM. You need a way to see inside. That's exactly what kubectl gives you: the power to inspect what's running, watch its health, and read the logs your Python code prints. With the right commands, you can turn cryptic failures into clear, actionable answers — and this lesson is your hands-on guide to doing exactly that with kubectl.
The problem this lesson solves
You've just deployed a Python Flask app to your cluster. It worked in Docker locally, but a few minutes later, your pods are in CrashLoopBackOff, or worse, they're running but every request returns a 500. Without a way to look inside, you're guessing. You restart pods, you redeploy — but the problem persists.
The core challenge: containers are ephemeral and isolated. You can't just hop into the virtual machine and check the process. But Kubernetes gives you a standard toolset for introspection. If you don't know these commands, you'll spend hours in the dark.
This lesson teaches you the essential kubectl commands to inspect pods and container logs with kubectl. You'll learn to check pod status, read stdout/stderr from your Python app, and run commands inside the container without leaving your terminal. The result: you'll diagnose issues in minutes, not hours.
Core concept / mental model
Think of your cluster as a hotel. Your pods are the rooms, and your Python application is the guest. You can't peek through the keyhole, but you have a front desk (the Kubernetes API) that can relay everything: the room's status (is the guest inside? are they causing trouble?), the messages they leave (logs), and even let you knock and have a conversation (exec into the container).
kubectl getlets you list rooms (pods) and their current status (Running, Pending, CrashLoopBackOff).kubectl describegives you a detailed report on a room: events, configurations, and why the guest might be disturbed.kubectl logsfetches the written messages (stdout and stderr) that your Python app left behind.kubectl execlets you go into the room and do more, like checking environment variables or running a quick Python script.
This mental model helps: you're not guessing; you're using a structured API to ask the right questions of your cluster.
How it works step by step
Every kubectl command you run hits the Kubernetes API server, which then retrieves the info from the etcd database or the kubelet on the node. Here's the logical flow of inspecting:
- List your pods to see the actual state.
- Pick the pod you need to inspect, often by name or label.
- Describe the pod to get detailed status and recent events.
- Fetch logs from the container(s) inside the pod.
- Execute a command inside the container if you need more.
Each step is deliberate. You'll often start with get, narrow down with labels, then dive into describe and logs. This prevents you from wasting time on the wrong pod.
Hands-on walkthrough
Let's put this into practice. We'll assume you have a pod running a simple Python Flask app. If you don't have one, create it with the following manifest:
apiVersion: v1
kind: Pod
metadata:
name: flask-pod
labels:
app: flask-demo
spec:
containers:
- name: flask
image: python:3.11-slim
command: ["sh", "-c"]
args:
- |
echo "Container starting..." >> /proc/1/fd/1
pip install flask --quiet
echo "Flask installed" >> /proc/1/fd/1
python -c "from flask import Flask; app = Flask(__name__)
@app.route('/')
def hello():
return 'Hello, K8s!'
app.run(host='0.0.0.0', port=8080)" &
sleep 3600
Pro tip: For a quick demo, you can also use
kubectl run flask-demo --image=python:3.11-slim --command -- sleep 3600— we'll practice logs with that too.
Step 1: See all pods
kubectl get pods
Expected output (similar):
NAME READY STATUS RESTARTS AGE
flask-pod 1/1 Running 0 5m42s
The READY column tells you if containers are up. If you see 0/1, something's wrong.
Step 2: Get detailed information
kubectl describe pod flask-pod
This prints a treasure trove: pod IP, node, labels, and — critically — the Events section at the bottom. That's where you see things like "Container image "flask" already present" or "Back-off restarting failed container" if there's a crash.
Step 3: Fetch logs
kubectl logs flask-pod
You'll see the output from your Python code:
Container starting...
Flask installed
* Serving Flask app ''
* Debug mode: off
But wait — what if your app writes to stderr? By default, kubectl logs shows both stdout and stderr combined from the container's terminal.
Step 4: Follow live logs
When your Python app is serving requests, you'll want to watch logs in real time:
kubectl logs -f flask-pod
Great for local debugging, but be careful in production — it blocks your terminal.
Step 5: Get logs from a previous instance
If your pod crashed and restarted, the logs from the previous attempt are still accessible:
kubectl logs flask-pod --previous
The --previous flag is gold when troubleshooting CrashLoopBackOff — you see the error that caused the crash!
Step 6: Run commands inside the container
kubectl exec -it flask-pod -- python -c "import flask; print(flask.__version__)"
You might see:
2.3.3
Or use an interactive shell:
kubectl exec -it flask-pod -- /bin/bash
Now you're inside the container — inspect files, run diagnostics, and exit with exit.
Multi-container pods
If a pod has multiple containers, you must specify which one:
kubectl logs flask-pod -c flask-container
kubectl exec -it flask-pod -c sidecar-container -- /bin/sh
Compare options / when to choose what
Not every inspection method suits every situation. Here's a decision table:
| Situation | Best command | Why |
|---|---|---|
| Quick status check | kubectl get pods |
Fast overview of cluster health |
| Pod failing to start | kubectl describe pod <name> |
Shows events and reason for failure |
| App is running but misbehaving | kubectl logs <pod> |
See what your Python code says |
| Crash loop — need old logs | kubectl logs <pod> --previous |
Get logs from before the crash |
| Need to debug internals | kubectl exec -it <pod> -- /bin/sh |
Interactive access to container FS |
| Watch logs live during testing | kubectl logs -f <pod> |
Real-time output for development |
Pro tip: For multiple pods (like a Deployment), use
kubectl logs deployment/<name>— it fetches logs from one pod in that deployment automatically.
Troubleshooting & edge cases
"Error from server: Internal error occurred: log line too long"
If a Python app prints massive JSON logs, kubectl truncates. Solution:
- Use --tail=50 to get the last 50 lines.
- Write logs to a file inside the container and kubectl cp it out.
"No logs found" but you know your app prints
- Check if the app is writing to
stdoutor a file. Containers only seestdout/stderrunless you configure logging. - Your Python logging handler may buffer; force flush with
flush=True.
Pod shows CrashLoopBackOff
- Run
kubectl logs --previousto get the crash cause. - Common causes: wrong
ENVvariables, missing dependencies, or bad port binding.
exec can't find bash
Many slim images (like python:3.11-slim) don't have bash. Use /bin/sh instead.
Permission denied on exec
You need pods/exec RBAC permission. As a developer, you usually have it — but in a strict cluster, ask your admin.
What you learned & what's next
You now have a solid toolkit to inspect pods and container logs with kubectl. You can:
- List and describe pods to diagnose status issues.
- Read and follow logs from your Python containers.
- Access previous logs after a crash.
- Execute commands inside containers for deeper debugging.
- Handle multi-container pods and common edge cases.
These skills are the foundation for the next step in your Kubernetes journey: debugging with kubectl port-forward or managing deployments. With logs and exec, you can confidently move to orchestrating more complex apps.
Callout: The more you practice, the faster you'll debug. Next lesson, you'll learn how to forward a local port to a pod so you can test your Python API directly.
Practice recap
Create a simple Python pod that writes a log line every second, then use kubectl logs -f to watch it live. Then intentionally cause a crash (e.g., exit with code 1) and practice kubectl logs --previous to see the error. Try multi-container eventually.
Common mistakes
- Running
kubectl logson a multi-container pod without-c— you get an error asking you to specify a container. - Using
--previouson a freshly deployed pod that never crashed — returns no output, which confuses beginners. - Trying to exec with
bashin a container that only hassh— leads to a "no such file" error. - Ignoring
kubectl describeevents — the fastest way to see why a pod isn't starting is in the Events section.
Variations
- Use
kubectl logs deployment/my-appto get logs from a random pod in a Deployment. - Use
kubectl logs -l app=flask-demoto fetch logs from all pods matching a label. - For centralized logging, use
kubectl logsfor ad-hoc debugging, and EFK stack (Elasticsearch, Fluentd, Kibana) for production.
Real-world use cases
- A Python service crashes on startup in production; you use
kubectl logs --previousto see the traceback and fix a missing environment variable. - Your Flask app is slow under load; you exec into the pod and run
topto check for CPU/memory bottlenecks. - You're debugging a multi-container pod with a sidecar; you use
kubectl logs -cto isolate which container is failing.
Key takeaways
- Start with
kubectl get podsto see the big picture, then drill down withdescribe. kubectl logsreads stdout/stderr from your container — make sure your Python code logs to stdout.- For crash loops, always check
kubectl logs --previous— it contains the last error before the crash. kubectl execlets you run commands inside the container for deeper inspection.- In multi-container pods, always specify
-c <container-name>. - Use
kubectl describeevents to find the root cause of scheduling or image pull failures.
Keep learning
Related tutorials, quizzes, and articles for this topic.
Discussion
Questions, corrections, and tips help everyone reading this page.
0 comments
Add a comment
No comments yet — start the thread.