Istio Operator - Sidecar injection via Pod annotations
Sat Aug 01, 2020 · 464 words
kubernetesistio

You want to use the automatic sidecar injection in Istio to add Envoy proxies to workloads. Like me, you do not want to enable for it all workloads in a namespace. You would rather opt for a safer, more cautious approach of enabling it on a per pod basis.

You’ve installed the Istio control plane into your Kubernetes cluster using the Istio Operator. You’ve enabled the automatic sidecar injection in the operator CRD:

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  autoInjection:
    components:
      injector:
        enabled: true

Following the documentation, you might try and just add the annotation to pods to enable injection:

sidecar.istio.io/inject: “true”

This won’t work. You kill the existing pod but the new one does not have a sidecar injected. This is because the webhook will only target resources being applied to namespaces containing the label:

istio-injection=enabled

It is scoped to these namespaces. Herein lies the problem. If you apply this label everything in the namespace will have an Envoy proxy injected by default.

If we were not using the operator we could just change a value in the istio-sidecar-injector ConfigMap, setting policy to disabled:

apiVersion: v1
kind: ConfigMap
metadata:
  name: istio-sidecar-injector
data:
  config: |-
    policy: disabled

This would mean that the mutating webhook admission controller would listen for pod creation events happening in the labelled namespace as normal, but it would not inject a proxy by default. We can see the namespace selector with the following example from the Istio documentation:

$ kubectl get mutatingwebhookconfiguration istio-sidecar-injector -o yaml | grep "namespaceSelector:" -A5
  namespaceSelector:
    matchLabels:
      istio-injection: enabled
  rules:
  - apiGroups:
    - ""

So we need to figure out what setting in the Istio operator CRD maps directly to this policy field in the istio-sidecar-injector ConfigMap.

The operator has it’s own custom CRD that ends up getting converted into Helm values files. So if we look at the Helm chart we can figure out what we need to set in the operator.

config: |-
    policy: {{ .Values.global.proxy.autoInject }}

If we can take this and look at the API for the operator we can see how to convert this Helm value field into the operators CRD setting:

values:
  global:
    proxy:
      autoInject: disabled

So if we set this and re-apply the IstioOperator CRD we can use kubectl to confirm that the istio-sidecar-injector ConfigMap has been updated to set policy to disabled:

kubectl -n istio-system get configmap istio-sidecar-injector -o jsonpath='{.data.config}' | grep policy:

Now we can label our namespaces with the istio-injection label and not have all newly created pods injected with an Envoy proxy. This allows us to control the roll out by adding the inject annotation to pods:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: ignored
spec:
  template:
    metadata:
      annotations:
        sidecar.istio.io/inject: "true"

We are now able to roll out Istio to our applications in a more controlled manner.


back · about · writing · contact · home