注入envoy-sidecar容器启动网络不通
问题:容器注入envoy sidercar后,服务启动偶发无法访问数据库报错connect refused ;偶发无法进行域名解析;

排查过程:
1、容器启动后手动进入容器访问数据库和进行域名解析没问题
2、回滚到不注入envoy sidercar ,无此问题
3、容器进行启动抓包
#rm -rf /data/log/promtheus-phone-alert/1.pcap #nohup tcpdump -i any -w /data/log/promtheus-phone-alert/1.pcap & #fping -c1 badiu.com #fping -c1 mirrors.ucloud.cn #pkill tcpdump #sleep 10000000 |

我们发现每次dns解析完,都会发送一个syn的tcp包给 本地127.0.0.1的15001端口要建立连接,并且连接被RST导致域名无法解析成功(联想到可能和envoy和流量重定向有关系)
为啥会发送一个syn 的TCP包给dns服务呢?最后说
经过我们验证容器名称空间的iptables规则:

DNS解析的udp流量是被直通容器,但是TCP的流量会被转发到15001端口统一处理。
4、我们把53的TCP流量直接放行,不redirect 到15001处理
查询后找到以下参数加入到pod annotation: traffic.sidecar.istio.io/excludeOutboundPorts: "53"
pod注入后的yaml init-container参数生效,查看日志域名解析没有问题


查看抓包数据:udp 解析完一次后 又使用tcp协议解析一次 才成功获取ip 然后发出的 ping请求

到这里我们能定位到是跟重定向15001端口有关系,可能是istio-proxy容器没有启动完成15001端口没有开通,业务容器就进行网络访问被重定向到15001产生的问题
5、业务容器启动后进行探测15001端口
nc -vz 127.0.0.1 15001
到这里可以定位到业务容器启动后 envoy sidecar还没有启动,TCP流量转发到15001 导致网络不通

6、保证容器顺序启动,先启动istio-proxy 再启动业务容器
istio官方给出了解决方案 使用k8s lifecyle 的poststart 功能pilot-agent的wait函数等待 envoy启动后再进行业务容器的启动
(k8s本身创建容器是有顺序的,创建完第一个再创建完第二个,但是创建完并不代表istio-proxy的15001端口起来了,仅仅是容器创建成功没有ready,
使用lifecycle可以延迟容器的创建完成时间,可以认为是poststart没有执行完这个容器就没创建完成)
lifecycle:
postStart:
exec:
command:
- pilot-agent
- wait
|
pilot wait 源码https://juejin.cn/post/6883322930361532430
istio官方文档:
https://istio.io/latest/docs/ops/common-problems/injection/

经验证业务容器启动后访问15001端口没问题

最后来看下为什么会发送udp协议的dns解析并且收到dns-server的响应后,又发送TCP协议的解析?
udp 报文有512字节限制收到dns-server的响应的报文被截断导致udp dns解析失败,使用TCP协议继续解析。
查看我们抓包数据的响应包确实被截断了

参考:

浙公网安备 33010602011771号