To view Kubernetes logs, run kubectl logs <pod-name>, add -n <namespace> if the pod is not in your default namespace, and add -f to follow the output live. That covers most days. The rest of this guide covers the cases where it does not: multi-container pods, crashed pods, many replicas at once, and the point where a command line stops being the fastest way to read a stream.
TL;DR
kubectl logs <pod> -n <namespace>prints a pod's logs. Use-c <container>for a specific container and-fto stream.-pshows the previous container instance, which is what you need after a crash or restart.-l app=nginxpulls logs from every pod matching a label, but concurrent streams are capped by default, so raise the limit deliberately.kubectl logsreads node-local logs. They disappear when pods are removed or logs rotate, so keep a cluster-level store for anything you must retain.- A desktop client gives you live logs across clusters without juggling terminals and contexts.
Table of Contents
- The basic command: logs from one pod
- Pick the right container
- Tail and stream logs live
- See why a pod crashed: the previous container's logs
- Logs from many pods: label selectors
- Where the logs actually come from
- When kubectl is the wrong tool
- What a good Kubernetes log viewer should do
- Our perspective: logs are a daily reading task, not a project
- Viewing logs in Kubezilla Desktop
- A practical routine for log debugging
- Common problems and quick fixes
- FAQ
- Sources
The basic command: logs from one pod
The kubectl logs reference describes the command as printing the logs for a container in a pod or other specified resource. The simplest form:
kubectl logs my-api-7d9f8b6c54-x2k4p
If the pod lives outside your current namespace, name it:
kubectl logs my-api-7d9f8b6c54-x2k4p -n payments
Forgetting -n is the most common reason for a "pod not found" error. If you work across several namespaces, check which one your context points to before you assume the pod is gone:
kubectl config view --minify | grep namespace
To find the pod name in the first place, list pods in the namespace with kubectl get pods -n payments. Add -w to that command and kubectl keeps watching, printing a new line whenever a pod changes state. That is the quickest way to see a rollout while you wait for logs to appear.
Pick the right container
A pod can run more than one container: an application plus a sidecar proxy, a log shipper, or an init container. When a pod has several, kubectl needs to know which one you mean. The official documentation says you can pick the target container by name with the -c flag:
kubectl logs my-api-7d9f8b6c54-x2k4p -c app -n payments
Not sure what the containers are called? Run kubectl describe pod my-api-7d9f8b6c54-x2k4p -n payments and read the Containers section. If you want everything, --all-containers=true prints every container in the pod, and --prefix labels each line with its source so you can tell them apart.
Tail and stream logs live
People searching for "tail logs" or "live logs" want two different things, and kubectl has a flag for each.
Limit how much history you see. --tail=100 prints only the last 100 lines. --since=15m prints lines from the last 15 minutes. --since-time takes an absolute RFC3339 timestamp, and --timestamps prefixes each line with the time it was written. These flags are all listed on the kubectl logs reference page.
Keep the stream open. Add -f (or --follow) and the command does not return. New lines print as the container writes them. Combined with a tail limit, this is the standard live view:
kubectl logs my-api-7d9f8b6c54-x2k4p -n payments -f --tail=50
Starting with --tail matters. Without it, following a busy container first dumps the entire retained log into your terminal, and the line you wanted scrolls away before you read it. The same idea of watching live output from a container is covered from a broader operations angle in this piece on log sources.
Press Ctrl+C to stop following. The pod is unaffected.

See why a pod crashed: the previous container's logs
When a container crashes and Kubernetes restarts it, plain kubectl logs shows the new instance, which is usually a few seconds old and says nothing useful. The -p or --previous flag returns logs from the prior instance, if one exists:
kubectl logs my-api-7d9f8b6c54-x2k4p -n payments -p
This is the first command to run for a pod stuck in CrashLoopBackOff. A typical sequence:
kubectl get pods -n paymentsshows the restart count climbing.kubectl logs <pod> -n payments -pshows the stack trace or error from the run that died.kubectl describe pod <pod> -n paymentsshows the exit code, the last state and any OOMKilled reason.
If --previous returns an error saying no previous container exists, the container has not restarted. If the pod itself was deleted, there is nothing to ask for: its logs went with it. More on that below.
Logs from many pods: label selectors
A deployment with six replicas has six pods and six separate log streams. You rarely care which replica handled a request. You want all of them. The -l or --selector flag filters pods by label, and the documentation notes that matching objects must satisfy all the label constraints you provide:
kubectl logs -l app=nginx -n web --tail=20
To see which pods a selector will hit, run kubectl get pods -l app=nginx -n web first. If it returns the wrong pods, so will your logs.
A few practical points:
- Pointing at a deployment name can return logs from only one pod. Use a label selector when you need the whole set.
- Concurrent streams are limited. The
--max-log-requestsflag caps how many log streams kubectl opens at once, and its default is 5, according to the kubectl logs reference. With a selector that matches more pods than that while following, raise it, for example--max-log-requests=10. - Lines interleave without context. Add
--prefixso each line carries its pod and container name, and--timestampsso you can reconstruct the order.
For tailing logs across a dozen pods for an hour, plain kubectl gets awkward. Output from different pods interleaves, you cannot search or pause it, and one dropped connection ends the stream. Many engineers reach for a small open-source multi-pod tailer or a GUI at this point. We cover what to look for in the next sections.
Where the logs actually come from
Knowing the mechanism explains most surprises. Container runtimes capture each container's standard output and standard error streams, and the kubelet makes them available for retrieval, as the Kubernetes logging architecture guide explains. Two consequences follow:
- Your app must write to stdout or stderr. If it writes only to a file inside the container,
kubectl logsshows nothing. Either change the logger config or add a sidecar that streams the file to stdout. - The logs live on the node.
kubectl logsasks the kubelet on the node running the pod to hand back what it holds.
That last point is also the limit. As one engineering write-up puts it, kubectl logs is not a long-term storage system: logs are read from node storage and get rotated or removed along with pods. If a pod is evicted, a node is replaced during an upgrade, or a deployment rolls and old replicas are deleted, the history can be gone by the time you investigate.
When kubectl is the wrong tool
kubectl is the right answer for a quick look. It starts to hurt in these situations:
| Situation | Why kubectl struggles | What helps |
|---|---|---|
| Incident review a day later | Pod or node may be gone, logs rotated | Cluster-level log storage |
| Searching for one request ID across services | Plain text stream, no index | Centralized logging with search |
| Watching five pods at once while debugging | Interleaved output, stream limit | A viewer with per-pod panes or filters |
| Switching between staging and production clusters | Context switching, easy to run against the wrong cluster | A client that shows clusters side by side |
| Reading logs for a pod while checking its CPU and memory | Separate commands and terminals | A single window with logs and metrics |
The first two rows are a storage and indexing problem. A centralized logging stack, built from an agent on each node and a searchable backend, solves it, and the Kubernetes documentation describes cluster-level logging as the way to keep logs beyond the life of a pod. The last three rows are an interface problem, and that is where a desktop client earns its place.
What a good Kubernetes log viewer should do
Whether you build a workflow around terminal tools or a GUI, judge a log viewer on a short list of things:
- Live streaming that does not stall. Following should feel like
tail -f, without reconnect gymnastics. - Container and pod selection without typing names. Pod names carry random suffixes. Clicking beats copy-pasting.
- Time and text filtering. You should be able to narrow to the last few minutes or a keyword without piping through
grep. - Cluster awareness. It should make obvious which cluster and namespace you are reading, to avoid acting on production by accident.
- Credentials handled safely. A viewer that holds your kubeconfigs should store them locally and not ship them anywhere.
- Light on resources. You open it dozens of times a day, often on a laptop already running a browser, an IDE and containers.
Centralized platforms in the cloud tick the search box but need setup, agents and often per-gigabyte billing. A local desktop client ticks the speed and convenience boxes and needs only the access you already have.
Our perspective: logs are a daily reading task, not a project
Most log work in Kubernetes is small and urgent. A deploy went out, a pod restarted, a customer reported an error five minutes ago. Nobody wants to stand up a logging platform for that, and nobody wants to remember the exact flag order either. They want to click a pod and read.
That is why we built Kubezilla Desktop as a native app, written in Rust, with live log streaming next to the rest of the cluster view: metrics, pod terminals, YAML editing, scaling, Helm and ArgoCD operations. It keeps kubeconfigs in secure local storage, with no cloud sync and no telemetry, so connecting multiple clusters does not mean handing credentials to a third party. It supports SSH tunnels for clusters behind a bastion, so you do not have to maintain a VPN client for every environment.
Our view is that kubectl remains the foundation. You should know the flags above, because they work in every environment, including a broken one at 3 a.m. A good client does not replace that knowledge. It removes the repetitive typing, keeps the context visible and lets you spend attention on what the logs say.
— Margus
Viewing logs in Kubezilla Desktop
In Kubezilla Desktop, you add your kubeconfig or connect through an SSH tunnel, pick the cluster and namespace, open the pod and watch its logs stream live. Everything stays on your machine. The app runs on Linux, macOS and Windows, and a single window can reach several clusters, which cuts out the habit of switching contexts in a terminal.
Because logs sit alongside the other views, a typical debugging loop stays in one place:
- Read the live logs for the failing pod.
- Check CPU and memory next to them. Our guide to viewing pod metrics walks through
kubectl topand what comes after it. - Open a shell in the container when you need to test something. We cover pod shell access separately.
- Scale the workload or edit the YAML, then watch the logs react. If scaling is the fix, see our notes on scaling a deployment.
Kubezilla Desktop costs €5 per month. You can see what is included on the pricing page or read more about the Kubernetes desktop app itself.
A practical routine for log debugging
Whichever tool you use, the same sequence saves time:
- Confirm cluster and namespace first. Most wrong-environment mistakes happen before the first log line is read. If you manage many environments, a clear view of every cluster matters; our article on multi-cluster Kubernetes management goes deeper.
- Start narrow. Use
--tail=100or--since=10mso you read the part of the story that matters. - Check the previous instance if restarts are nonzero. Use
-p. - Widen with a label selector when you suspect the issue is not specific to one replica.
- Add timestamps and prefixes whenever you combine streams.
- Save what you need. If the evidence will matter after the incident, copy it out or confirm your centralized logging captured it. Do not rely on a pod that is about to be replaced.
- Rule out the network path. If the logs look healthy but the service does not respond, test the connection directly. Our guide to kubectl port-forward with multiple ports covers the syntax and pitfalls.
Common problems and quick fixes
"Error from server (NotFound): pods not found." Wrong namespace or a pod that was replaced. Run kubectl get pods -n <namespace> again. Pod names change on every rollout.
"a container name must be specified." The pod has more than one container. Use -c <container> or --all-containers.
The output is empty. The application may log to a file rather than stdout, or may not have written anything yet. Check the app's logging configuration.
A selector returns fewer logs than expected. Verify the labels with kubectl get pods --show-labels. Remember that all labels in the selector must match.
The stream cuts out after a while. Long-running follows can be interrupted by network or API server timeouts. Re-run the command with --since=1m to pick up near where you left off, or use a client that reconnects automatically.
Logs are missing from an hour ago. They were likely rotated on the node or the pod is gone. That is the signal to adopt cluster-level logging for anything you need to keep.

FAQ
How do I view logs for a pod that already crashed?
Run kubectl logs <pod> -p to read the previous container instance's output. This works while the pod object still exists and the container has restarted. If the pod was deleted, those logs are no longer available from kubectl, so you need a centralized log store.
How do I tail logs from multiple pods at once?
Use a label selector, for example kubectl logs -l app=nginx -f --prefix --tail=20. Raise --max-log-requests if the selector matches more than the default number of pods. For a long session with many pods, a viewer that separates or filters streams is easier to read than interleaved terminal output.
Does kubectl logs keep logs forever?
No. It reads logs held on the node, which are rotated and are removed when the pod goes away. Send logs to a cluster-level system if you need history for audits or incident reviews.
What is the best way to watch resources and logs together?
In the terminal, use kubectl get pods -w in one pane and kubectl logs -f in another. In a desktop client such as Kubezilla Desktop, you can watch the pod's state, its live logs and its metrics in a single window, with no extra terminals to manage.
Sources
- kubectl logs | Kubernetes reference
- Logging Architecture | Kubernetes
- kubectl logs: View, Tail, and Debug Kubernetes Pod Logs
