Kubernetes Native Sidecar Containers: 2026 Guide
June 14, 2026
A native sidecar container is an entry in a Pod's initContainers list with restartPolicy: Always. Stable since Kubernetes v1.33, it starts before the main app, keeps running for the Pod's whole life, and shuts down only after the app container exits.12
TL;DR
For years a "sidecar" was just an extra container in spec.containers — a pattern with two nagging bugs: nothing guaranteed it started before your app, and in a Job it never stopped, so the Job hung forever. Kubernetes native sidecars fix both. You declare the sidecar in initContainers with restartPolicy: Always; Kubernetes then starts it before the app, lets the rest of the Pod proceed while it keeps running, terminates it after the app on shutdown, and — crucially — lets Jobs complete. The feature went stable in v1.33 (April 2025), so it is generally available in every supported release as of mid-2026.123
What you'll learn
- What a native sidecar container is and the one-line spec that creates it
- How a native sidecar differs from a plain init container
- How a native sidecar differs from a regular (old-style)
spec.containerssidecar - Which Kubernetes version made native sidecars stable
- How to define one in YAML, and why
Alwaysis the only legalrestartPolicy - The startup and termination ordering rules
- Why native sidecars finally make sidecars work with Jobs
- Whether native sidecars support probes and resource limits
What is a native sidecar container in Kubernetes?
A native sidecar container is a secondary container that runs alongside your main application container in the same Pod, providing support functions like logging, metrics, a proxy, or config sync without touching the app's code.1 What makes it "native" is the implementation: Kubernetes treats it as a special case of an init container — specifically, an entry in spec.initContainers that sets restartPolicy: Always.1
That single field changes the container's lifecycle. A normal init container runs once and exits before the next container starts. A native sidecar instead starts in the init phase, is allowed to keep running, and stays alive for the entire life of the Pod — the behavior you actually want from a logging agent or service-mesh proxy.1
How is a native sidecar different from an init container?
A regular init container must run to completion before the next container starts and is gone before your app comes up; a native sidecar only has to start before Kubernetes moves on, and then it keeps running the whole time.14 They live in the same initContainers list, but the restartPolicy: Always flag flips one into a long-lived companion.
There are two more practical differences. First, native sidecars support startupProbe, readinessProbe, and livenessProbe; plain init containers do not accept those lifecycle and probe fields at all.1 Second, a native sidecar restarts on its own if it crashes, even in a Pod whose Pod-level restartPolicy is Never or OnFailure — built-in sidecars follow initContainers[].restartPolicy: Always rather than the Pod-level policy.1
| Behavior | Regular init container | Native sidecar (restartPolicy: Always) |
|---|---|---|
| Defined in | spec.initContainers | spec.initContainers |
| Must finish before app starts | Yes | No — only needs to start |
| Runs during the Pod's life | No | Yes |
| Supports probes | No | Yes |
| Can define resource requests/limits | Yes | Yes |
| Restarts independently if it crashes | No | Yes |
How is a native sidecar different from a regular (old-style) sidecar?
A regular sidecar is just another container in spec.containers, with no ordering or completion guarantees; a native sidecar lives in spec.initContainers with restartPolicy: Always, which guarantees it starts before the app and never blocks Pod completion.1 The old pattern worked, but it had two well-known sharp edges.
The first is startup races: regular containers in spec.containers are started without any readiness ordering, so even a sidecar listed before your app isn't guaranteed to be ready when the app starts — and the app may fail a database call or begin serving before the proxy or auth sidecar is up. The second is Job completion, covered in its own section below. Native sidecars remove both problems by leaning on the init-container machinery, which is a core reason the Kubernetes project built the feature instead of leaving sidecars as a convention.15
Which Kubernetes version added native sidecar containers?
Native sidecar containers (KEP-753, the SidecarContainers feature gate) landed as alpha in v1.28, became beta and enabled by default in v1.29, and graduated to stable in v1.33, which was released on April 23, 2025.26 Because it is stable, the feature is on by default and needs no feature-gate flag.
In practice that means every currently supported Kubernetes release ships native sidecars as a generally available feature: the supported branches as of mid-2026 are 1.34, 1.35, and 1.36.3 If you are on v1.33 or newer, you can use native sidecars today; if you are on v1.29 through v1.32, the feature is present (beta, on by default) but you are running an out-of-support release and should upgrade.
How do you define a native sidecar container?
You add the sidecar to initContainers and set restartPolicy: Always on it. That is the entire trick — the app container stays in spec.containers as usual:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 1
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
initContainers:
- name: log-shipper
image: log-shipper:1.0
restartPolicy: Always # this line makes it a native sidecar
resources:
requests:
cpu: 50m
memory: 64Mi
startupProbe:
httpGet:
path: /healthz
port: 9000
containers:
- name: app
image: my-app:2.3
ports:
- containerPort: 8080
One rule to remember: for an init container, Always is the only accepted value of restartPolicy. Setting it to OnFailure or Never is rejected, and the Pod fails to create:1
initContainers:
- name: log-shipper
image: log-shipper:1.0
restartPolicy: OnFailure # rejected — Pod creation fails validation
So there is no ambiguity — either you omit restartPolicy (a normal run-once init container) or you set it to Always (a native sidecar).
How do native sidecars start up and shut down?
Native sidecars start before your app, in the order they appear in initContainers, and shut down after your app, in the reverse order.17 On startup, Kubernetes proceeds to the next init container or to the main containers once the sidecar has started — and, if the sidecar defines a startupProbe, once that probe succeeds.1 So adding a startupProbe is what gives you the "proxy is ready before the app sends its first request" guarantee; without one, the app only waits for the sidecar process to have started, not to be ready.
On shutdown, the kubelet holds off on stopping the sidecars until the main application container has fully stopped, then terminates the sidecars in the opposite order of their appearance in the spec.17 Each sidecar receives SIGTERM and has until terminationGracePeriodSeconds to exit cleanly; if it doesn't, it gets SIGKILL (exit code 137).7 This ordering means your logging sidecar is still alive to flush the app's final log lines, and your proxy is still up to drain the app's last in-flight connections.
Why do native sidecars finally make sidecars work with Jobs?
Because native sidecars do not block Pod completion: once all the regular containers in a Job Pod finish, Kubernetes sends the sidecars SIGTERM and the Job completes normally.5 This is one of the main reasons the feature exists. With an old-style sidecar in spec.containers, a Job with a logging or proxy sidecar would run the main task to success, but the ever-running sidecar kept the Pod alive, so the Job sat at "1 running" forever and teams resorted to brittle hacks — shared emptyDir exit flags, a kubectl call to kill the sidecar, or third-party terminators.
Native sidecars delete all of that. In a Job, where restartPolicy is OnFailure or Never, the sidecar is treated as supporting infrastructure: its continued running no longer counts against completion.5 The manifest looks like any other Job — the sidecar just lives in initContainers:
apiVersion: batch/v1
kind: Job
metadata:
name: nightly-export
spec:
template:
spec:
restartPolicy: Never
initContainers:
- name: db-proxy
image: db-proxy:1.0
restartPolicy: Always # native sidecar — won't block completion
containers:
- name: export
image: export-job:1.0 # when this finishes, the Job completes
You get the convenience of a sidecar (centralized logging, a database proxy, a secrets agent) with the clean termination semantics a batch workload needs.
Can native sidecars use probes and resource limits?
Yes — native sidecars support startupProbe, readinessProbe, and livenessProbe, and they take resources requests and limits just like any regular container.1 This is a real upgrade over plain init containers, which don't accept probe or lifecycle fields. Use a startupProbe when you need the app to wait for the sidecar to be genuinely ready (not just started), and a livenessProbe to have a wedged sidecar restarted on its own.
Native sidecars also get their out-of-memory (OOM) score adjusted in line with the primary containers, so the kubelet is less likely to evict the sidecar first under memory pressure.1 As with any container, set resources.requests so the scheduler accounts for the sidecar, and resources.limits so a runaway agent can't starve your app.
Bottom line
If you are on Kubernetes v1.33 or newer, native sidecars are the right default for any supporting container: declare it in initContainers with restartPolicy: Always and you get guaranteed start-before-app ordering, clean reverse-order shutdown, and Jobs that actually complete. The old spec.containers sidecar pattern is now legacy — migrate it. For the broader Pod and workload model, see our Kubernetes hands-on guide for 2026; to keep rollouts clean while sidecars drain, pair it with zero-downtime Kubernetes deployments; and when your sidecar is an observability agent, wire it into an OpenTelemetry Collector tracing pipeline.
Footnotes
-
Kubernetes documentation, "Sidecar Containers" — https://kubernetes.io/docs/concepts/workloads/pods/sidecar-containers/ ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11 ↩12 ↩13 ↩14 ↩15 ↩16 ↩17 ↩18 ↩19 ↩20 ↩21
-
Kubernetes blog, "Kubernetes v1.33: Octarine" (April 23, 2025) — https://kubernetes.io/blog/2025/04/23/kubernetes-v1-33-release/ ↩ ↩2 ↩3 ↩4
-
Kubernetes releases — https://kubernetes.io/releases/ ↩ ↩2 ↩3
-
Kubernetes documentation, "Init Containers" — https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ ↩
-
Kubernetes documentation, "Adopting Sidecar Containers" — https://kubernetes.io/docs/tutorials/configuration/pod-sidecar-containers/ ↩ ↩2 ↩3 ↩4
-
KEP-753: Sidecar Containers (sig-node) — https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/753-sidecar-containers/README.md ↩
-
Kubernetes blog, "Start Sidecar First: How To Avoid Snags" (June 3, 2025) — https://kubernetes.io/blog/2025/06/03/start-sidecar-first/ ↩ ↩2 ↩3 ↩4