• Sidecar 注入 Webhook
    • 注入的结果和预期不一致
    • Pod 完全不能创建
      • x509 证书相关的错误
      • 部署状态中出现 no such hosts 或 no endpoints available 错误

    Sidecar 注入 Webhook

    自动 sidecar 注入可将 sidecar 代理添加到用户创建的 pod 中。在创建时,它使用 MutatingWebhook 将 sidecar 容器和卷附加到每个 pod 的模板规范中。可以使用 webhook namespaceSelector 机制将注入范围限定为特定的命名空间或使用注解为每个 pod 启用和禁用注入。

    是否进行 sidecar 注入取决于以下三个条件:

    • webhook 的 namespaceSelector

    • 默认策略

    • 每个 pod 的可覆盖注解

    下面的表格展示了基于三个条件变量的最终的注入状态。

    namespaceSelector 匹配默认策略Pod 覆盖注解sidecar.istio.io/injectSidecar 是否注入?
    yesenabledtrueyes
    yesenabledfalseno
    yesenabledyes
    yesdisabledtrueyes
    yesdisabledfalseno
    yesdisabledno
    noenabledtrueno
    noenabledfalseno
    noenabledno
    nodisabledtrueno
    nodisabledfalseno
    nodisabledno

    注入的结果和预期不一致

    不一致包括 sidecar 的非预期注入和未预期注入。

    • 通过检查 webhook 的 namespaceSelector 以确定目标命名空间是否包含或者排除在 webhook 范围内。

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

    1. $ kubectl get mutatingwebhookconfiguration istio-sidecar-injector -o yaml | grep "namespaceSelector:" -A5
    2. namespaceSelector:
    3. matchLabels:
    4. istio-injection: enabled
    5. rules:
    6. - apiGroups:
    7. - ""

    在标记 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. - disabled
    8. rules:
    9. - apiGroups:
    10. - ""

    在没有标记 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-public Active 18d disabled
    6. kube-system Active 18d disabled

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

    1. $ kubectl label namespace istio-system istio-injection=disabled --overwrite

    (重复 pod 创建时调用注入 webhook 的所有命名空间)

    1. $ kubectl label namespace default istio-injection=enabled --overwrite
    • 检查默认 policy

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

    1. $ kubectl -n istio-system get configmap istio-sidecar-injector -o jsonpath='{.data.config}' | head
    2. policy: enabled
    3. template: |-
    4. initContainers:
    5. - name: istio-init
    6. image: "docker.io/jasonayoung/proxy_init:d49fa0a7f7d17f25552ad749d23f8ac73596e0cc"
    7. args:
    8. - "-p"
    9. - [[ .MeshConfig.ProxyListenPort ]]
    10. - "-u"
    11. - 1337

    策略允许的值为 disabledenabled。仅当 webhook 的 namespaceSelector 与目标命名空间匹配时,默认策略才会被应用。无法识别的策略值默认为 disabled

    • 检查每个 pod 覆盖注解

    可以使用 pod 模板规范的元数据中的注解 sidecar.istio.io/inject 来覆盖默认策略。部署时 metadata 将被忽略。注释值为 true 会被强制注入 sidecar,为 false 则会强制不注入 sidecar。

    以下注解会覆盖默认策略并强制注入 sidecar:

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

    Pod 完全不能创建

    在失败的 pod 的部署上运行 kubectl describe -n namespace deployment name。通常能在事件日志中获取到调用注入 webhook 失败原因。

    x509 证书相关的错误

    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. x509: certificate signed by unknown authority (possibly because of "crypto/rsa: verification error" while trying \
    4. 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 secret istio.istio-sidecar-injector-service-account -o jsonpath='{.data.root-cert\.pem}' | md5sum
    4. 4b95d2ba22ce8971c7c92084da31faf0 -

    CA 证书必须匹配。如不匹配,则可重新启动 sidecar 注入 pod。

    1. $ kubectl -n istio-system patch deployment istio-sidecar-injector \
    2. -p "{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"date\":\"`date +'%s'`\"}}}}}"
    3. deployment.extensions "istio-sidecar-injector" patched

    部署状态中出现 no such hosts 或 no endpoints available 错误

    注入是失效关闭的(fail-close)。如果 istio-sidecar-injector pod 尚未准备就绪,则无法创建 pod。在这种情况下,则会出现以下错误 no such host (Kubernetes 1.9) 或 no endpoints available (>=1.10)。

    Kubernetes 1.9:

    1. Internal error occurred: failed calling admission webhook "istio-sidecar-injector.istio.io": \
    2. Post https://istio-sidecar-injector.istio-system.svc:443/admitPilot: dial tcp: lookup \
    3. istio-sidecar-injector.istio-system.svc on 169.254.169.254:53: no such host

    Kubernetes 1.10:

    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:10514,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