应用容器接入istio的sidecar启动出现无法访问网络

故障现象:
该问题的表现是接入了sidecar proxy的应用在启动过程中发现一小段时间内,无法通过网络访问 pod 外部的其他服务,例如外部的 Erueke,MySQL等服务,通过服务的重试功能过段时间应用又正常启动了。
日志:
ERROR [] RedirectingEurekaHttpClient.execute:83 Request execution errorcom.sun.jersey.api.client.ClientHandlerException: java.net.UnknownHostException: eurekasit.app.com: Name or service not known

故障原因:
如下图所示,Envoy 启动后会通过 xDS 协议向 Pilot 请求服务和路由配置信息,Pilot 收到请求后会根据 Envoy 所在的节点(Pod 或者 VM)组装配置信息,包括 Listener、Route、Cluster 等,然后再通过 xDS 协议下发给 Envoy。根据 Mesh 的规模和网络情况,该配置下发过程需要数秒到数十秒的时间。在这段时间内,由于初始化容器已经在 Pod 中创建了 Iptables rule 规则,因此应用向外发送的网络流量会被重定向到 Envoy ,而此时 Envoy 中尚没有对这些网络请求进行处理的监听器和路由规则,无法对此进行处理,导致网络请求失败。

解决方法:
Sidecar 初始化完成后再启动应用程序

配置方法 - Istio 1.7 及之后版本
Istio 1.7 及之后的版本中,可以通过下面的方法配置在 Sidecar 初始化完成后再启动应用容器。

全局配置:
在 istio-system/istio ConfigMap 中将 holdApplicationUntilProxyStarts 这个全局配置项设置为 true

kubectl edit cm istio -n istio-system

apiVersion: v1
data:
  mesh: |-
    defaultConfig:
      holdApplicationUntilProxyStarts: true

局部配置:
按 Deployment 配置,如果不希望该配置全局生效,则可以通过下面的 annotation 在 Deployment 级别进行配置。

kubect edit deploy test -n docker-demo

  template:
    metadata:
      annotations:
        proxy.istio.io/config: '{ "holdApplicationUntilProxyStarts": true }'

 

实现原理:在开启 holdApplicationUntilProxyStarts 选项后,Istio Sidecar Injector Webhook 会在 Pod 中插入下面的 yaml 片段。该 yaml 片段在 Sidecar proxy 的 postStart 生命周期时间中执行了 pilot-agent wait 命令。该命令会检测 Proxy 的状态,待 Proxy 初始化完成后再启动 Pod 中的下一个容器。这样,在应用容器启动时,Sidecar proxy 已经完成了配置初始化,可以正确代理应用容器的对外网络请求。

 ##  https://www.cnblogs.com/liucx/

参考:

https://www.cnblogs.com/tencent-cloud-native/p/13644195.html

Istio流量管理实现机制深度解析 (https://zhaohuabing.com/post/2018-09-25-istio-traffic-management-impl-intro/)

posted @ 2022-04-02 14:56  liucx  阅读(123)  评论(0编辑  收藏  举报