Kubernetes Native Sidecar Containers
Native sidecar containers (stable in Kubernetes 1.29) solve a long-standing lifecycle problem: regular sidecar containers in the main containers list start and stop in an arbitrary order, causing proxy sidecars like Envoy to not be ready when the app starts, or log collectors to die before flushing the last batch. Native sidecars are init containers with restartPolicy: Always — they start before main containers and are guaranteed to terminate after them.
Overview
Overview
Native sidecar containers solve a persistent pain point of the sidecar pattern: no guaranteed lifecycle ordering between the proxy or collector and the main application. They arrived as beta, on by default, in Kubernetes 1.29 and graduated to stable in 1.33, with a single API field: restartPolicy: Always on an initContainer.
Before native sidecars
The sidecar pattern was an operator convention with no lifecycle guarantees. Engineers running Istio, Linkerd, Fluent Bit and similar tools built fragile workarounds with init containers, shell loops and sleep commands.
- Occasional connection refused at app startup — The proxy was not ready yet
- Systematic last-log-line loss in Jobs — The log collector was terminated before flushing its buffer
What changes
- Declared as — A regular container — An initContainer with restartPolicy: Always
- Startup order — Not guaranteed — Sidecar before the app
- Shutdown order — Not guaranteed — App before the sidecar
- Coordination — Application-level workarounds — Handled by the kubelet
> [!TIP] Platform teams that inject sidecars via MutatingAdmissionWebhook get correct lifecycle ordering transparently, just as the injection itself is transparent to developers.
Key concepts
- restartPolicy on initContainers
- The restartPolicy field is now valid on initContainers (K8s 1.29+). Setting restartPolicy: Always on an initContainer converts it to a native sidecar. The other two values (OnFailure and Never, the defaults for regular pods) cause the initContainer to behave like a traditional init container that must succeed before proceeding. A native sidecar (restartPolicy: Always initContainer): Starts in order with other initContainers Does NOT have to exit before the next initContainer or main containers start If the native sidecar's readinessProbe passes, the kubelet starts the next init container Is restarted if it crashes (like a main container with restartPolicy: Always) Is NOT sent SIGTERM until all main containers have exited The preStop hook on the native sidecar is important in mesh scenarios: you may want the proxy to continue accepting traffic for a few seconds after main container exit to drain in-flight connections before the proxy itself shuts down.
When to use it
- When troubleshooting service mesh proxy startup failures where the app gets connection refused because the proxy is not yet ready
- When Kubernetes Jobs are losing the last log batch because the log collector sidecar exits before flushing
- When designing a new sidecar injection pattern via MutatingAdmissionWebhook and wanting lifecycle guarantees without workarounds
- When evaluating K8s 1.29+ features for upgrading an existing cluster and assessing migration from manual sidecar ordering workarounds
Sign up free to read the full topic
More DevOps topics
- Kubernetes Descheduler
- Kubernetes Error Triage — Symptoms, Exit Codes and Cloud Equivalents
- Kubernetes Evictions and Node Pressure
- Kubernetes Gateway API v1
- Kubernetes Multi-cloud and Hybrid Cluster Patterns
- Kubernetes Multi-tenancy Patterns
- Kubernetes Network Policies
- Kubernetes Networking Deep Dive
- Kubernetes Observability: Metrics, Logs, and Traces
- Kubernetes Operators & CRDs
- Kubernetes Pod Networking & CNI
- Kubernetes Pod Scheduling
Start free on Cariara · Coding problems · System design studio