Pod Startup Forensics: The Tooling Gap
Why existing eBPF tools, continuous profilers, and APM platforms can't provide a durable pod-startup timeline that joins lifecycle records to kernel evidence.
Series · Pod Startup Forensics
Post 2 of 7
Series · Pod Startup Forensics
Post 2 of 7
- Pod Startup Forensics: The Problem
- Pod Startup Forensics: The Tooling Gap
- Pod Startup Forensics: Joining Lifecycle Events to Syscall Evidence
- Pod Startup Forensics: The Architecture
- Pod Startup Forensics: Surviving Deletion
- Pod Startup Forensics: Closing the Gap
- Pod Startup Forensics: Closure and What's Next
Table of Contents
kubectl get events gives raw chronology with no phase model. kubelet_pod_start_sli_duration_seconds gives per-kubelet aggregate telemetry with no per-pod label. Neither provides a per-pod startup timeline with syscall attribution. Kubernetes observability isn’t short on eBPF-based tooling, though, and eBPF is exactly the mechanism you’d reach for to explain why a phase blocked. So it’s worth checking, tool by tool, what each one actually does today, not what its name suggests it might do.
Tetragon: Real syscall visibility, no concept of a phase
Tetragon is Cilium’s eBPF-based runtime security and observability tool. Its base installation streams process-execution and process-exit events with Kubernetes identity, node, and time metadata. With a tracing policy configured for a relevant kernel function, it can also report process and syscall-adjacent events. That’s real, fine-grained, per-process attribution, and it is exactly the kind of signal you’d want during a slow init container: which operation, which process, which pod, down to the timestamp.
What Tetragon doesn’t document is a pod-startup phase to attach that signal to. Each event type, process_exec, process_exit, process_kprobe, process_uprobe, process_tracepoint, is a standalone record. Correlation across events uses Tetragon’s exec_id and parent_exec_id relationships; a host PID is also present, but exec_id is the documented process identifier for correlation. With a suitable tracing policy, Tetragon can report a connect()-related event with pod identity and a timestamp. It cannot place that event in an init-container or main-container startup interval without a phase model from somewhere else. Tetragon operates at the process and syscall layer; the Kubernetes lifecycle model remains a separate join. Right primitive, missing the other half.
Pixie: Deep runtime tracing, built for services that are already running
Pixie (px.dev) is a CNCF sandbox project, also eBPF-based, that automatically instruments HTTP, gRPC, DNS, and SQL traffic without code changes, builds service maps from the traffic it observes, and produces CPU flame graphs and resource profiles broken down by pod, node, and namespace. It collects, stores, and queries telemetry in-cluster; its telemetry tables use bounded in-memory storage, so retained data is intentionally short-lived.
Pixie’s value proposition is instant visibility into application traffic: request/response bodies, query latencies, who’s calling whom. An init container can generate protocol traffic or CPU behavior that Pixie observes while it runs. But those observations do not define schedule-to-ready intervals, distinguish a Kubernetes startup phase, or show whether an observed operation dominated that phase. Pixie can show useful fragments of a startup; its public documentation does not describe a per-pod lifecycle model that assembles schedule, pull, attach, mount, init, and readiness into one timeline.
Parca and Pyroscope: Continuous profilers, sampling code that’s already executing
Parca and Grafana Pyroscope are both continuous-profiling systems, but their collection paths are not identical. Parca Agent is an eBPF sampling profiler: it captures user- and kernel-space stacks 19 times per second and discovers targets across Kubernetes and systemd automatically, with no code changes or restarts required. Grafana Pyroscope is a continuous-profiling backend that aggregates profiles collected through language SDKs, auto-instrumentation, and eBPF-based collectors. It supports language-specific profiling integrations for Go, Java, Python, Ruby, Node.js, .NET, and Rust, and correlates profiles with metrics, logs, and traces.
Both tools can answer where a process spent CPU time and how that changed over time. A continuous profile may capture startup work, especially when a process runs long enough to receive samples, but it does not by itself provide Kubernetes phase boundaries or tie sampled CPU stacks to the wall-clock delay between lifecycle events. Startup is a one-shot sequence of distinct intervals—for example scheduling, image pulling, volume work, container initialization, and readiness. Neither product’s public documentation describes a Kubernetes lifecycle query that attributes a Created-to-Started interval to a named startup phase. A profiler may still collect samples while the container executes; it does not supply the missing phase boundary or the surrounding pull, attach, and mount timeline.
The generic platforms: Broad coverage, no startup-specific model
The remaining category is the generic Kubernetes observability platform: the kind that bundles logs, metrics, traces, and often eBPF-based profiling into one product and sells breadth. Metoro is representative. It combines eBPF-based kernel telemetry, APM-style dashboards and service maps, log collection, continuous CPU/memory profiling, Kubernetes events, resource data, and deployment context in one installation. That’s a real, wide net. The public product material reviewed for this project does not describe a dedicated model of the schedule-to-ready sequence a pod goes through before it starts serving anything.
OpenObserve is primarily a unified logs, metrics, traces, and RUM backend. It can also deploy OpenTelemetry eBPF instrumentation that captures application traces and RED metrics without application code changes. Its public documentation does not describe a purpose-built pod-startup lifecycle model, so collecting or querying those signals alone does not produce a phase-attributed startup timeline.
Across the public documentation reviewed here, broad signal coverage does not amount to a dedicated pod-startup phase model: a per-pod schedule-to-ready timeline that attaches an observation to a named lifecycle phase. These tools are strong at explaining particular signals. The missing question is which startup phase was slow, and why.
What’s actually missing
Line these up, and the shape of the gap gets sharper, not vaguer. Tetragon has process and kernel evidence but no phase model to hang it on. Pixie has deep runtime tracing but no documented lifecycle timeline. Parca and Pyroscope can show CPU behavior, including some startup work, but do not supply Kubernetes phase boundaries. The generic platforms provide breadth without a documented startup-specific model. Several could supply valuable inputs to a timeline: Events, logs, traces, profiles, and kernel observations. But turning those fragments into a durable per-pod forensic timeline still requires a lifecycle model, storage after a pod disappears, and joins that connect each fragment to a named startup interval. That’s not four small gaps between four adjacent categories of tool. It’s one gap, looked at from four angles.
