Sidecar Injection
The automatic process by which a service mesh adds a proxy container to every new pod created in a labeled namespace. Triggered by a Kubernetes mutating admission webhook - no changes to application manifests are required.
What is Sidecar Injection
Sidecar injection is how the service mesh gets its proxy container into every pod automatically. You do not add the sidecar to your Deployment YAML. You label the namespace, and Kubernetes does the rest.
Developer creates a Deployment | vPod creation request sent to Kubernetes API server | vMutating Admission Webhook intercepts the request(installed by the service mesh during setup) | vWebhook adds the sidecar proxy container to the pod spec | vPod starts with two containers: app + sidecarEnabling Injection
Injection is controlled at the namespace level with a label:
## Enable automatic sidecar injection for the production namespacekubectl label namespace production istio-injection=enabled ## Verify the label is appliedkubectl get namespace production --show-labelsAfter labeling, every new pod created in that namespace automatically gets the sidecar. Existing pods are not affected - they must be restarted to get the sidecar injected.
Verifying Injection Worked
After deploying a pod to a labeled namespace, check the container count:
kubectl get pods -n production ## Correct output after injection:## NAME READY STATUS RESTARTS## orders-api-abc-xyz 2/2 Running 0 ## 2/2 means: app container + sidecar both running## 1/1 means: injection did not happen - check namespace labelManual Injection
You can also inject the sidecar manually for specific pods without labeling the namespace:
## Inject sidecar into a specific deployment manifestistioctl kube-inject -f deployment.yaml | kubectl apply -f -Injection and mTLS
Sidecar injection is a prerequisite for mTLS. If a pod does not have a sidecar, it cannot participate in mTLS. This is why you must use PERMISSIVE mode during migration - pods without sidecars would fail all communication in STRICT mode.
Namespace with label → pods get sidecars → mTLS capableNamespace without label → pods have no sidecars → mTLS not possibleRememberLabeling a namespace only affects NEW pods. If you label a namespace and existing pods are already running, those pods still have no sidecar. You must delete and recreate them (or roll the deployment) to trigger injection.
Common MistakeLabeling kube-system, istio-system, or kube-public for sidecar injection. These namespaces contain core cluster components that will break if their traffic is intercepted by mesh proxies. Only label application namespaces.
Frequently Asked Questions
How does sidecar injection actually add a container without editing my deployment YAML?
It relies on a Kubernetes mutating admission webhook: when you label a namespace (e.g., `istio-injection=enabled`), the mesh's control plane registers a webhook that intercepts every pod creation request in that namespace and rewrites the pod spec on the fly, adding the proxy container before the pod is actually scheduled. You never touch your Deployment or application manifest — the mutation happens at the API server admission stage, invisible to `kubectl apply`.
What's a common gotcha with automatic sidecar injection?
Init containers or jobs that run and exit quickly can finish before the sidecar proxy is ready, or the pod can hang because the sidecar container never terminates on its own (a known Istio issue with Kubernetes Jobs prior to native sidecar support). Also, injecting a whole namespace means you can't selectively skip individual pods without an explicit `sidecar.istio.io/inject: false` annotation on each one — an easy thing to forget for debug or one-off pods.