Istio在UAEK中的实践改造之路
2018-09-10 15:57:52UCloud App Engine on Kubernetes(后简称“UAEK”)是UCloud内部打造的一个基于Kubernetes的,具备高可用、跨机房容灾、自动伸缩、立体监控、日志搜集和简便运维等特性计算资源交付平台,旨在利用容器技术提高内部研发运维效率,让开发能将更多的精力投入在业务研发本身。
为什么需要ServiceMesh
UCloud App Engine on Kubernetes(后简称“UAEK”)是UCloud内部打造的一个基于Kubernetes的,具备高可用、跨机房容灾、自动伸缩、立体监控、日志搜集和简便运维等特性计算资源交付平台,旨在利用容器技术提高内部研发运维效率,让开发能将更多的精力投入在业务研发本身,同时,让运维能更从容应对资源伸缩、灰度发布、版本更迭、监控告警等日常工作。
考虑到Kubernetes本来就是为自动部署、伸缩和容器化而生,再加上UCloud UAEK团队完成IPv6组网调研和设计实现后,一个成熟的容器管理平台很快正式在北京二地域的多个可用区上线了。相比于过去申请管理虚拟机部署应用服务,Kubernetes确实带来了实实在在的便利,例如方便灵活的自动伸缩以及触手可及的微服务架构,只需简单配置即可实现跨可用区容灾等。
然而,微服务化又为系统架构带来许多新的问题,例如服务发现、监控、灰度控制、过载保护、请求调用追踪等。大家已经习惯自行运维一组Zookeeper集群用以实现服务发现和客户端负载均衡,使用UAEK后能否免去运维Zookeeper的工作?为了监控业务运行状态,大家都需要在代码里加上旁路上报逻辑,使用UAEK是否能无侵入零耦合地实现监控上报?
此外,过去很多系统模块间调用缺少熔断保护策略,波峰流量一打就瘫,使用UAEK是否能帮助业务方免去大规模改造呢?过去排查问题,尤其是调用耗时环节排查总是费时费力,使用UAEK能否为定位瓶颈提供方便的工具?
显然,仅凭一个稳定的Kubernetes平台不足以解决这些问题。因此,在UAEK立项之初,团队就把ServiceMesh作为一个必须实现的目标,任何在UAEK上部署的TCP后台服务,都能享受到ServiceMesh带来的这些特性:
为什么是Istio?
关于ServiceMesh的实现,我们重点考察了Istio。通过前期的调研和测试,我们发现Istio的几个特性能很好满足UAEK的需求:
整个服务网格分成控制面板和数据面两大部分。数据面指的就是注入到应用Pod中的Envoy容器,它负责代理调度模块间的所有流量。控制面分为Pilot,Mixer和Citadel三大模块,具体功能如下:
Istio整体工作的原理和流程细节非常复杂,所涉及到的技术栈有一定的深度和广度。这里只概括一下大体过程:
Istio在UAEK环境下的改造之路
经过上述的调研和与一系列测试,UAEK团队充分认可Istio的设计理念和潜在价值,希望通过利用Istio丰富强大的微服务治理功能吸引更多的内部团队将服务迁移到UAEK环境中。
然而,事实上,在UAEK上接入Istio的过程并非一帆风顺。最早开始调研Istio的时候,Istio还在0.6版本,功能并不完善,在UAEK环境中无法开箱即用。
IPv6问题的解决
我们首先碰到的问题是,UAEK是一个纯IPv6网络环境,而Istio对IPv6流量的支持并不完备,部分组件甚至无法在IPv6环境下部署。
在介绍具体改造案例之前,先了解下Istio Sidecar是如何接管业务程序的流量。
如上图所描述,Istio会向应用Pod注入两个容器:proxy-init容器和envoy容器。proxy-init容器通过初始化iptables设置,将所有的TCP层流量通过nat redirect重定向到Envoy监听的15001端口。以入流量为例,Envoy的服务端口接收到被重定向到来的TCP连接后,通过getsocketopt(2)系统调用,使用SO_ORIGINAL_DST参数找到该TCP连接的真实目的地IP地址,并将该请求转发到真实目的IP。
然而,我们发现在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无法找到请求的真实目的地址,遂报错并立刻关闭了客户端连接。
发现问题后,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全局配额限制。
前面提到过,Mixer Telemetry主要负责向Envoy收集每次请求的调用情况。0.8版本的Mixer Telemetry也存在严重的性能问题。压测中发现,当集群QPS达到2000以上时,Telemetry实例的内存使用率会一路狂涨。
经过分析定位,发现Telemetry内存上涨的原因是数据通过各种后端Adapter消费的速率无法跟上Envoy上报的速率, 导致未被Adapter处理的数据快速积压在内存中。我们随即去除了Istio自带的并不实用的stdio日志搜集功能,这一问题随即得到极大缓解。幸运的是,随着Istio1.0的发布,Telemetry的内存数据积压问题得到解决,在相同的测试条件下,单个Telemetry实例至少能胜任3.5W QPS情况下的数据搜集上报。
问题、希望与未来
历经重重问题,一路走来,一个生产环境可用的ServiceMesh终于在UAEK环境上线了。在这一过程中,也有部门内其他团队受UAEK团队影响,开始学习Istio的理念并尝试在项目中使用Istio。然而,目前的现状离我们的初心依然存在差距。
Istio依然在高速迭代中,无论是Istio本身还是Envoy Proxy,每天都在演进更新。每一次版本更新,带来的都是更为强大的功能,更为简练的API定义,同时也带来了更复杂的部署架构。从0.7.1到0.8,全新的路由规则v1alpha3与之前的API完全不兼容,新的Virtualservice与原先的routerule截然不同,给每位使用者构成了不少麻烦。
如何完全避免升级Istio给现网带来负影响,官方依然没有给出***平滑的升级方案。此外,从0.8到1.0虽然各个组件的性能表现有显著提升,但从业内反馈来看,并没令所有人满意,Mixer的Check缓存机制究竟能多大程度缓解Policy的性能压力依然需要观察。

值得一提的是,我们发现的不少bug同时也在被社区其他开发者发现并逐一解决。令我们开心的是,UAEK团队不是信息孤岛,我们能感受到Istio官方社区正在努力高速迭代,始终在致力于解决广大开发者关心的种种问题,我们提交的issue能在数小时内被响应,这些,都让我们坚信,Istio是一个有潜力的项目,会向Kubernetes一样走向成功。
从UAEK接入用户的经验来看,用户需要正确地使用好Istio离不开前期深入的Istio文档学习。UAEK后续需致力于要简化这一过程,让用户能傻瓜化、界面化、随心所欲地定制自己的路由规则成为我们下一个愿景。
UAEK团队始终致力于改革UCloud内部研发流程,让研发提升效率,让运维不再苦恼,让所有人开心工作。除了继续完善ServiceMesh功能,下半年UAEK还会开放更多的地域和可用区,提供功能更丰富的控制台,发布自动化的代码管理打包持续集成(CI/CD)特性等等,敬请期待!
作者介绍
陈绥,UCloud资深研发工程师,先后负责监控系统、Serverless产品、PaaS平台ServiceMesh等开发,有丰富的分布式系统开发经验。
搞工程造价,工作在不同城市间流动吗?
如果你是毕业生,很有可能在一线施工现场做造价,留不留在公司是人力资源部定的,总之干工程的流动性就是很大。 但是如果是中建的分公司的话,它会有片区划分的,比如zj三局二公司北京公司就是管理华北片区的。
工程监理工程师的工作任务是三控二管一协调还是三控三管一协调
三控3管一协调
电子信息工程和通信工程在课程上有何区别
学科:工学门类:电气信息类专业名称:电子信息工程业务培养目标:本专业培养具备电子技术和信息系统的基础知识,能从事各类电子设备和信息系统的研究、设计、制造、应用和开发的高等工程技术人才。 业务培养要求:本专业是一个电子和信息工程方面的专业。 本专业学生主要学习信号的获取与处理、电厂设备信息系统等方面的专业知识,受到电子与信息工程实践的基本训练,具备设计、开发、应用和集成电子设备和信息系统的能力。 毕业生应获得以下几个方面的知识和能力:1.能够较系统地掌握本专业领域宽广的技术基础理论知识,适应电子和信息工程方面广泛的工作范围;2.掌握电子电路的基本理论和实验技术,具备分析和设计电子设备的基本能力;3.掌握信息获取、处理的基本理论和应用的一般方法,具有设计、集成、应用及计算机模拟信息系统的基本能力;4.了解信息产业的基本方针、政策和法规,了解企业管理的基本知识;5.了解电子设备和信息系统的理论前沿,具有研究、开发新系统、新技术的初步能力;6.掌握文献检索、资料查询的基本方法,具有一定的科学研究和实际工作能力。 主干学科:电子科学与技术、信息与通信工程、计算机科学与技术。 1.知识理论系统性较强。 学习本课程需要有一定的基础理论、知识作铺垫且又是学习有关后续专业课程的基础。 2.基础理论比较成熟。 虽然电子技术发展很快,新的器件、电路日新月异,但其基本理论已经形成了相对稳定的体系。 有限的学校教学不可能包罗万象、面面俱到,要把学习重点放在学习、掌握基本概念、基本分析、设计方法上。 主要课程:电路理论系列课程、计算机技术系列课程、信息理论与编码、信号与系统、数字信号处理、电磁场理论、自动控制原理、感测技术等。 主要实践性教学环节:包括课程实验、计算机上机训练、课程设计、生产实习、毕业设计等。 一般要求实践教学环节不少于30周。 修业年限:四年授予学位:工学学士通信工程主干课程: 主干学科:信息与通信工程、计算机科学与技术。 主要课程:电路理论与应用的系列课程、计算机技术系列课程、信号与系统、电磁场理论、数字系统与逻辑设计、数字信号处理、通信原理等。 对于女生来说,前者应该比较好.
发表评论