skip to content

In Kubernetes, after a pod is deleted and its Deployment replaces it, can you still read the old pod's container logs with kubectl, and why?

level: juniorimportance: must knowfreq 72%

answer

  1. files on the node, not etcd
  2. logs belong to the pod UID
  3. kubelet cleans up on deletion
  4. only one previous instance kept
  5. capture before delete or rollback

basics

~20 s

No. Kubernetes keeps container logs only as files on the pod's node, tied to that pod; once the pod is deleted the kubelet removes its containers and log directory, and the replacement pod starts with empty logs.

solid answer

~40 s

No. `kubectl logs` does not read a central store: the API server asks the kubelet on the pod's node to stream the log file the container runtime wrote there. Those files belong to the pod — when the pod is deleted, the kubelet tears down its containers and removes the pod's log directory, and `kubectl logs <old-pod>` just fails because the pod object no longer exists. The replacement pod has a new name, a new UID and fresh files. Within one pod, logs survive a container restart only as far as `--previous`, which shows the single instance before the current one. So the rule in an incident is: capture `kubectl logs` (and `--previous`) output before you delete, roll back or scale down, and rely on a cluster log pipeline for anything older.

code

bash · 4 lines
bash
kubectl logs transcoder-7f9c4d6b8-x2lqp -n media -c transcoder > current.log
kubectl logs transcoder-7f9c4d6b8-x2lqp -n media -c transcoder --previous > previous.log
kubectl describe pod transcoder-7f9c4d6b8-x2lqp -n media > describe.txt
kubectl rollout restart deployment/transcoder -n media

go deeper

for a junior

Recall that container logs are files on the pod's node, that they disappear when the pod is deleted, and that --previous shows only the one instance before the current container.

for a middle

Explain the request path from kubectl through the API server to the node's kubelet, and why deletions caused by rollouts, scale-downs and CronJob history limits also delete logs.

for a senior

Show the incident habit: capture logs, previous logs and describe output before any restart or rollback, and name the gaps that only a node-level collector closes.

for a principal

Frame node-local logs as a platform gap: decide what evidence must outlive a pod, and make shipping it a default of every cluster rather than a per-team choice.

## Where Kubernetes keeps container logs Kubernetes itself has **no central log store**. A container writes to **stdout** and **stderr**; the **container runtime** (containerd or CRI-O, behind the **CRI**) captures both streams and writes them to a file on the node's disk. The **kubelet** — the node agent — owns the directory layout and the rotation of those files. When you run `kubectl logs <pod>`: 1. `kubectl` calls the pod's `log` subresource on **kube-apiserver**. 2. The API server looks up which node runs the pod and proxies the request to that node's kubelet. 3. The kubelet opens the container's current log file and streams it back. Nothing about that path touches etcd. Log text is never part of the pod object, so it cannot outlive the files on the node. ## What survives what | Event | Pod object | Log files on the node | What `kubectl logs` gives you | |---|---|---|---| | Container restarts in place | same pod | new file for the new instance; the previous instance's file is kept | current instance; `--previous` gives the one before | | Pod deleted (rollout, scale-down, `kubectl delete`) | gone | removed by the kubelet during cleanup | an error — the pod is not found | | Pod evicted for node pressure | kept, phase `Failed` | may be removed, because eviction tells the kubelet to reclaim the pod's resources | do not count on anything | | Node deleted or its disk replaced | pods rescheduled elsewhere | gone with the disk | nothing | Two details matter here: - **Restarts keep only one old instance.** By default the kubelet's container garbage collection keeps one dead instance per container, which is why `--previous` means "the instance just before the current one", not "any earlier run". - **A replacement pod is a different pod.** A Deployment's ReplicaSet creates a new pod with a new name and UID. It has no link to the deleted pod's files, and `kubectl` does not follow a Deployment to its old pods. ## Why deletion wipes the evidence Once a pod is deleted, the kubelet stops its containers and then cleans up everything it created for that pod: the containers themselves, the sandbox, and the pod's log directory under `/var/log/pods/`. That is deliberate — a node that kept every dead pod's logs would fill its disk. The consequence is that **deleting a failing pod is a destructive act for debugging**, even though the controller replaces it within seconds. The same applies to things that delete pods for you: - a **rolling update** scales the old ReplicaSet down, deleting its pods; - **`kubectl rollout undo`** does the same to the bad revision's pods; - **scaling to zero** deletes every pod; - a CronJob's **history limits** or a Job's **`ttlSecondsAfterFinished`** delete finished Jobs, and their pods and logs with them. ## Keeping the evidence A practical order of work before you remove a broken pod: 1. Save the current output: `kubectl logs <pod> -c <container> > current.log`. 2. If the container has restarted, save the previous instance: `kubectl logs <pod> -c <container> --previous > previous.log`. 3. Save `kubectl describe pod <pod>` — it includes recent Events and the container's last termination state, and Events expire on their own. 4. Only then delete, roll back or scale. For anything you cannot capture by hand — a pod that died at 3 a.m. — you need a **node-level log collector** that tails the files and ships them to a durable store before the kubelet removes them. How that pipeline works is a separate subject; the Kubernetes part is only that the files exist, where they are, and for how long. ## A worked example On a single-node development cluster on a laptop, a video-transcoding worker pod `transcoder-7f9c4d6b8-x2lqp` in namespace `media` starts failing on one input file. The developer runs `kubectl rollout restart deployment/transcoder -n media` to "clear it". The Deployment creates `transcoder-7f9c4d6b8-q4k2v`, deletes the old pod, and `kubectl logs transcoder-7f9c4d6b8-x2lqp -n media` now returns a not-found error. The encoder's stack trace existed only in the deleted pod's log file, and that file is gone. Had the developer run `kubectl logs --previous` first, the trace would be on their disk. ## Ephemeral debug containers are no exception A container added with `kubectl debug` lives in the pod's `spec.ephemeralContainers`. Its output is written to the same per-pod log directory and read with `kubectl logs <pod> -c <debug-container-name>` — and it disappears with the pod in exactly the same way.

  • Can you read the output of an ephemeral debug container that `kubectl debug` added to a pod?
    Yes. An ephemeral container is a real container listed in the pod's `spec.ephemeralContainers`, and the API server accepts its name for the `log` subresource. `kubectl logs <pod> -c <debug-container-name>` streams what it wrote, from the same per-pod log directory on the node. Its logs share the pod's lifetime: delete the pod and they are removed with everything else.
  • A pod shows as `Evicted` in `kubectl get pods`. Are its container logs still readable?
    Do not rely on it. The pod object stays with phase `Failed`, but a node-pressure eviction exists to free resources, so the kubelet is told to clean up the pod's content aggressively, including containers and their log files. `kubectl logs` may return nothing or an error even though the pod is still listed. If the evicted workload matters, its logs must already be in a cluster log pipeline.
  • `kubectl logs` on a pod with a sidecar printed a container you did not want. How does kubectl choose?
    With no `-c`, kubectl uses the container named in the pod's `kubectl.kubernetes.io/default-container` annotation if it is set, otherwise the first container in the spec, and prints a notice saying which one it defaulted to. Pass `-c <name>` to pick one explicitly, or `--all-containers` to read every container's log in turn.

Container logs are like notes written on a hotel room's whiteboard: they stay while you keep the room, and a room swap means housekeeping wipes the board before the next guest arrives.

saying these in an interview costs you the question

  • Deleting a crash-looping pod is harmless because the logs stay in the cluster.
  • kubectl logs reads log text that the API server stores in etcd.
  • The replacement pod from a Deployment inherits the deleted pod's log history.
  • kubectl logs --previous can reach any earlier restart, not only the last one.
  • An Evicted pod still listed by kubectl keeps its logs readable indefinitely.