Logs, events and container output streams
Where a container's output goes, how to read exactly the lines you need, how to show a log file, and how events help.
Key ideas in this lesson · tap one for a simple explanation
What you will be able to do
- Read the logs of any container: one named container, the run before a crash, or every Pod with a label.
- Find a container's log file on its node.
- Add a native sidecar that prints an app's log file to stdout, without changing the app container.
- Sort and filter events, and you know when to use describe and when to use get events.
This exam skill is called Manage and evaluate output streams. The tasks are small and exact. Save one container's error lines to a file. Find the that crashed with a given message. Make an app's log file readable with kubectl logs.
A container's log is everything its app prints. A program prints to two output streams: stdout for normal output and stderr for errors. The saves both streams into one file on the . kubectl logs reads that file back for you.
Your app
prints to stdout and stderr
Container runtime
saves both streams to one file
Log file on the node
/var/log/pods/…
kubectl logs
asks the kubelet to read the file
A file the app writes inside its own container is not on this path, so kubectl logs never sees it.
Reading logs with kubectl logs
kubectl -n shop logs web-7d9c # the default container (see the trap below)
kubectl -n shop logs web-7d9c -c sidecar # one named container (init containers too)
kubectl -n shop logs web-7d9c --all-containers # every container, init containers included
kubectl -n shop logs web-7d9c --previous # the instance before the current one (-p)
kubectl -n shop logs web-7d9c -f # follow; Ctrl-C to stop
kubectl -n shop logs web-7d9c --since=10m # only recent lines (also --since-time=2026-10-17T09:00:00Z)
kubectl -n shop logs web-7d9c --tail=50 # last 50 lines
kubectl -n shop logs web-7d9c --timestamps # prefix each line with the runtime's RFC3339 timestamp
kubectl -n shop logs -l app=web --prefix # every Pod with the label; lines start [pod/<name>/<container>]
kubectl -n shop logs deploy/web # one Pod picked from the Deployment
# The typical exam shape: one container, one pattern, into a file
kubectl -n shop logs web-7d9c -c app | grep 'ERROR' > /tmp/cka/web-errors.txt- Name the container. In a Pod with several containers,
kubectl logswithout-cpicks a default. That is the one named in thekubectl.kubernetes.io/default-containerannotation, or else the first. It printsDefaulted container "app" out of: …. Always pass-cwhen the question names a container. - Labels cut the output. With
-l, you get only the last 10 lines of each Pod. Add--tail=-1when you need the full log. - The output is the answer. When you write a file the grader compares, do not add
--timestampsor--prefix. You also do not need2>&1: stderr lines are already in the container log.
Which run do you see after a crash?
When a container crashes, the starts it again. That is a new run, with a new log. The kubelet keeps the current run and normally one run before it.
Run 1: crashed
the kubelet keeps its log
kubectl logs POD --previous
Run 2: running now
started by the restart
kubectl logs POD
Once the container is Running again, the crash output is only in --previous.
If --previous answers unable to retrieve container logs, the old run is already gone. When you are unsure, run both commands. All of these logs disappear when the Pod is deleted.
Where the logs live on the node
The log files sit on the node that runs the Pod. Each container has a folder: /var/log/pods/<namespace>_<pod>_<pod-uid>/<container>/. The file name is the restart count: 0.log for the first run, 1.log after one restart. /var/log/containers/ holds shortcuts (symlinks) to the same files.
kubectl -n shop get pod web-7d9c -o wide # which node?
docker exec -it cka-worker bash
ls /var/log/pods/ | grep web-7d9c
tail -n 3 /var/log/pods/shop_web-7d9c_*/app/0.log
# 2026-10-17T10:35:46.709286291Z stderr F connection reset by peer
ls -l /var/log/containers/ | grep web-7d9cWhen the is down, kubectl logs cannot work, but crictl logs on the node still can. Control plane failures shows how.
When the app writes to a file
Some apps write their log to a file instead of stdout. Then kubectl logs shows nothing. The fix is a helper container that reads the file and prints it to its own stdout.
The right helper is a native : an with restartPolicy: Always, which runs for the Pod's whole life. Pods, init containers and sidecars teaches it. Below is the block you add, for a Pod report whose app writes /data/report.log to a shared volume named data.
spec:
initContainers: # add this list, beside containers
- name: log-tail
image: busybox:1.36
restartPolicy: Always # this line makes it a sidecar
command: ["sh", "-c", "tail -n +1 -F /data/report.log"]
volumeMounts:
- name: data # the volume the app writes to
mountPath: /dataYou cannot add a container to a running Pod. So you rebuild the Pod:
- 1.Export it:
kubectl -n shop get pod report -o yaml > report.yaml. - 2.Add the
initContainersblock to the file. - 3.Replace it:
kubectl replace --force -f report.yamldeletes the Pod and creates it again, with the same name. - 4.Check it:
kubectl -n shop logs report -c log-tailshows the app's log.
For a , edit its Pod template instead. It then rolls out new Pods by itself.
Events
Events are short notes that Kubernetes writes about what it did and what failed: Scheduled, Pulled, BackOff, FailedScheduling. The , the kubelet and the controllers write them. There are two ways to read them:
- Events expire after one hour by default. For an older problem, read the logs instead.
kubectl get eventsis not sorted by time. Add--sort-by=.metadata.creationTimestamp, or usekubectl events, which sorts by itself.
kubectl -n shop get events --sort-by=.metadata.creationTimestamp
kubectl -n shop get events --field-selector type=Warning
kubectl -n shop get events --field-selector involvedObject.kind=Pod,involvedObject.name=web-7d9c
kubectl -n shop get events -w # stream new events while you fix things
kubectl get events -A --sort-by=.metadata.creationTimestamp | tail -20
kubectl -n shop events --for pod/web-7d9c --types=Warning # kubectl events sorts by time itselfkubectl describe pod also shows the exit code of the last crash, under Last State. Application failures explains what each exit code means.
In the official docs· open on exam day too
- Logging Architecturesearch: logging architecture
- kubectl logssearch: kubectl logs
- Sidecar Containerssearch: sidecar containers
- kubectl eventssearch: kubectl events
Stream a log file with a native sidecar
ledger in namespace tsx-logs writes its log to /var/log/ledger/ledger.log, so kubectl logs shows nothing. Add a container named sidecar using image busybox:1.36 that streams that file to its standard output for the whole life of the Pod, so that kubectl -n tsx-logs logs ledger -c sidecar shows the ledger entries. Implement it as a native sidecar container. The Pod must keep the name ledger, and the container app must stay unchanged.Cluster:kubectl config use-context kind-cka
- 1
Set up the scenario
curl -fsSL https://codewithmuh.com/labs/cka/t/ts-logs-1/setup | bash - 2
Solve it in your terminal
Use kubectl and the Kubernetes docs, like on exam day. Save any answer files under
/tmp/cka/. - 3
Check your work
curl -fsSL https://codewithmuh.com/labs/cka/t/ts-logs-1/verify | bashGot FAIL? Read which check failed, fix it, run it again. - 4
Clean up (optional)
curl -fsSL https://codewithmuh.com/labs/cka/t/ts-logs-1/cleanup | bash
Extract one container's error lines
billing in namespace tsx-grep runs two containers. Write every log line of the container worker that contains the string ERROR to /tmp/cka/billing-errors.txt, one per line, in the order they were logged and exactly as the container printed them.Cluster:kubectl config use-context kind-cka
- 1
Set up the scenario
curl -fsSL https://codewithmuh.com/labs/cka/t/ts-logs-2/setup | bash - 2
Solve it in your terminal
Use kubectl and the Kubernetes docs, like on exam day. Save any answer files under
/tmp/cka/. - 3
Check your work
curl -fsSL https://codewithmuh.com/labs/cka/t/ts-logs-2/verify | bashGot FAIL? Read which check failed, fix it, run it again. - 4
Clean up (optional)
curl -fsSL https://codewithmuh.com/labs/cka/t/ts-logs-2/cleanup | bash
Find the Pod that crashed with a given error
tsx-crash keep restarting. One of them crashes right after logging connection refused. Write only that Pod's name to /tmp/cka/crashed-pod.txt.Cluster:kubectl config use-context kind-cka
- 1
Set up the scenario
curl -fsSL https://codewithmuh.com/labs/cka/t/ts-logs-3/setup | bash - 2
Solve it in your terminal
Use kubectl and the Kubernetes docs, like on exam day. Save any answer files under
/tmp/cka/. - 3
Check your work
curl -fsSL https://codewithmuh.com/labs/cka/t/ts-logs-3/verify | bashGot FAIL? Read which check failed, fix it, run it again. - 4
Clean up (optional)
curl -fsSL https://codewithmuh.com/labs/cka/t/ts-logs-3/cleanup | bash
Finished this lesson?
0 of 3 tasks passed. Your readiness counts tasks, so run them before you move on.