更新时间:2024-03-15 GMT+08:00

Sidecar未就绪导致Pod启动失败

问题背景

加入网格的服务有时可能遇到Pod启动失败,且一直重启。排查原因发现业务容器与外部通信时流量会经过istio-proxy容器,但业务容器比istio-proxy容器先启动,在istio-proxy容器没启动成功时,业务容器已经启动,与外部通信将会失败,Pod一直重启。

规避方案

在Istio 1.7及以后版本,社区通过给istio-injector注入逻辑增加一个叫HoldApplicationUntilProxyStarts的开关来解决了该问题,开关打开后,Proxy将会注入到第一个Container,istio-proxy容器先于业务容器启动。

开关配置分为全局和局部两种,下面介绍两种启用方法。

需要注意的是,打开开关后,意味着业务容器需要等Sidecar完全Ready后才能启动,会让Pod启动速度变慢一些。在需要快速扩容应对突发流量场景可能会显得吃力,所以建议您自行评估业务场景,利用局部配置的方法,只给需要的业务打开此开关。

  • 全局配置
    1. 执行以下命令,编辑IOP CR资源。

      kubectl edit iop private-data-plane -n istio-system

      在spec.values.global.proxy字段下添加以下配置:

      holdApplicationUntilProxyStarts: true

    2. 执行以下命令,确认最新日志无报错。

      kubectl logs -n istio-operator $(kubectl get po -n istio-operator | awk '{print $1}' | grep -v NAME)

    3. 执行以下命令,确认IOP CR是正常状态。

      kubectl get iop -n istio-system

    4. 执行以下命令,滚动升级已添加到网格的服务。

      kubectl rollout restart deployment nginx -n default

      其中,nginx为示例服务,default为命名空间,请替换为实际取值。

    5. 执行以下命令,确认Pod重启成功。

      kubectl get pod -n default | grep nginx

    6. 执行以下命令,确认Pod正常添加了postStart lifecycle,并且istio-proxy容器放在了第一个位置。

      kubectl edit pod nginx-7bc96f87b9-l4dbl

  • 局部配置

    如果使用Istio 1.8及其以上的版本,可以为需要打开此开关的Pod加上proxy.istio.io/config注解,将holdApplicationUntilProxyStarts置为true。

    以default命名空间下nginx服务为例,用户其他服务操作类似。

    kubectl edit deploy nginx -n default

    在spec.template.metadata.annotations字段下添加以下配置:

    proxy.istio.io/config: |
      holdApplicationUntilProxyStarts: true