加入收藏 | 设为首页 | 会员中心 | 我要投稿 惠州站长网 (https://www.0752zz.com.cn/)- 办公协同、云通信、物联设备、操作系统、高性能计算!
当前位置: 首页 > 移动 > 正文

Istio在UAEK中的实践改造之路

发布时间:2018-09-14 23:43:46 所属栏目:移动 来源:陈绥
导读:副标题#e# 9月15日技术沙龙 | 与东华软件、AWS、京东金融、饿了么四位大咖探讨精准运维! 为什么需要ServiceMesh UCloud App Engine on Kubernetes(后简称UAEK)是UCloud内部打造的一个基于Kubernetes的,具备高可用、跨机房容灾、自动伸缩、立体监控、日志

然而,我们发现在IPv6环境下,Envoy无法劫持Pod的流量。通过抓包观察和追溯源码发现,Pod启动的时候,首先会运行一个iptables初始化脚本,完成pod内的nat redirect配置,将容器内的TCP出入流量都劫持到Envoy的监听端口中,但这个初始化脚本没有ip6tables的对应操作并且discard了所有IPv6流量,因此我们修改了初始化脚本,实现了IPv6的流量劫持。

一波刚平,一波又起。完成IPv6流量劫持后, 我们发现所有访问业务服务端口的TCP流量都被Envoy重置,进入Envoy容器中发现15001端口并没有开启。追溯Envoy和Pilot源码发现,Pilot给Envoy下发的listen地址为0:0:0:0:15001, 这是个IPv4地址,我们需要Envoy监听地址的为[::0]:15000,于是继续修改Pilot源码。

经过上述努力,应用服务端程序Pod终于能成功Accept我们发起的TCP连接。但很快,我们的请求连接就被服务端关闭,客户端刚连接上就立刻收到TCP FIN分节,请求依然失败。通过观察Envoy的运行日志,发现Envoy接收了TCP请求后,无法找到对应的4层流量过滤器(Filter)。

深入跟进源码发现,Envoy需要通过getsocketopt(2)系统调用获取被劫持的访问请求的真实目的地址, 但在IPv6环境下Envoy相关的实现存在bug,如下代码所示。由于缺少判定socket fd的类型, getsocketopt(2)传入的参数是IPv4环境下的参数,因此Envoy无法找到请求的真实目的地址,遂报错并立刻关闭了客户端连接。

Istio在UAEK中的实践改造之路

发现问题后,UAEK团队立刻修改Envoy源码,完善了getsocketopt(2) 的SO_ORIGINAL_DST选项的IPv6兼容性,然后将这一修改提交到Envoy开源社区,随后被社区合并到当前的Master分支中,并在Istio1.0的Envoy镜像中得到更新使用。

到此为止,Istio SideCar终于能在UAEK IPv6环境下正常调度服务间的访问流量了。

此外,我们还发现Pilot、Mixer等模块在处理IPv6格式地址时出现数组越界、程序崩溃的情况,并逐一修复之。

性能评估

Istio1.0发布之前,性能问题一直是业界诟病的焦点。我们首先考察了增加了Envoy后,流量多了一层复制,并且请求发起前需要向Mixer Policy进行一次Check请求,这些因素是否会对业务产生不可接收的延迟。经过大量测试,我们发现在UAEK环境下会比不使用Istio时增加5ms左右的延迟,对内部大部分服务来说,这完全可以接受。

随后,我们重点考察了整个Istio Mesh的架构,分析下来结论是,Mixer Policy和Mixer Telemetry很容易成为整个集群的性能短板。由于Envoy发起每个请求前都需要对Policy服务进行Check请求,一方面增加了业务请求本身的延迟,一方面也给作为单点的Policy增大了负载压力。我们以Http1.1请求作为样本测试,发现当整个网格QPS达到2000-3000的时候,Policy就会出现严重的负载瓶颈,导致所有的Check请求耗时显著增大,由正常情况下的2-3ms增大到100-150ms,严重加剧了所有业务请求的耗时延迟,这个结果显然是不可接受的。

更严重的是,在Istio 0.8以及之前的版本,Policy是一个有状态的服务。一些功能,如全局的QPS Ratelimit配额控制,需要Policy单个进程记录整个Mesh的实时数据,这意味着Policy服务无法通过横向扩容实例来解决性能瓶颈。经过取舍权衡,我们目前关闭了Policy服务并裁剪了一些功能,比如QPS全局配额限制。

(编辑:惠州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读