Sidecar 自动注入问题

    1. 确保您的 Pod 不在 kube-systemkube-public 名称空间中。 这些命名空间中的 Pod 将忽略 Sidecar 自动注入。

    2. 确保您的 Pod 在其 Pod 定义中没有 hostNetwork:truehostNetwork:true 的 Pod 将忽略 Sidecar 自动注入。

      Sidecar 模型假定 iptables 会拦截所有 Pod 中的流量给 Envoy,但是 hostNetwork:true 的 Pod 不符合此假设,并且会导致主机级别的路由失败。

    3. 通过检查 webhook 的 namespaceSelector 以确定目标命名空间是否包含在 webhook 范围内。

      包含在范围内的 namespaceSelector 如下所示:

      在有 istio-injection=enabled 标签的命名空间中创建 Pod 就会调用注入 webhook。

      1. $ kubectl get namespace -L istio-injection
      2. NAME STATUS AGE ISTIO-INJECTION
      3. default Active 18d enabled
      4. istio-system Active 3d
      5. kube-public Active 18d
      6. kube-system Active 18d

      不包含在注入范围的 namespaceSelector 如下所示:

      1. $ kubectl get mutatingwebhookconfiguration istio-sidecar-injector -o yaml | grep "namespaceSelector:" -A5
      2. namespaceSelector:
      3. matchExpressions:
      4. - key: istio-injection
      5. operator: NotIn
      6. values:
      7. rules:
      8. - apiGroups:
      9. - ""

      在没有标记 istio-injection=disabled 标签的命名空间中创建 Pod,注入 webhook 就会被调用。

      1. $ kubectl get namespace -L istio-injection
      2. NAME STATUS AGE ISTIO-INJECTION
      3. default Active 18d
      4. istio-system Active 3d disabled
      5. kube-system Active 18d disabled

      验证应用程序 Pod 的命名空间是否已相应地被正确(重新)标记,例如:

      1. $ kubectl label namespace istio-system istio-injection=disabled --overwrite
    4. 检查默认策略

      istio-sidecar-injector configmap 中检查默认注入策略。

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

      策略允许的值为 disabled 或者 enabled。仅当 webhook 的 namespaceSelector 与目标命名空间匹配时,默认策略才会生效。无法识别的策略值默认为 disabled

    5. 检查每个 Pod 的标签

      可以使用 pod template spec metadata 中的标签 sidecar.istio.io/inject 来覆盖默认策略,如果这样的话,Deployment 相应的 metadata 将被忽略。标签值为 true 会被强制注入 Sidecar,为 false 则会强制不注入 Sidecar。

      以下标签会覆盖默认策略并强制注入 Sidecar:

      1. $ kubectl get deployment sleep -o yaml | grep "sidecar.istio.io/inject:" -B4
      2. template:
      3. metadata:
      4. labels:
      5. app: sleep
      6. sidecar.istio.io/inject: "true"

    在失败的 Pod 的 Deployment 上运行 kubectl describe -n namespace deployment name。通常能在事件中看到调用注入 webhook 失败的原因。

    1. Warning FailedCreate 3m (x17 over 8m) replicaset-controller Error creating: Internal error occurred: \
    2. failed calling admission webhook "sidecar-injector.istio.io": Post https://istio-sidecar-injector.istio-system.svc:443/inject: \
    3. to verify candidate authority certificate "Kubernetes.cluster.local")

    x509: certificate signed by unknown authority 错误通常由 webhook 配置中的空 caBundle 引起。

    验证 mutatingwebhookconfiguration 配置中的 caBundle 是否与 istio-sidecar-injector 中 pod 安装的根证书匹配。

    1. $ kubectl get mutatingwebhookconfiguration istio-sidecar-injector -o yaml -o jsonpath='{.webhooks[0].clientConfig.caBundle}' | md5sum
    2. 4b95d2ba22ce8971c7c92084da31faf0 -
    3. $ kubectl -n istio-system get configmap istio-ca-root-cert -o jsonpath='{.data.root-cert\.pem}' | base64 -w 0 | md5sum
    4. 4b95d2ba22ce8971c7c92084da31faf0 -

    Deployment 状态中出现 或 no endpoints available

    注入是失效关闭的(fail-close)。如果 istio-sidecar-injector Pod 尚未准备就绪,则无法创建 Pod。在这种情况下,则会出现 no endpoints available

    1. Internal error occurred: failed calling admission webhook "istio-sidecar-injector.istio.io": \
    2. Post https://istio-sidecar-injector.istio-system.svc:443/admitPilot?timeout=30s: \
    3. no endpoints available for service "istio-sidecar-injector"
    1. $ kubectl -n istio-system get pod -listio=sidecar-injector
    2. NAME READY STATUS RESTARTS AGE
    3. istio-sidecar-injector-5dbbbdb746-d676g 1/1 Running 0 2d
    1. $ kubectl -n istio-system get endpoints istio-sidecar-injector
    2. NAME ENDPOINTS AGE
    3. istio-sidecar-injector 10.48.6.108:15014,10.48.6.108:443 3d

    如果 Pod 或 endpoint 尚未准备就绪,可以通过检查 Pod 日志和状态查找有关 Webhook Pod 无法启动的原因。

    1. $ for pod in $(kubectl -n istio-system get pod -listio=sidecar-injector -o jsonpath='{.items[*].metadata.name}'); do \
    2. kubectl -n istio-system logs ${pod} \
    3. done
    4. $ for pod in $(kubectl -n istio-system get pod -listio=sidecar-injector -o name); do \
    5. kubectl -n istio-system describe ${pod} \
    6. done

    当 Kubernetes API server 包含诸如以下的代理设置时:

    使用这些设置,Sidecar 自动注入就会失败。相关的报错可以在 kube-apiserver 日志中找到:

    1. W0227 21:51:03.156818 1 admission.go:257] Failed calling webhook, failing open sidecar-injector.istio.io: failed calling admission webhook "sidecar-injector.istio.io": Post https://istio-sidecar-injector.istio-system.svc:443/inject: Service Unavailable

    根据 *_proxy 相关的的环境变量设置,确保 Pod 和 service CIDR 是没有被代理的。检查 kube-apiserver 的运行日志验证是否有请求正在被代理。

    一种解决方法是在 kube-apiserver 的配置中删除代理设置,另一种解决方法是把 istio-sidecar-injector.istio-system.svc 或者 .svc 加到 no_proxyvalue 里面。每种解决方法都需要重新启动 kube-apiserver

    Kubernetes 与此有关的一个 已被 PR #58698 解决。

    tcpdump 在 Sidecar 中不能工作 - 因为该容器不以 root 身份运行。但是由于同一 Pod 内容器的网络命名空间是共享的,因此 Pod 中的其他容器也能看到所有数据包。iptables 也能查看到 Pod 级别的相关配置。

    Envoy 和应用程序之间的通信是通过 127.0.0.1 进行的,这个通讯过程未加密。