Sidecar Injection Webhook
Automatic sidecar injection adds the sidecar proxy into user-created
pods. It uses a MutatingWebhook to append the sidecar’s containers
and volumes to each pod’s template spec during creation
time. Injection can be scoped to particular sets of namespaces using
the webhooks namespaceSelector mechanism. Injection can also be
enabled and disabled per-pod with an annotation.
Whether or not a sidecar is injected depends on three pieces of configuration and two security rules:
Configuration:
- webhooks
namespaceSelector - default
policy - per-pod override annotation
Security rules:
- sidecars cannot be injected in the
kube-systemorkube-publicnamespaces - sidecars cannot be injected into pods that use the host network
The following truth table shows the final injection status based on the three configuration items. The security rules above cannot be overridden.
namespaceSelector match | default policy | Pod override annotation sidecar.istio.io/inject | Sidecar injected? |
|---|---|---|---|
| yes | enabled | true | yes |
| yes | enabled | false | no |
| yes | enabled | yes | |
| yes | disabled | true | yes |
| yes | disabled | false | no |
| yes | disabled | no | |
| no | enabled | true | no |
| no | enabled | false | no |
| no | enabled | no | |
| no | disabled | true | no |
| no | disabled | false | no |
| no | disabled | no |
The result of sidecar injection was not what I expected
This includes an injected sidecar when it wasn’t expected and a lack of injected sidecar when it was.
Ensure your pod is not in the
kube-systemorkube-publicnamespace. Automatic sidecar injection will be ignored for pods in these namespaces.Ensure your pod does not have
hostNetwork: truein its pod spec. Automatic sidecar injection will be ignored for pods that are on the host network.The sidecar model assumes that the iptables changes required for Envoy to intercept traffic are within the pod. For pods on the host network this assumption is violated, and this can lead to routing failures at the host level.
Check the webhook’s
namespaceSelectorto determine whether the webhook is scoped to opt-in or opt-out for the target namespace.The
namespaceSelectorfor opt-in will look like the following:$ kubectl get mutatingwebhookconfiguration istio-sidecar-injector -o yaml | grep "namespaceSelector:" -A5 namespaceSelector: matchLabels: istio-injection: enabled rules: - apiGroups: - ""The injection webhook will be invoked for pods created in namespaces with the
istio-injection=enabledlabel.$ kubectl get namespace -L istio-injection NAME STATUS AGE ISTIO-INJECTION default Active 18d enabled istio-system Active 3d kube-public Active 18d kube-system Active 18dThe
namespaceSelectorfor opt-out will look like the following:$ kubectl get mutatingwebhookconfiguration istio-sidecar-injector -o yaml | grep "namespaceSelector:" -A5 namespaceSelector: matchExpressions: - key: istio-injection operator: NotIn values: - disabled rules: - apiGroups: - ""The injection webhook will be invoked for pods created in namespaces without the
istio-injection=disabledlabel.$ kubectl get namespace -L istio-injection NAME STATUS AGE ISTIO-INJECTION default Active 18d istio-system Active 3d disabled kube-public Active 18d disabled kube-system Active 18d disabledVerify the application pod’s namespace is labeled properly and (re) label accordingly, e.g.
$ kubectl label namespace istio-system istio-injection=disabled --overwrite(repeat for all namespaces in which the injection webhook should be invoked for new pods)
$ kubectl label namespace default istio-injection=enabled --overwriteCheck default policy
Check the default injection policy in the
istio-sidecar-injectorconfigmap.$ kubectl -n istio-system get configmap istio-sidecar-injector -o jsonpath='{.data.config}' | grep policy: policy: enabledAllowed policy values are
disabledandenabled. The default policy only applies if the webhook’snamespaceSelectormatches the target namespace. Unrecognized policy values default todisabled.Check the per-pod override annotation
The default policy can be overridden with the
sidecar.istio.io/injectannotation in the pod template spec’s metadata. The deployment’s metadata is ignored. Annotation value oftrueforces the sidecar to be injected while a value offalseforces the sidecar to not be injected.The following annotation overrides whatever the default
policywas to force the sidecar to be injected:$ kubectl get deployment sleep -o yaml | grep "sidecar.istio.io/inject:" -C3 template: metadata: annotations: sidecar.istio.io/inject: "true" labels: app: sleep
Pods cannot be created at all
Run kubectl describe -n namespace deployment name on the failing
pod’s deployment. Failure to invoke the injection webhook will
typically be captured in the event log.
x509 certificate related errors
Warning FailedCreate 3m (x17 over 8m) replicaset-controller Error creating: Internal error occurred: \
failed calling admission webhook "sidecar-injector.istio.io": Post https://istio-sidecar-injector.istio-system.svc:443/inject: \
x509: certificate signed by unknown authority (possibly because of "crypto/rsa: verification error" while trying \
to verify candidate authority certificate "Kubernetes.cluster.local")
x509: certificate signed by unknown authority errors are typically
caused by an empty caBundle in the webhook configuration.
Verify the caBundle in the mutatingwebhookconfiguration matches the
root certificate mounted in the istio-sidecar-injector pod.
$ kubectl get mutatingwebhookconfiguration istio-sidecar-injector -o yaml -o jsonpath='{.webhooks[0].clientConfig.caBundle}' | md5sum
4b95d2ba22ce8971c7c92084da31faf0 -
$ kubectl -n istio-system get secret istio.istio-sidecar-injector-service-account -o jsonpath='{.data.root-cert\.pem}' | md5sum
4b95d2ba22ce8971c7c92084da31faf0 -
The CA certificate should match. If they do not, restart the sidecar-injector pods.
$ kubectl -n istio-system patch deployment istio-sidecar-injector \
-p "{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"date\":\"`date +'%s'`\"}}}}}"
deployment.extensions "istio-sidecar-injector" patched
no such hosts or no endpoints available errors in deployment status
Injection is fail-close. If the istio-sidecar-injector pod is not ready, pods
cannot be created. In such cases you’ll see an error about no endpoints available.
Internal error occurred: failed calling admission webhook "istio-sidecar-injector.istio.io": \
Post https://istio-sidecar-injector.istio-system.svc:443/admitPilot?timeout=30s: \
no endpoints available for service "istio-sidecar-injector"
$ kubectl -n istio-system get pod -listio=sidecar-injector
NAME READY STATUS RESTARTS AGE
istio-sidecar-injector-5dbbbdb746-d676g 1/1 Running 0 2d
$ kubectl -n istio-system get endpoints istio-sidecar-injector
NAME ENDPOINTS AGE
istio-sidecar-injector 10.48.6.108:10514,10.48.6.108:443 3d
If the pods or endpoints aren’t ready, check the pod logs and status for any indication about why the webhook pod is failing to start and serve traffic.
$ for pod in $(kubectl -n istio-system get pod -listio=sidecar-injector -o jsonpath='{.items[*].metadata.name}'); do \
kubectl -n istio-system logs ${pod} \
done
$ for pod in $(kubectl -n istio-system get pod -listio=sidecar-injector -o name); do \
kubectl -n istio-system describe ${pod} \
done