腾讯云TSF微服务平台及ServiceMesh技术实践

接下来我们重点讲讲ServiceMesh的实现。
TSF服务框架的ServiceMesh主要是有2类实现。
第一类ServiceMesh实现是无独立控制面的全功能Sidecar,主要适用于有一定的研发能力,且对定制化要求较高的企业客户。TSF主要是基于Spring Cloud Sidecar能力来实现全功能Sidecar。Spring Cloud Sidecar的灵感来源于Netflix的Prana,这个也是Spring Cloud与ServiceMesh融合的重要手段。其主要工作流程如下图所示:

腾讯云TSF微服务平台及ServiceMesh技术实践


每个服务节点上会部署一个Sidecar进程,Sidecar根据配置将自身监听地址以及服务名注册到Consul Server。当收到外部请求时,会直接到达Zuul Servlet,此时首先判断请求是否来源于自身节点服务,假如来源于自身节点服务,则直接走本地路由。否则,就走Ribbon流程进行服务路由及转发。Sidecar在运行过程中,会定期调用所代理的服务的健康检查接口,获取服务健康状态并上报Consul Server。这种Sidecar代理+服务的方式,所表现出来的行为,与直接嵌入Spring Cloud SDK模式所表现的行为是一致的。Spring Cloud Sidecar模式的缺点在于对服务的URL有要求(来源于Zuul的约束,必须带有服务名),同时原生的Zuul + Ribbon转发模式的性能较差,缺少独立控制面使得运维成本较高。
第二类实现是带独立控制面的Sidecar,主要适用于对定制化要求不高,但是对性能比较敏感,业务代码改造工作量大,希望低成本运维的企业客户。带独立控制面的Sidecar也是ServiceMesh的业界通用实现。但是开发团队应该如何去实现这种ServiceMesh呢?
实现微服务框架的关键在于开源选型。TSF在Mesh构建初期,业界已经有不少优秀的开源数据面Sidecar产品,如Envoy、Linkrd、nginMesh、Conduit等,而且各有各的亮点和最佳适用场景。但最终数据面选定Envoy的原因在于:
  1. Envoy社区成熟度较高,商用稳定版本面世时间较长。如nginMesh以及Conduit至今仍未有商用版本。

  2. Envoy底层基于C++,性能上优于使用Scala的Linkrd,同时C++与腾讯系的语言体系较吻合。

  3. Envoy在腾讯内部使用相对广泛,稳定性相当高,对于运行态代理,稳定性直接影响交付质量。


而对于数据面的开源选型,则可选范围相对较少,当前控制面集大成者是Istio,业界几乎所有的开源数据平面产品(Conduit除外),都支持对接Istio,但是Istio存在2个问题使得当时在选型上挣扎了一下:
  1. 原生的Istio大部分能力与Kubernetes是强关联的。而TSF则是与P层平台解耦的,框架在设计上需要能够对接多P层平台。

  2. Istio至今未有商用稳定版本,当前最新版本是0.7.1。


最终控制平台仍然选型Istio,原因如下:
  1. Istio拥有极高的社区影响力,开发团队来源于Google和IBM。所基于的xDS(LDS、RDS、CDS、EDS)控制接口规范几乎成为控制面的实际规范。

  2. Istio版本速度较快,今年内极有可能会推出1.0版本。


  3. 腾讯云TSF微服务平台及ServiceMesh技术实践
  4. 通过调研Istio代码,发现通过一定程度的定制及扩展,可以使得Istio与Kubernetes成功解耦。经过选型后,我们Mesh产品架构如下:

  5. 腾讯云TSF微服务平台及ServiceMesh技术实践


Mesh涉及的部件所提供的功能如下:
  • Istio-Pilot:ServiceMesh的大脑,对接注册中心与配置中心,通过不同的接口给数据面节点提供服务调用所需要的全部规则及信息(包括Envoy的内部监听及转发规则、集群服务信息、服务路由规则、负载均衡规则、服务实例信息等),所依赖的控制接口描述可参考:https://github.com/envoyproxy/data-plane-api/tree/master/envoy/api/v2

  • Istio-Mixer:提供了一套Attribute处理框架,可供用户去定制服务权限控制、服务Quota限流、调用统计信息上报及采集分析的能力。

  • Istio-CA:主要是安全相关的。提供证书的更新、密钥集中管理下发、RBAC权限模型的更新及维护等能力。

  • Pilot-Agent:提供环境初始化、服务注册、Envoy进程监控的能力。

  • Envoy:提供服务的透明代理能力,可以根据控制面下发的控制信息进行消息的投递。当前支持的协议包括HTTP、HTTP2、GRPC。Envoy本身提供listener接口供自定义私有协议。ServiceMesh消息路由

    腾讯云TSF微服务平台及ServiceMesh技术实践

    下面通过一个例子讲解一下ServiceMesh内部如何进行消息路由:

    腾讯云TSF微服务平台及ServiceMesh技术实践


    • 服务A通过http://<targetServiceName>:<port>/url的方式对服务B发起REST服务调用。

    • A节点的流量接管能力将该报文接管到本节点的Envoy进程。

    • Envoy进程通过Pilot下发的控制信息(该控制信息的分类及运算比较复杂,鉴于篇幅关系不详细展开,后续有机会再单独开篇介绍),经过一系列的负载均衡计算及权限检查,确定了B服务的目标实例节点,将信息投递给该节点。

    • B节点收到消息后,流量接管能力将消息接管进Envoy。Envoy通过Quota限流策略检查是否已经达到上限,检查通过后,则根据Pilot下发的内部路由规则,路由给节点内的服务实例。

    • 服务实例收到请求后,进行业务逻辑的处理。

    ServiceMesh待改进点以及思路

    腾讯云TSF微服务平台及ServiceMesh技术实践

    最后,分享下ServiceMesh在使用过程中所遇到的待改进点以及思路。
    当前ServiceMesh在推广过程中,遇到的最大的障碍实际上还是Istio未有商用版本的问题。不过其实从Istio官网可以了解到,当前Istio大部分核心能力已经是beta或者stable状态(https://istio.io/about/feature-stages.html)。
    因此在商用前只要能够仔细评估涉及的能力范围,原则上不会出现较大的问题。其他潜在问题的待改进思路如下:
    • 暴力流量接管:这个也是网上诟病比较多的问题。由于Istio的数据面依赖于针对容器内流量进行全接管,但是对于虚拟机场景下可能不适用,毕竟虚拟机上可能不仅仅只有Mesh的服务。因此,需要考虑细粒度的接管方案。

    • 全量服务发现问题:Istio是一个集中的控制面,在构建路由数据时,会默认从注册中心获取全量的服务实例数据,一旦服务节点量级上升后,会导致较严重的性能及资源占用问题。因此,定制过程中可以考虑采用服务元数据的方式来减少发现的数据量。

    • Mixer缓存穿透的问题。由于Envoy在每个请求的发送前以及接受到请求后,都需要往Mixer去查询权限及Quota信息,为提升性能,Envoy会对这些查询结果进行缓存。而由于这些信息是per request的,而且Envoy无法知道会有哪些attributes(key)需要去缓存,从而缓存的总量有可能根据调用时长而呈现不断增长的趋势,引发资源占用问题。因此,在这方面可以适当引入LRU算法来解决。

    • 多租户隔离的支持。在公有云场景下,用户对隐私和隔离看得非常重要。往往不同用户/租户之间,服务配置、节点信息、控制信息等资源数据是隔离的,互相不可见。但是Istio本身并不支持这种级别的隔离。需要框架集成者去进行扩展。

    • 自动服务注册能力的支持。Istio并不提供自动服务注册能力(其服务模型依赖Kubernetes的Service),因此,假如需要将Istio脱离Kubernetes运行,首要解决的是自动服务注册的问题。思路是Pilot提供接口获取应用节点服务信息,然后通过通过每个节点部署的Pilot-Agent拉取并注册节点服务实例。


    由于ServiceMesh是一个技术栈相当深的系统,在不同业务场景下,所面对的挑战以及所需要的底层技术并非今天的分享就能够介绍全面的。
    由于本人学识有限, 所谈及的内容难免有疏漏之处,还请各位朋友不吝指正。谢谢!

上一篇:Istio熔断器功能解析


下一篇:k8s部署Istio1.5.8