How Kubernetes handles logs, metrics, and observability — from individual container stdout to cluster-wide aggregation. A core Troubleshooting topic on the CKA exam and a production necessity. Synthesized from CKA Day 36 — Kubernetes Logging and Monitoring.
The Three Levels of Kubernetes Logging
Kubernetes generates logs at three distinct levels. A CKA candidate must know how to access each one:
Level
Scope
Access Method
CKA Relevance
Container
Single container stdout/stderr
kubectl logs
High — daily debugging and exam tasks
Node
Runtime and kubelet journals
SSH + journalctl, /var/log
Medium — node NotReady diagnosis
Cluster
Aggregated from all nodes
Centralized stack (EFK, PLG)
Low on exam; high in production
Level 1: Container Logs
Basic Log Retrieval
Every container’s stdout and stderr are collected by the kubelet and made available via the API server:
# Default container logskubectl logs nginx-pod# Container in a multi-container Podkubectl logs multi-pod -c sidecar# Previous instance (after crash or restart)kubectl logs nginx-pod --previous# Live tailkubectl logs nginx-pod -f# Last N lineskubectl logs nginx-pod --tail=100# Combined: follow previous containerkubectl logs nginx-pod --previous -f
Exam Trap:kubectl logs without -c fails on multi-container Pods. Always know which container you need, or use -c explicitly. Source: CKA Day 36
The --previous Flag
When a container restarts (e.g., due to CrashLoopBackOff or liveness probe failure), the current kubectl logs output only shows the new instance. The --previous flag retrieves logs from the terminated container — this is often the only way to see the actual error that caused the crash.
# Classic troubleshooting chainkubectl get pod nginx-pod # Check RESTARTS columnkubectl describe pod nginx-pod # Check Events for the whykubectl logs nginx-pod --previous # Read the crash outputkubectl exec -it nginx-pod -- /bin/sh # Debug interactively if running
This chain mirrors the “Troubleshooting Chain” taught across the CKA course: get → describe → logs → exec. Source: CKA Day 0
Level 2: Node Logs
When the API server is unreachable or kubectl logs returns no data, inspect the node directly.
Filesystem Paths
On clusters using containerd or CRI-O (the modern default):
Path
Contents
/var/log/containers/
Symlinks to container log files, named <pod>_<ns>_<container>-<id>.log
/var/log/pods/
Pod-level directories with container log files
/var/log/syslog or /var/log/messages
General system logs
Service Journal Logs
# kubelet logs — critical for node healthjournalctl -u kubelet -n 100# container runtime logsjournalctl -u containerd -n 100# API server logs (on control plane node)journalctl -u kube-apiserver -n 100
CKA Note: In the exam environment, you may be given SSH access to nodes. Knowing where to look without the API server is a differentiator.
Level 3: Cluster Logging Architecture
Production clusters cannot rely on kubectl logs for operational visibility. The standard pattern uses a node-level agent that forwards logs to a central store.
The Metrics Server is an in-memory aggregator that collects CPU and memory usage from kubelets and exposes them via the Kubernetes metrics API:
# Install Metrics Server (if missing)kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml# Verifykubectl get pods -n kube-system | grep metrics-server
Kind Cluster Note: On Kind clusters, Metrics Server requires --kubelet-insecure-tls because Kind uses self-signed kubelet serving certificates. In production, proper certificate trust is required.
kubectl top
# Node-level metricskubectl top node# Pod-level metricskubectl top pod -n default# Container-level breakdownkubectl top pod my-pod --containers# Sort by CPUkubectl top pod --all-namespaces --sort-by=cpu
Output Column
Meaning
CPU(cores)
Current CPU consumption in millicores or cores
MEMORY(bytes)
Current memory consumption in MiB/GiB
Metrics Server vs Full Monitoring
Aspect
Metrics Server
Prometheus + Grafana
Data retention
In-memory only (~1 minute)
Persistent time-series storage
Historical trends
❌ No
✅ Yes
Alerting
❌ No
✅ Yes (Alertmanager)
Custom metrics
❌ No
✅ Yes (HPA v2 with custom metrics API)
CKA exam
✅ Tested
❌ Not tested
For the exam, Metrics Server is sufficient. For production, Prometheus and Grafana (or a managed equivalent) are the standard stack.
# Fastest log inspection sequencekubectl get pod <name> -o wide # IP, node, restartskubectl describe pod <name> # Events and statekubectl logs <name> --previous # Crash reasonkubectl logs <name> -c <container> # Multi-container target# Node-level diagnosis (SSH to node)journalctl -u kubelet -n 50ls /var/log/containers/ | grep <pod-name># Resource pressure checkkubectl top nodekubectl top pod -n <namespace>
Time Management: The exam rewards knowing the exact log source for each component. API server issues → control plane node journals. Pod crashes → kubectl logs --previous. Network issues → CNI and kube-proxy logs in kube-system.
Production Best Practices
Practice
Rationale
Log to stdout
Let the runtime handle log collection; avoid file-based logging when possible
Use structured logs (JSON)
Easier parsing by Fluentd/Fluent Bit and downstream analytics
Set log rotation
Prevent node disks from filling up; configure containerLogMaxSize and containerLogMaxFiles in kubelet
Install Metrics Server before HPA
HPA cannot function without it; verify on every new cluster
Separate metrics and logs pipelines
Don’t conflate Prometheus (metrics) with Loki/EFK (logs); they have different storage and query patterns
Monitor the monitors
If Fluent Bit or Metrics Server fails, you are flying blind
Practical Practice
Exam-style hands-on tasks for this topic. Complete each task before reviewing the solution. Time yourself — CKA tasks average 5–7 minutes.
Task 1: Retrieve Previous Container Logs
A Pod app-1 crashed — retrieve logs from the previous container instance.
Requirements: Do not delete the Pod.
Verification:kubectl logs app-1 --previous | tail -5Solution:
kubectl get pod app-1kubectl describe pod app-1 | grep -A 5 "Last State"kubectl logs app-1 --previous | tail -20
Task 2: Stream Multi-Container Pod Logs
Stream logs from all containers in a multi-container Pod api-1.
Requirements: Show logs from both containers simultaneously.
Verification: Visual confirmation of mixed output.
Solution:
kubectl logs api-1 -c app --tail=10kubectl logs api-1 -c sidecar --tail=10# Or follow both in separate terminals:kubectl logs api-1 -c app -fkubectl logs api-1 -c sidecar -f
Task 3: Install Metrics Server
Install Metrics Server and verify kubectl top node works.
Requirements: Use the official release manifest. Add --kubelet-insecure-tls on Kind.
Verification:kubectl top nodeSolution:
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml# On Kind, patch the deployment:kubectl patch deployment metrics-server -n kube-system --type='json' -p='[{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value": "--kubelet-insecure-tls"}]'kubectl top nodekubectl top pod -n kube-system
Task 4: Identify and Evict Memory Pressure
A node is under memory pressure — identify the top memory-consuming Pod and evict it if necessary.
Requirements: Use kubectl top to find the culprit.
Verification:kubectl top pod --all-namespaces --sort-by=memorySolution:
kubectl top nodekubectl top pod --all-namespaces --sort-by=memorykubectl get pod <highest-pod> -o yaml | grep -A 2 "qosClass"# Evict by deleting the Pod (controller will recreate if it exists)kubectl delete pod <highest-pod> -n <ns>kubectl top node