Installing the Sidecar

Injection

In order to take advantage of all of Istio’s features, pods in the mesh must be running an Istio sidecar proxy.

The following sections describe two ways of injecting the Istio sidecar into a pod: enabling automatic Istio sidecar injection in the pod’s namespace, or by manually using the istioctl command.

When enabled in a pod’s namespace, automatic injection injects the proxy configuration at pod creation time using an admission controller.

Manual injection directly modifies configuration, like deployments, by adding the proxy configuration into it.

If you are not sure which one to use, automatic injection is recommended.

Automatic sidecar injection

Sidecars can be automatically added to applicable Kubernetes pods using a mutating webhook admission controller provided by Istio.

While admission controllers are enabled by default, some Kubernetes distributions may disable them. If this is the case, follow the instructions to turn on admission controllers.

When you set the istio-injection=enabled label on a namespace and the injection webhook is enabled, any new pods that are created in that namespace will automatically have a sidecar added to them.

Note that unlike manual injection, automatic injection occurs at the pod-level. You won’t see any change to the deployment itself. Instead, you’ll want to check individual pods (via kubectl describe) to see the injected proxy.

Deploying an app

Deploy sleep app. Verify both deployment and pod have a single container.

Zip

  1. $ kubectl apply -f @samples/sleep/sleep.yaml@
  2. $ kubectl get deployment -o wide
  3. NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
  4. sleep 1/1 1 1 12s sleep curlimages/curl app=sleep
  1. $ kubectl get pod
  2. NAME READY STATUS RESTARTS AGE
  3. sleep-8f795f47d-hdcgs 1/1 Running 0 42s

Label the default namespace with istio-injection=enabled

  1. $ kubectl label namespace default istio-injection=enabled --overwrite
  2. $ kubectl get namespace -L istio-injection
  3. NAME STATUS AGE ISTIO-INJECTION
  4. default Active 5m9s enabled
  5. ...

Injection occurs at pod creation time. Kill the running pod and verify a new pod is created with the injected sidecar. The original pod has 1/1 READY containers, and the pod with injected sidecar has 2/2 READY containers.

  1. $ kubectl delete pod -l app=sleep
  2. $ kubectl get pod -l app=sleep
  3. pod "sleep-776b7bcdcd-7hpnk" deleted
  4. NAME READY STATUS RESTARTS AGE
  5. sleep-776b7bcdcd-7hpnk 1/1 Terminating 0 1m
  6. sleep-776b7bcdcd-bhn9m 2/2 Running 0 7s

View detailed state of the injected pod. You should see the injected istio-proxy container and corresponding volumes.

  1. $ kubectl describe pod -l app=sleep
  2. ...
  3. Events:
  4. Type Reason Age From Message
  5. ---- ------ ---- ---- -------
  6. ...
  7. Normal Created 11s kubelet Created container istio-init
  8. Normal Started 11s kubelet Started container istio-init
  9. ...
  10. Normal Created 10s kubelet Created container sleep
  11. Normal Started 10s kubelet Started container sleep
  12. ...
  13. Normal Created 9s kubelet Created container istio-proxy
  14. Normal Started 8s kubelet Started container istio-proxy

Disable injection for the default namespace and verify new pods are created without the sidecar.

  1. $ kubectl label namespace default istio-injection-
  2. $ kubectl delete pod -l app=sleep
  3. $ kubectl get pod
  4. namespace/default labeled
  5. pod "sleep-776b7bcdcd-bhn9m" deleted
  6. NAME READY STATUS RESTARTS AGE
  7. sleep-776b7bcdcd-bhn9m 2/2 Terminating 0 2m
  8. sleep-776b7bcdcd-gmvnr 1/1 Running 0 2s

Controlling the injection policy

In the above examples, you enabled and disabled injection at the namespace level. Injection can also be controlled on a per-pod basis, by configuring the sidecar.istio.io/inject label on a pod:

ResourceLabelEnabled valueDisabled value
Namespaceistio-injectionenableddisabled
Podsidecar.istio.io/inject“true”“false”

If you are using control plane revisions, revision specific labels are instead used by a matching istio.io/rev label. For example, for a revision named canary:

ResourceEnabled labelDisabled label
Namespaceistio.io/rev=canaryistio-injection=disabled
Podistio.io/rev=canarysidecar.istio.io/inject=”false”

If the istio-injection label and the istio.io/rev label are both present on the same namespace, the istio-injection label will take precedence.

The injector is configured with the following logic:

  1. If either label is disabled, the pod is not injected
  2. If either label is enabled, the pod is injected
  3. If neither label is set, the pod is injected if .values.sidecarInjectorWebhook.enableNamespacesByDefault is enabled. This is not enabled by default, so generally this means the pod is not injected.

Manual sidecar injection

To manually inject a deployment, use istioctl kube-inject:

Zip

  1. $ istioctl kube-inject -f @samples/sleep/sleep.yaml@ | kubectl apply -f -
  2. serviceaccount/sleep created
  3. service/sleep created
  4. deployment.apps/sleep created

By default, this will use the in-cluster configuration. Alternatively, injection can be done using local copies of the configuration.

  1. $ kubectl -n istio-system get configmap istio-sidecar-injector -o=jsonpath='{.data.config}' > inject-config.yaml
  2. $ kubectl -n istio-system get configmap istio-sidecar-injector -o=jsonpath='{.data.values}' > inject-values.yaml
  3. $ kubectl -n istio-system get configmap istio -o=jsonpath='{.data.mesh}' > mesh-config.yaml

Run kube-inject over the input file and deploy.

Zip

  1. $ istioctl kube-inject \
  2. --injectConfigFile inject-config.yaml \
  3. --meshConfigFile mesh-config.yaml \
  4. --valuesFile inject-values.yaml \
  5. --filename @samples/sleep/sleep.yaml@ \
  6. | kubectl apply -f -
  7. serviceaccount/sleep created
  8. service/sleep created
  9. deployment.apps/sleep created

Verify that the sidecar has been injected into the sleep pod with 2/2 under the READY column.

  1. $ kubectl get pod -l app=sleep
  2. NAME READY STATUS RESTARTS AGE
  3. sleep-64c6f57bc8-f5n4x 2/2 Running 0 24s

Customizing injection

Generally, pod are injected based on the sidecar injection template, configured in the istio-sidecar-injector configmap. Per-pod configuration is available to override these options on individual pods. This is done by adding an istio-proxy container to your pod. The sidecar injection will treat any configuration defined here as an override to the default injection template.

Care should be taken when customizing these settings, as this allows complete customization of the resulting Pod, including making changes that cause the sidecar container to not function properly.

For example, the following configuration customizes a variety of settings, including lowering the CPU requests, adding a volume mount, and adding a preStop hook:

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: example
  5. spec:
  6. containers:
  7. - name: hello
  8. image: alpine
  9. - name: istio-proxy
  10. image: auto
  11. resources:
  12. requests:
  13. cpu: "100m"
  14. volumeMounts:
  15. - mountPath: /etc/certs
  16. name: certs
  17. lifecycle:
  18. preStop:
  19. exec:
  20. command: ["sleep", "10"]
  21. volumes:
  22. - name: certs
  23. secret:
  24. secretName: istio-certs

In general, any field in a pod can be set. However, care must be taken for certain fields:

  • Kubernetes requires the image field to be set before the injection has run. While you can set a specific image to override the default one, it is recommended to set the image to auto which will cause the sidecar injector to automatically select the image to use.
  • Some fields in Pod are dependent on related settings. For example, CPU request must be less than CPU limit. If both fields are not configured together, the pod may fail to start.

Additionally, certain fields are configurable by annotations on the pod, although it is recommended to use the above approach to customizing settings. Additional care must be taken for certain annotations:

  • If sidecar.istio.io/proxyCPU is set, make sure to explicitly set sidecar.istio.io/proxyCPULimit. Otherwise the sidecar’s cpu limit will be set as unlimited.
  • If sidecar.istio.io/proxyMemory is set, make sure to explicitly set sidecar.istio.io/proxyMemoryLimit. Otherwise the sidecar’s memory limit will be set as unlimited.

For example, see the below incomplete resources annotation configuration and the corresponding injected resource settings:

  1. spec:
  2. template:
  3. metadata:
  4. annotations:
  5. sidecar.istio.io/proxyCPU: "200m"
  6. sidecar.istio.io/proxyMemoryLimit: "5Gi"
  1. spec:
  2. containers:
  3. - name: istio-proxy
  4. resources:
  5. limits:
  6. memory: 5Gi
  7. requests:
  8. cpu: 200m
  9. memory: 5Gi
  10. securityContext:
  11. allowPrivilegeEscalation: false

Custom templates (experimental)

This feature is experimental and subject to change, or removal, at any time.

Completely custom templates can also be defined at installation time. For example, to define a custom template that injects the GREETING environment variable into the istio-proxy container:

  1. apiVersion: install.istio.io/v1alpha1
  2. kind: IstioOperator
  3. metadata:
  4. name: istio
  5. spec:
  6. values:
  7. sidecarInjectorWebhook:
  8. templates:
  9. custom: |
  10. spec:
  11. containers:
  12. - name: istio-proxy
  13. env:
  14. - name: GREETING
  15. value: hello-world

Pods will, by default, use the sidecar injection template, which is automatically created. This can be overridden by the inject.istio.io/templates annotation. For example, to apply the default template and our customization, you can set inject.istio.io/templates=sidecar,custom.

In addition to the sidecar, a gateway template is provided by default to support proxy injection into Gateway deployments.