Asterrr's Handbook

Observability

Logs, metrics and traces in Kubernetes, how Prometheus, OpenTelemetry, Jaeger and Fluent Bit fit together, the metrics APIs behind autoscaling, and SLOs and cost signals.

Exam tasks: 4.1 (observability: telemetry signals, Prometheus, OpenTelemetry, tracing, logging, cost management)

The decision: which signal answers the question (a log line, a metric or a trace), and which CNCF project collects, stores or shows it?

Three signals, three questions

SignalAnswersShapeTypical CNCF tool
LogsWhat exactly happened in this process at this moment?Timestamped text or structured eventsFluentd, Fluent Bit
MetricsHow much, how often, how fast, over time?Numeric samples with labels, cheap to storePrometheus
TracesWhere did this one request spend its time across services?A tree of spans sharing a trace IDJaeger, OpenTelemetry
  • Monitoring watches for failure modes you predicted (an alert on error rate). Observability lets you ask new questions about failures you didn't predict, by correlating all three signals.
  • Some newer material adds profiles (continuous CPU and memory profiling) as a fourth signal. OpenTelemetry is adding profiling support, but the exam focuses on the three above.

Exam signal

"Which microservice made the checkout request slow?" is a trace question. "Is the error rate above 2% for the last 10 minutes?" is a metric question. "What stack trace did the payment Pod print before it crashed?" is a log question.

Logs in Kubernetes

  • Containers should write to stdout and stderr. The container runtime writes those streams to files on the node, and the kubelet serves them to kubectl logs and rotates them.
  • kubectl logs <pod> -c <container> picks a container, --previous shows the last crashed instance, and -f follows the stream.
  • Kubernetes has no built-in log storage. When a Pod is deleted or its node dies, its logs go with it. That's why clusters ship logs elsewhere.
PatternHow it worksTrade-off
Node-level agent (most common)A DaemonSet such as Fluent Bit tails every container log file on each nodeOne agent per node, no app changes
SidecarA helper container in the Pod streams or ships the app's log fileWorks for apps that only log to files, costs a container per Pod
App pushes directlyThe app sends logs to a backend over the networkCouples the app to the backend
  • Fluentd (graduated) is the original unified logging layer. Fluent Bit is its lightweight sibling under the same CNCF project, preferred as the per-node agent.
  • Structured logs (JSON with fields like level and trace_id) can be filtered and linked to traces.

kubectl logs as the logging strategy

kubectl logs reads what's still on the node. It can't search across Pods, and it shows nothing after the Pod is gone. An answer that relies on it for audits or post-incident review is wrong; centralized shipping is the fix.

Metrics and Prometheus

  • Prometheus (graduated, the second project to join CNCF after Kubernetes) pulls (scrapes) metrics over HTTP from /metrics endpoints at an interval and stores them as time series: a metric name plus labels.
  • Kubernetes components (API server, kubelet, scheduler, controller manager) expose metrics in Prometheus format already. Software that can't, gets an exporter that translates (for example node_exporter for host metrics).
  • Short-lived batch jobs can't be scraped reliably, so they push to the Pushgateway, which Prometheus scrapes.
  • You query with PromQL, for example rate(http_requests_total[5m]).
  • Alertmanager receives alerts from Prometheus rules and handles routing, grouping, deduplication and silencing. Prometheus itself evaluates the rules; it doesn't send emails or pages.
  • Prometheus is built for a single server. Thanos and Cortex (both incubating) add long-term storage and a global view across many Prometheus servers.
Metric typeBehaviourExample
CounterOnly goes up (resets on restart)Total requests served
GaugeGoes up and downCurrent memory use, queue length
HistogramCounts observations in buckets, so you can compute percentiles on the serverRequest latency
SummaryComputes quantiles in the clientRequest latency, pre-aggregated

Grafana is the CNCF dashboard project

Grafana is the usual dashboard on top of Prometheus, but it's a Grafana Labs project, not a CNCF project. If the question asks which CNCF graduated project collects and stores metrics, the answer is Prometheus.

The metrics APIs behind autoscaling

  • metrics-server collects CPU and memory usage from each kubelet and serves the Resource Metrics API (metrics.k8s.io). It keeps only current values in memory: it isn't a monitoring system.
  • kubectl top pods and kubectl top nodes fail until metrics-server (or another provider) is installed.
  • The HPA reads resource metrics, or custom and external metrics served by an adapter.
  • kube-state-metrics is different: it turns the state of objects (desired vs available replicas, Pod phase) into Prometheus metrics. Usage comes from metrics-server; object state comes from kube-state-metrics.

Traces and OpenTelemetry

  • A trace is one request's journey. Each step is a span with a start time, duration and parent. The trace ID travels between services in request headers, usually in the W3C Trace Context format.
  • OpenTelemetry (OTel, graduated) is the vendor-neutral standard for producing and moving telemetry: APIs, SDKs, auto-instrumentation, the OTLP protocol and the Collector. It covers traces, metrics and logs.
  • OTel is not a backend. It sends data to Jaeger, Prometheus or a commercial vendor. Switching vendors means changing the Collector's exporter, not re-instrumenting code.
  • The Collector pipeline is receivers, then processors (batching, sampling, dropping sensitive attributes), then exporters. It runs as an agent per node, a gateway Deployment, or both.
  • Jaeger (graduated) stores and visualizes traces. Current Jaeger is built on the OTel Collector and accepts OTLP natively.

Legacy: use OpenTelemetry instead

OpenTracing (a CNCF project) and OpenCensus (from Google) merged into OpenTelemetry in 2019. Both are archived. Jaeger's own client libraries are also retired in favour of the OpenTelemetry SDKs.

SLOs, alerting and cost

TermMeaningExample
SLIA measured indicatorShare of checkout requests answered under 300 ms
SLOYour internal target for the SLI99.5% over 30 days
SLAA contract with a penalty, looser than the SLO99% or the customer gets credits
Error budgetWhat the SLO lets you miss0.5% of requests per 30 days
  • Alert on symptoms users feel (SLO burn rate, error rate, latency) rather than on every cause (CPU at 80%).
  • Cost is an observability signal too. Requests drive scheduling and cost, so oversized requests waste nodes even when usage is low. Compare requested vs used resources and right-size.
  • OpenCost (incubating) allocates cluster cost to namespaces, workloads and labels from usage and cloud prices. Labels such as team and cost-center make the breakdown useful.
Pull
Prometheus scrapes targets. Pushgateway is the exception for short-lived jobs.
metrics.k8s.io
Resource Metrics API served by metrics-server, used by HPA and kubectl top.
OTLP
OpenTelemetry's wire protocol for traces, metrics and logs.
stdout / stderr
Where containers should log so the kubelet and node agents can collect it.

Scenarios

Scenario
A team at Larkspur Media sees that some product page requests take 6 seconds. Each request passes through five microservices. Which observability signal will most directly show which service adds the delay?
Scenario
An operator runs `kubectl top pods` on a new cluster and gets an error saying the metrics API is not available. What is missing?
Scenario
A platform team wants every service instrumented once, with the freedom to switch the tracing backend later without changing application code. What should they adopt?

Further reading

On this page