kubectl logs: Every Flag You'll Actually Use
kubectl logs: Every Flag You'll Actually Use
kubectl logs is the first command you reach for when something breaks — and most people know only the bare version. The flags below are the difference between scrolling through a million lines and finding the error in the first ten.
Table of Contents
- The basics
- Follow and tail
- Multi-container pods
- Logs from many pods at once
- Time filtering
- Crashed containers: --previous
- Debugging when logs are empty
- Beyond kubectl logs
The basics
kubectl logs <pod-name> # current container logs
kubectl logs <pod-name> -n <namespace> # non-default namespace
Logs come from the container's stdout/stderr — if your app writes to a file instead of stdout, kubectl logs shows nothing. That's a container-design problem (log to stdout), not a kubectl problem.
Follow and tail
kubectl logs -f <pod> # stream live, like tail -f
kubectl logs --tail=100 <pod> # last 100 lines only
kubectl logs <pod> | tail -50 # same, via pipe
-f is your deploy-verification workhorse: kubectl logs -f deploy/my-app right after kubectl rollout watches the new version come up.
Multi-container pods
Sidecars mean one pod, several log streams. -c picks the container:
kubectl logs <pod> -c app # one container
kubectl logs <pod> --all-containers # every container, prefixed
kubectl logs <pod> -c istio-proxy # the sidecar specifically
Forgetting -c on a multi-container pod gets you a container name must be specified — or silently the wrong container's logs.
Logs from many pods at once
kubectl logs accepts a selector or a workload instead of a pod name — it streams from one matching pod, or fans out with --prefix:
kubectl logs -l app=web --all-containers --prefix # every web pod, prefixed
kubectl logs deploy/api --tail=50 # one pod from the deployment
kubectl logs -l app=web --max-log-requests 10 # cap concurrent streams
For serious multi-pod tailing, stern (a tiny dedicated tool) does it better: stern web streams all matching pods with color-coded prefixes.
Time filtering
kubectl logs --since=10m <pod> # last 10 minutes
kubectl logs --since=1h <pod> # last hour
kubectl logs --since-time=2026-10-15T09:00:00Z <pod> # absolute RFC3339
--since after an incident narrows the haystack before you grep.
Crashed containers: --previous
kubectl logs <pod> --previous # logs of the *last* crashed container
This is the CrashLoopBackOff move: the current container keeps restarting, so its logs are empty or truncated — --previous gets the logs from the run that just died, which is where the actual panic/error lives. If --previous returns "container not found," the pod restarted more than once or was rescheduled — check kubectl describe for the restart count and reason.
Debugging when logs are empty
kubectl logs returning nothing is itself a signal:
- Container never started — check
kubectl describe podevents (probe failures,CreateContainerError, ImagePullBackOff — see fixing ImagePullBackOff). - App logs to a file —
kubectl execin and read it, or reconfigure the app to log to stdout. - Log rotation evicted data — kubelet keeps a bounded file; long-running pods lose early logs. For anything beyond "what just happened," you need a log pipeline.
- Pod was deleted and recreated — logs die with the pod.
--previousonly works for restarts within the same pod.
Beyond kubectl logs
kubectl logs is for live debugging — it's not retention. For history across restarts, pod deletions, and multi-node searches, you want log aggregation: Grafana Loki is the lightweight Kubernetes-native option, and pairs with the alerting covered in Prometheus Alerting.
Related Articles
Last Updated: October 2026 Author: CloudOpsGuide Team Difficulty: Beginner Estimated Reading Time: 7 minutes