---
title: 'Kubernetes Native Sidecar Containers: 2026 Guide'
description: 'Kubernetes native sidecar containers, stable since v1.33: how a restartPolicy Always init container fixes startup order, Job completion, and graceful shutdown.'
url: https://nerdleveltech.com/kubernetes-native-sidecar-containers
language: en
date: '2026-06-14'
category: cloud-devops
tags:
  - kubernetes
  - native sidecar
  - init containers
  - pods
  - cloud-devops
markdown_url: https://nerdleveltech.com/kubernetes-native-sidecar-containers.md
attribution: 'Source: NerdLevelTech — https://nerdleveltech.com/kubernetes-native-sidecar-containers'
terms: https://nerdleveltech.com/llms.txt
---

# Kubernetes Native Sidecar Containers: 2026 Guide

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.[^1][^3]

## 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.[^1][^3][^7]

## 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.containers` sidecar
- Which Kubernetes version made native sidecars stable
- How to define one in YAML, and why `Always` is the only legal `restartPolicy`
- 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.[^1][^2] 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.[^1][^6]

## 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.[^3][^4] 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.[^7] 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:

```yaml
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]

```yaml
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.[^1][^5] 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.[^1][^5] Each sidecar receives `SIGTERM` and has until `terminationGracePeriodSeconds` to exit cleanly; if it doesn't, it gets `SIGKILL` (exit code 137).[^5] 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.[^6] 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.[^6] The manifest looks like any other Job — the sidecar just lives in `initContainers`:

```yaml
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.

## FAQ

**What is a native sidecar container in Kubernetes?**
A secondary container declared in a Pod's `initContainers` list with `restartPolicy: Always`. It starts before the main app, runs for the Pod's whole life, and stops after the app — ideal for logging, proxies, and metrics agents.[^1]

**Native sidecar vs init container — what's the difference?**
A plain init container runs once to completion before the app starts and then exits. A native sidecar only needs to start before the app and then keeps running, supports probes, and restarts independently if it crashes.[^1]

**Which Kubernetes version added native sidecars?**
Alpha in v1.28, beta (on by default) in v1.29, and stable in v1.33, released April 23, 2025. It is generally available in every supported release as of mid-2026.[^3][^7]

**How do I define a native sidecar?**
Put the container in `spec.initContainers` and set `restartPolicy: Always` on it. `Always` is the only accepted value; `OnFailure` or `Never` makes Pod creation fail.[^1]

**Why does my Job Pod never complete when it has a sidecar?**
That's the old-style sidecar problem: a container in `spec.containers` keeps running after the main task finishes, so the Job never completes. Move it to a native sidecar — native sidecars don't block Pod completion in Jobs.[^6]

**In what order do native sidecars start and stop?**
They start before the app in list order, and stop after the app in reverse order, each getting `SIGTERM` then `SIGKILL` after `terminationGracePeriodSeconds`.[^1][^5]

**Can a native sidecar have probes and resource limits?**
Yes — startup, readiness, and liveness probes plus `resources` requests and limits, unlike plain init containers.[^1]

## 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](https://nerdleveltech.com/kubernetes-explained-a-2026-hands-on-guide); to keep rollouts clean while sidecars drain, pair it with [zero-downtime Kubernetes deployments](https://nerdleveltech.com/kubernetes-zero-downtime-deployments-tutorial); and when your sidecar is an observability agent, wire it into an [OpenTelemetry Collector tracing pipeline](https://nerdleveltech.com/opentelemetry-collector-nodejs-tracing-tutorial).

[^1]: Kubernetes documentation, "Sidecar Containers" — https://kubernetes.io/docs/concepts/workloads/pods/sidecar-containers/
[^2]: Kubernetes documentation, "Init Containers" — https://kubernetes.io/docs/concepts/workloads/pods/init-containers/
[^3]: Kubernetes blog, "Kubernetes v1.33: Octarine" (April 23, 2025) — https://kubernetes.io/blog/2025/04/23/kubernetes-v1-33-release/
[^4]: KEP-753: Sidecar Containers (sig-node) — https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/753-sidecar-containers/README.md
[^5]: Kubernetes blog, "Start Sidecar First: How To Avoid Snags" (June 3, 2025) — https://kubernetes.io/blog/2025/06/03/start-sidecar-first/
[^6]: Kubernetes documentation, "Adopting Sidecar Containers" — https://kubernetes.io/docs/tutorials/configuration/pod-sidecar-containers/
[^7]: Kubernetes releases — https://kubernetes.io/releases/
