Choose the exact pod and container
A Deployment name is not a pod name, and a pod can contain multiple containers. List the pods in the intended namespace, then inspect the pod spec to see container names. Be cautious with generated pod names during a rollout: old and new ReplicaSets may run at the same time.
kubectl get pods -n payments
kubectl logs checkout-6f95d67cf8-8x2qt -n payments -c api --tail=200
Sidecars can be just as important as the main application. A proxy may show upstream resets while the application log looks normal. An init container may fail before the main container starts. Select each source deliberately.
Begin with a bounded view
Following an entire large log can bury the useful startup error and consume unnecessary bandwidth. Begin with a reasonable tail such as 100 or 200 lines. Add --timestamps when you need to align messages with alerts, deploys, or Kubernetes events. Use --since=15m or --since-time to bound a known incident window.
kubectl logs checkout-6f95d67cf8-8x2qt -n payments -c api --since=15m --timestamps
Remember which clock the application itself uses. Kubernetes-added timestamps and timestamps inside each log line may use different formats or time zones.
Use previous logs after a restart
If the restart count is above zero, the current container may be healthy or may not have reached the failing code yet. The --previous flag asks for the preceding terminated instance.
kubectl logs checkout-6f95d67cf8-8x2qt -n payments -c api --previous
This is particularly useful for CrashLoopBackOff, failed startup migrations, uncaught exceptions, and out-of-memory terminations. Retrieve it early: only the previous instance is exposed this way, and pod replacement removes that pod's local log context.
Follow output when reproducing a problem
Use --follow when you can trigger the faulty request or watch a startup sequence. Keep the window scoped with a tail so the session starts near the current moment. Stop following once you have enough evidence; an open stream is not monitoring.
For a Deployment with several replicas, a request may reach a different pod from the one you are watching. Use request IDs, trace IDs, ingress logs, labels, or a centralized logging system to find the handling replica. Do not assume silence in one pod means the request never reached the service.
Know what pod logs omit
kubectl logs returns the container's captured standard output and standard error. It does not automatically include files written inside the container, application telemetry sent elsewhere, node journal entries, or events from the Kubernetes API. An application that logs only to a file may appear silent.
Pair logs with kubectl describe pod, conditions, events, exit codes, resource usage, and the workload's rollout history. If the process never starts, the decisive error may be a mount or image event rather than an application log.
Do not use a pod stream as your archive
Container logs live on nodes and are subject to rotation. Pods are replaced routinely. Production observability normally ships logs to a durable backend where they can be searched across replicas and correlated over time. Set retention and access controls according to the sensitivity of the data.
Logs often contain customer identifiers, tokens, query strings, or internal addresses. Avoid pasting unredacted production logs into support tickets or public issues. Fix overly sensitive application logging at the source.
A useful five-minute log routine
- Confirm context and namespace.
- Check pod readiness, age, and restart count.
- Select the exact container.
- Read a timestamped, bounded tail.
- If it restarted, read the previous instance.
- Compare the times with events and the latest rollout.
- Move to the central log backend when the issue crosses pods or a longer period.
Clusterdeck provides container selection, follow mode, tail length, time filtering, auto-refresh, and wrapping in a persistent log tab. That is useful for interactive diagnosis on a Mac; kubectl commands remain easy to copy into a runbook or incident record.