Istio sidecar injection is not a feature you "enable" on a namespace; rather, it’s a process that happens to the pods running within a namespace.
Here’s a namespace with sidecar injection enabled, showing a running pod and the injected sidecar container:
apiVersion: v1
kind: Pod
metadata:
name: my-app-pod
namespace: default
labels:
app: my-app
spec:
containers:
- name: my-app-container
image: nginx:latest
ports:
- containerPort: 80
- name: istio-proxy # This is the injected sidecar
image: docker.io/istio/proxyv2:1.18.0 # Example version
args:
- /usr/local/bin/istio-proxy
- --config
- "proxy.istio.io/config"
# ... other proxy arguments
The real magic isn’t in the namespace itself, but in how Istio intercepts pod creation and modifies the pod’s definition to include the sidecar. This is primarily controlled by admission controllers.
When you create or update a pod in a Kubernetes cluster where Istio is installed, the Istio istiod component acts as a validating and mutating admission webhook. If a namespace has the istio-injection=enabled label, istiod will intercept the pod creation request and inject the Envoy sidecar container into the pod’s spec.
The problem Istio solves is enabling advanced networking features like traffic management, observability, and security without requiring changes to your application code. Instead of embedding libraries into your application, Istio injects a fully-fledged Envoy proxy as a sidecar container next to your application container. This sidecar intercepts all inbound and outbound network traffic for the pod, allowing Istio to control and observe it.
Here’s how it works internally:
- Kubernetes API Server: When you
kubectl applya pod definition, the request goes to the Kubernetes API server. - Admission Webhooks: The API server, configured with Istio’s admission webhooks, forwards the pod creation request to
istiod. istiodLogic:istiodchecks the pod’s namespace for theistio-injection=enabledlabel.- Mutation: If the label is present,
istiodmodifies the pod definition in memory, adding the Envoy sidecar container. It also injects necessary volumes and environment variables for the sidecar to function. - API Server Response: The modified pod definition is sent back to the API server, which then creates the pod with both your application container and the Istio sidecar.
- Envoy Initialization: The
istio-proxycontainer starts, initializes itself based on configuration provided byistiod, and begins proxying traffic for your application container.
The primary lever you control is the istio-injection label on the namespace.
# Enable sidecar injection for the 'default' namespace
kubectl label namespace default istio-injection=enabled
# Verify the label is set
kubectl get namespace default --show-labels
When you create a pod in a namespace with this label, Istio’s admission controller automatically injects the sidecar. You don’t need to modify your pod YAML to request the sidecar; Istio does it for you. To disable injection for a namespace, you simply remove the label:
# Disable sidecar injection for the 'default' namespace
kubectl label namespace default istio-injection-
It’s worth noting that you can also explicitly disable injection for a specific pod using an annotation, even if the namespace has injection enabled:
apiVersion: v1
kind: Pod
metadata:
name: my-app-pod-no-injection
namespace: default
annotations:
sidecar.istio.io/inject: "false" # Explicitly disable
spec:
containers:
- name: my-app-container
image: nginx:latest
This annotation allows for fine-grained control, letting you opt-out specific workloads from Istio’s management if necessary.
The most surprising thing about how Istio achieves this seamless injection is that it doesn’t rely on any special Kubernetes features beyond standard admission controllers. It’s a testament to the extensibility of Kubernetes that a complex system like Istio can be built by intercepting and modifying resource definitions before they are persisted. This mechanism allows Istio to manage traffic, enforce policies, and gather telemetry without any application code modifications, treating the network layer as a programmable entity.
The next concept you’ll likely encounter is how to configure the behavior of these injected sidecars, particularly concerning traffic routing and security policies.