Maintenance

Site is under maintenance — quizzes are still available.

Go to quizzes

View Pod Logs in Real Time

Learn how to view pod logs in real time in Kubernetes — streaming, filtering, and troubleshooting container output with kubectl logs.

Focus: view pod logs in real time

Sponsored

Your pod just started crashing, or worse — it's running but returning errors you can't reproduce locally. You need to see what's happening right now, not after the pod restarts and logs vanish. kubectl logs is your first responder tool, and with the -f flag you can watch container output stream in real time, exactly like tail -f on a file.

The problem this lesson solves

Kubernetes pods are ephemeral — they start, run, fail, and get replaced without warning. When something goes wrong, you don't have ssh access to the node. The only window into a running container's behavior is its standard output and standard error streams, collected and exposed by the kubelet.

Without real-time log streaming, you’re debugging blind: - You miss intermittent errors that happen every few minutes. - You can't correlate a spike in 5xx responses with a log line. - By the time a pod restarts, its previous logs are gone (unless configured otherwise).

Real-time streaming lets you watch output as it's produced — essential for debugging, monitoring rollouts, or validating that new code works before traffic hits it.

Core concept / mental model

Think of kubectl logs -f as connecting a hose to your pod's stdout/stderr. The kubelet buffers the last few lines (configurable via --tail), then opens a persistent connection. New lines appear in your terminal instantly.

Key definitions: - Stream: A continuous flow of log lines from the container, not a snapshot. - Buffer: The last N lines of output held by the kubelet before streaming begins. - Multi-container pod: A pod with >1 container — you must specify which container's logs to stream (-c). - Previous instance: When a pod restarts, --previous shows logs from the last incarnation (before the restart).

Pro tip: Real-time streaming is not the same as kubectl logs without -f. Without -f you get a dump of existing logs and the command exits. With -f you stay connected, watching new output live.

How it works step by step

  1. You issue kubectl logs -f <pod-name> (optionally with -c <container> for multi-container pods).
  2. Kubectl contacts the Kubernetes API server, which forwards the request to the kubelet on the node hosting the pod.
  3. The kubelet opens the container's log file (written by the container runtime, like containerd) and begins sending lines back to the API server.
  4. The API server streams those lines to your terminal over an HTTP connection (upgraded to a websocket-like stream).
  5. New lines appear as they are written by the container. Press Ctrl+C to disconnect.

Optional flags that modify the behavior: | Flag | Purpose | |------|---------| | --tail=N | Show only the last N lines before streaming (default is all). Useful for large logs. | | --since=5m | Only stream logs newer than a time offset (e.g., 5m, 1h). | | --timestamps | Prepend each line with a timestamp from the kubelet. | | --prefix | (Kubernetes v1.29+) Prefix each line with the pod and container name, helpful in multi-container pods. | | -f / --follow | Enable real-time streaming. | | --previous | Get logs from the previous instance of a restarted container. |

When to use --tail vs --since

  • Use --tail=100 when you only care about the most recent output (e.g., last error before crash).
  • Use --since=10m when you want a time window — especially useful after a recent incident.
  • Combine them! --tail=100 --since=30m shows up to 100 lines from the last 30 minutes.

Hands-on walkthrough

Let's create a pod that writes a timestamp every 2 seconds, then watch its logs live.

Example 1: Deploy a demo pod

# log-demo-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: log-demo
spec:
  containers:
  - name: logger
    image: busybox
    args:
    - /bin/sh
    - -c
    - |
      i=0
      while true; do
        echo "$(date): iteration $i"
        i=$((i+1))
        sleep 2
      done
kubectl apply -f log-demo-pod.yaml

Example 2: Stream logs in real time

kubectl logs -f log-demo

Output (live updating):

Fri Mar 27 12:01:00 UTC 2025: iteration 0
Fri Mar 27 12:01:02 UTC 2025: iteration 1
Fri Mar 27 12:01:04 UTC 2025: iteration 2
... (continues until Ctrl+C)

Pro tip: Open two terminals – one with kubectl logs -f log-demo and another to interact with the pod. You'll see log output immediately.

Example 3: Stream with --tail and --timestamps

kubectl logs -f --tail=5 --timestamps log-demo

Output:

2025-03-27T12:01:10.123456789Z Fri Mar 27 12:01:10 UTC 2025: iteration 5
2025-03-27T12:01:12.123456789Z Fri Mar 27 12:01:12 UTC 2025: iteration 6
...

Notice only the last 5 lines before the stream started, and each line now includes a precise timestamp.

Example 4: Multi-container pod — specify container

# multi-log-demo.yaml
apiVersion: v1
kind: Pod
metadata:
  name: multi-log-demo
spec:
  containers:
  - name: app
    image: busybox
    args: [/bin/sh, -c, 'while true; do echo "app log: $(date)"; sleep 3; done']
  - name: sidecar
    image: busybox
    args: [/bin/sh, -c, 'while true; do echo "sidecar log: $(date)"; sleep 5; done']
kubectl apply -f multi-log-demo.yaml
kubectl logs -f multi-log-demo -c app

Output (only app container's logs):

app log: Fri Mar 27 12:05:00 UTC 2025
app log: Fri Mar 27 12:05:03 UTC 2025
...

Compare options / when to choose what

Tool / Method Use Case Trade-off
kubectl logs -f Quick debugging, ad-hoc monitoring No persistence; lost on terminal close
kubectl logs --tail=N -f Large log volume but only need recent lines Skips earlier historical data
kubectl logs --since=5m After an incident, focus on recent time window No live streaming unless combined with -f
stern or kubetail Match multiple pods by label and stream all logs External tool, extra setup
kubectl logs --previous Debug a container that has already restarted Only works if terminatedMessagePolicy is set or logs are retained on node
Log aggregation (Loki, ELK) Long-term storage, search, alerting Infrastructure complexity, cost

For ad-hoc debugging, kubectl logs -f is your Swiss army knife. Combine with --tail for focused views. For production observability, feed logs into an aggregator.

Troubleshooting & edge cases

Error: error: container X is waiting to start: ... The container hasn't started yet — logs aren't available. Wait a moment or check kubectl get pods for status.

Error: error: unable to retrieve container logs for ... The pod may be in a CrashLoopBackOff state and the container isn't running. Use --previous to see the last run's output.

kubectl logs -f --previous my-crashing-pod

Error: error: you must specify at least one container Your pod has multiple containers — add -c <container-name>.

Edge case: Log lines too long The kubelet splits log lines at 16KB by default. Very long lines may be truncated. Workaround: write shorter log lines in your application.

Edge case: Log stream hangs or disconnects A long idle period can cause the API server to time out (default ~1 hour). Re-run the command. For production, use stern with reconnect logic.

Edge case: Empty output despite container running The container may be writing to a file, not stdout/stderr. Ensure your app logs to stdout/stderr (standard 12-factor app practice). Use kubectl exec to check file-based logs if needed.

Pro tip: If you need persistent access to logs, set up a logging sidecar or use kubectl logs --follow within a watch loop in combination with a terminal multiplexer (e.g., tmux).

What you learned & what's next

You now understand: - How kubectl logs -f provides a real-time stream of container stdout/stderr. - How to target specific containers in multi-container pods with -c. - How to control initial output with --tail, --since, and --timestamps. - How to debug restarted containers with --previous. - Which tool to choose for ad-hoc streaming vs. aggregated logging.

Next lesson in this track: Check Pod Health with Readiness and Liveness Probes — you'll learn how to make Kubernetes automatically detect problems and restart your pod, while using real-time logs to verify probe behavior.

Practice recap

Create a new pod that runs a loop writing both 'INFO' and 'ERROR' messages. Stream its logs with kubectl logs -f --tail=5 --timestamps. Kill the terminal session (Ctrl+C) and try again with --since=1m to see only recent output. Then check what happens when you omit -f — notice the differences.

Common mistakes

  • Forgetting the -c flag for multi-container pods — you'll get an error asking you to specify a container.
  • Running kubectl logs -f on a CrashLoopBackOff pod — the stream ends immediately because the container isn't running. Use --previous instead.
  • Assuming --tail limits output forever — it only affects the initial dump; streaming continues indefinitely.
  • Not using --since with long-running logs — you may be stuck scrolling through millions of lines before reaching the interesting part.

Variations

  1. Use stern to match pods by label regex and stream all matched pod logs into a single output — great for debugging deployments.
  2. Use kubetail (bash script) to tail multiple pods simultaneously with color-coding per pod.
  3. For aggregate viewing in a browser, consider deploying Kubernetes Dashboard or Octant, which offer log viewers with streaming.

Real-world use cases

  • Debugging a production 5xx spike by streaming logs of all pods in a deployment simultaneously using stern.
  • Validating a new release by watching logs of a canary pod in real time before routing full traffic.
  • Monitoring a CI/CD job that runs as a pod — streaming logs to a developer's terminal during the build.

Key takeaways

  • Use kubectl logs -f <pod> to stream container stdout/stderr in real time, exactly like tail -f.
  • Always specify -c <container> for multi-container pods, or you'll get an error.
  • Leverage --tail, --since, and --timestamps to control the volume and format of your initial output.
  • For restarted containers, --previous shows logs from the last incarnation before the crash.
  • Real-time streaming is ad-hoc — for long-term needs, pipe logs into an aggregator like Loki or ELK.
  • Container logs only capture stdout/stderr — ensure your app writes to these streams, not files, for kubectl logs to work.

Sponsored

Sponsored

Discussion

Questions, corrections, and tips help everyone reading this page.

0 comments

Add a comment

Shown publicly with your comment.

Be constructive · max 4,000 characters

No comments yet — start the thread.

Related tutorials, quizzes, and articles for this topic.