Service Mesh(中文译做服务网格)这一概念由 Buoyant 公司的 CEO,William Morg」n 首先提出。2017 年 4 月该公司发布了第一个 Service Mesh 产品 Linkerd,这篇同一时间发表的文章 What’s a service mesh?And why do I need one? 也被业界公认是 Service Mesh 的权威定义。
其定义翻译为:Service Mesh 是一个处理服务通讯的专门的基础设施层。它的职责是在由云原生应用组成服务的复杂拓扑结构下进行可靠的请求传送。在实践中,它是一组和应用服务部署在一起的轻量级的网络代理,对应用服务透明。这段话有点晦涩难懂,但只要抓住下面 4 个关键点就能轻松理解:
如果用一句话来总结,我个人对它的定义是:Service Mesh 是一组用来处理服务间通讯的网络代理。 上面晦涩抽象的定义很难让你真正理解 Service Mesh 存在的意义。你可能会想,服务间通信(service-to-service communication)无非就是通过 RPC、HTTP 这些方式进行,有什么可处理的?没错,服务间只需要遵循这些标准协议进行交互就可以了,但是在微服务这样的分布式环境下,分散的服务势必带来交互的复杂性,而规模越大的系统其通信越加错综复杂。分布式计算下的 8 个谬论很好的归纳了分布式环境下存在的网络问题。而为了解决这些问题,提高系统的容错能力和可用性,出现了服务注册与发现、负载均衡、熔断、降级、限流等等和通信相关的功能,而这些才是 Service Mesh 要真正处理的问题。 Pattern:Service Mesh 这篇文章详细的讲述了微服务架构下通讯处理的演进,由此引出 Service Mesh 出现的意义和核心价值。下图为服务通信演变的过程:
可以说,Service Mesh 就是 Sidecar 的网络拓扑形态,Mesh 这个词也由此而来。(关于 Sidecar 模式这里不做讨论,你可以自行 Google)。 业务系统的核心价值应该是业务本身,而不是服务,微服务只是一种实现手段,实现业务才是目标。现有的微服务架构下,为解决可能出现的网络通信问题,提升系统的弹性,开发人员不得不花费大量时间和精力去实现流量控制相关的非业务需求,不能聚焦在业务本身。而 Service Mesh 的出现解决了这一问题,带来了下面 2 个变革:
在云原生应用中,面对数百个服务或数千个实例,单个业务链路的请求经由服务的拓扑路径可能会非常复杂,单独处理非常必要。这就是 Service Mesh 的意义所在。 那么 Service Mesh 到底能带来哪些实用的功能呢?可以把它们归纳为下面 4 个部分:
通过上面的讲述,我相信 Service Mesh 的概念大家都已经有所了解。接下来我们来介绍两个重要的网格产品,让大家进一步了解 Service Mesh 的产品形态是什么样的。 目前市面上比较成熟的开源服务网格主要有下面几个:Linkerd,这是第一个出现在公众视野的服务网格产品,由 Twitter 的 finagle 库衍生而来,目前由 Buoyant 公司负责开发和维护;Envoy,Lyft 开发并且是第一个从 CNCF 孵化的服务网格产品,定位于通用的数据平面或者单独作为 Sidecar 代理使用;Istio,由 Google、IBM、Lyft 联合开发的所谓第二代服务网格产品,控制平面的加入使得服务网格产品的形态更加完整。 从今年的风向看,作为构建云原生应用的重要一环,Service Mesh 已经被各大云厂商认可,并看好它的发展前景。在 Istio 红透半边天的情况下,作为和 Google 在云服务市场竞争的 Amazon 来说,自然不愿错失这块巨大的蛋糕。他们在今年 4 月份发布了自己的服务网格产品:AWS App Mesh。这一部分内容我们会聚焦于 Istio 和 App Mesh 这两个产品,通过横向的对比分析让大家对 Service Mesh 的产品形态和两大云厂商的策略有一个更深入的认识。 从官方的介绍来看,Istio 和 App Mesh 都明确的表示自己是一种服务网格产品。Istio 强调了自己在连接、安全、控制和可视化 4 个方面的能力;而 App Mesh 主要强调了一致的可见性和流量控制这两方面能力,当然也少不了强调作为云平台下的产品的好处:托管服务,无需自己维护。 从某种程度上讲,Istio 是一个相对重一点的解决方案,提供了不限于流量管理的各个方面的能力;而 App Mesh 是更加纯粹的服务于运行在 AWS 之上的应用并提供流控功能。笔者认为这和它目前的产品形态还不完善有关(后面会具体提到)。从与 AWS 技术支持团队的沟通中可以感觉到,App Mesh 应该是一盘很大的棋,目前只是初期阶段。 和 AWS 里很多产品一样,App Mesh 也不是独创,而是基于 Envoy 开发的。AWS 这样的闭环生态必然要对其进行改进和整合。同时,也为了把它封装成一个对外的服务,提供适当的 API 接口,在 App Mesh 这个产品中提出了下面几个重要的技术术语,我们来一一介绍一下。
上面的图展示了这几个概念的关系:当用户请求一个虚拟服务时,服务配置的路由器根据路由策略将请求指向对应的虚拟节点,这些节点最终会与集群中某个对外提供服务的 DNS 或者服务名一一对应。 那么这些 App Mesh 自创的术语是否能在 Istio 中找到相似甚至相同的对象呢?我归纳了下面的表格来做一个对比:
从上面的对比看出,App Mesh 目前基本上实现了最主要的流量控制(路由)的功能,但像超时重试、熔断、流量复制等高级一些的功能还没有提供,有待进一步完善。 AWS App Mesh 是一个商业产品,目前还没有找到架构上的技术细节,不过我们依然可以从现有的、公开的文档或介绍中发现一些有用的信息。 从这张官网的结构图中可以看出,每个服务的橙色部分就是 Sidecar 代理:Envoy。而中间的 AWS App Mesh 其实就是控制平面,用来控制服务间的交互。那么这个控制平面具体的功能是什么呢?我们可以从今年的 AWS Summit 的一篇 PPT 中看到这样的字样:
熟悉 Istio 架构的朋友有没有觉得似曾相识?没错,这个控制平面的职责和 Pilot 基本一致。由此可见,不管什么产品的控制平面,也必须具备这些核心的功能。 那么在平台的支持方面呢?下面这张图展示了 App Mesh 可以被运行在如下的基础设施中,包括 EKS、ECS、EC2 等等。当然,这些都必须存在于 AWS 这个闭环生态中。 而 Istio 这方面就相对弱一些。尽管 Istio 宣称是支持多平台的,但目前来看和 Kubernetes 还是强依赖。不过它并不受限于单一的云平台,这一点有较大的优势。 Istio 的架构大家都比较熟悉,数据平面由 Envoy sidecar 代理组成,控制平面包括了 Pilot、Mixer、Citadel、Galley 等控件。它们的具体功能这里就不再赘述了,感兴趣的同学可以直接去官网查看详细信息。 部署 无论是 Istio 还是 App Mesh 都使用了控制平面 + 数据平面的模式,且 Sidecar 都使用了 Envoy 代理。Istio 的控制平面组件较多,功能也更复杂,1.0.x 版本完整安装后的 CRD 有 50 个左右。架构修改后 Mixer 的一些 adapter 被独立出去,crd 有所降低。下面是最新的 1.4 版本,安装后仍然有 24 个 crd。 而 App Mesh 就简单得多,只针对核心概念添加了如下 3 个 crd,用一个 controller 进行管理。 尽管 Istio 更多的 crd 在一定程度上代表了更加丰富的功能,但同时也为维护和 troubleshooting 增加了困难。 流量控制 尽管两者的数据平面都基于 Envoy,但它们提供的流量控制能力目前还是有比较大的差距的。在路由的设置方面,App Mesh 提供了相对比较丰富的匹配策略,基本能满足大部分使用场景。下面是 App Mesh 控制台里的路由配置截图,可以看出,除了基本的 URI 前缀、HTTP Method 和 Scheme 外,也支持请求头的匹配。 Istio 的匹配策略更加完善,除了上面提到的,还包括 HTTP Authority,端口匹配,请求参数匹配等,具体信息可以从官方文档的虚拟服务设置查看。下面两段 yaml 分别展示了两个产品在虚拟服务配置上的差异。 App Mesh 配置: Istio 配置: 另外一个比较大的不同是,App Mesh 需要你对不同版本的服务分开定义(即定义成不同的虚拟服务),而 Istio 是通过目标规则 DestinationRule 里的子集 subsets 和路由配置做的关联。本质上它们没有太大区别。 除了路由功能外,App Mesh 就显得捉襟见肘了。就在笔者撰写本文时,AWS 刚刚添加了重试功能。而 Istio 借助于强大的 Envoy,提供了全面的流量控制能力,如超时重试、故障注入、熔断、流量镜像等。 安全 在安全方面,两者的实现方式具有较大区别。默认情况下,一个用户不能直接访问 App Mesh 的资源,需要通过 AWS 的 IAM 策略给用户授权。比如下面的配置是容许用户用任意行为去操作网格内的任意资源: 因此,App Mesh 的授权和认证都是基于 AWS 自身的 IAM 策略。 Istio 提供了两种认证方式,基于 mTLS 的传输认证,和 基于 JWT 的身份认证。而 Istio 的授权是通过 RBAC 实现的,可以提供基于命名空间、服务和 HTTP 方法级别的访问控制。这里就不具体展示了,大家可以通过官网文档来查看。 可观察性 一般来说,可以通过三种方式来观察你的应用:指标数据、分布式追踪、日志。Istio 在这三个方面都有比较完整的支持。指标方面,可以通过 Envoy 获取请求相关的数据,同时还提供了服务级别的指标,以及控制平面的指标来检测各个组件的运行情况。通过内置的 Prometheus 来收集指标,并使用 Grafana 展示出来。分布式追踪也支持各种主流的 OpenTracing 工具,如 Jaeger、Zipkin 等。访问日志一般都通过 ELK 去完成收集、分析和展示。另外,Istio 还拥有 Kiali 这样的可视化工具,给你提供整个网格以及微服务应用的拓扑视图。总体来说,Istio 在可观察方面的能力是非常强大的,这主要是因为 Mixer 组件的插件特性带来了巨大的灵活性。 App Mesh 在这方面做的也不错。从最新发布的官方 repo 中,App Mesh 已经提供了集成主流监控工具的 helm chart,包括 Prometheus、Grafana、Jaeger 等。同时,AWS 又一次发挥了自己闭环生态的优势,提供了与自家的监控工具 CloudWatch、X-Ray 的整合。总的来说,App Mesh 在对服务的可观察性上也不落下风。 AWS App Mesh 作为一个 2019 年 4 月份才发布的产品(GA),在功能的完整性上和 Istio 有差距也是情有可原的。从 App Mesh 的 Roadmap 可以看出,很多重要的功能,比如熔断已经在开发计划中。从笔者与 AWS 的支持团队了解的信息来看,他们相当重视这个产品,优先级很高,进度也比较快,之前还在预览阶段的重试功能在上个月也正式发布了。另外,App Mesh 是可以免费使用的,用户只需要对其中的实例资源付费即可,没有额外费用。对 AWS 来说,该产品的开发重点是和现有产品的整合,比如 Roadmap 列出的使用 AWS Gateway 作为 App Mesh 的 Ingress。借助着自己的生态优势,这种整合即方便快捷的完善了 App Mesh,同时又让生态内的产品结合的更紧密,使得闭环更加的牢固,不得不说是一步好棋。 和 App Mesh 目前只强调流控能力不同,Istio 更多的是把自己打造成一个更加完善的、全面的服务网格系统。架构优雅,功能强大,但性能上受到质疑。在产品的更迭上貌似也做的不尽如人意(不过近期接连发布了 1.3 到 1.4 版本,让我们对它的未来发展又有了期待)。Istio 的优势在于 3 大顶级技术公司加持的强大资源,加上开源社区的反哺,利用好的话容易形成可持续发展的局面,并成为下一个明星级产品。然而 Google 目前对 Istio 的态度有一些若即若离,一方面很早就在自家的云服务 gcloud 里提供了 Istio 的默认安装选项,但同时又发布了和 Istio 有竞争关系的 Traffic director 这个托管的控制平面。笔者的猜测是 Google 也意识到 Istio 的成熟不可能一蹴而就,鉴于网格技术托管需求的越发强烈,先提供一个轻量化的产品以占领市场。 目前各大厂商都意识到了网格技术的重要性并陆续推出了自己的产品(包括 AWS App Mesh,Kong 的 Kuma,国内的蚂蚁金服、腾讯云等),竞争也会逐渐激烈。未来是三分天下还是一统山河,让我们拭目以待。 最后这部分给大家简要介绍一下我们(FreeWheel)在 Service Mesh 领域的实践。希望通过一些前瞻性的探索,总结出最佳实践,为我们将来的微服务应用全面拥抱云原生提供一定的经验和指导。目前我们已经开发完成的 Data service 项目就整合了 AWS App Mesh,即将上线,并使用网格的能力进行智能路由和发布。 Data service 项目只包含两个服务:Forecast service 和 Query service,前者作为业务服务通过 Query service 查询来自持久层(ClickHouse)的数据;后者作为数据访问代理,从持久层获取数据并进行对象化的封装。这个 mini 的微服务系统非常适合作为一个先行者为我们探索网格的功能、性能、易用性等方面的能力,且范围足够小,不会影响到其他业务系统。 选择 AWS App Mesh 作为该项目的网格产品主要原因如下:
下图是该项目的部署视图。前端请求从我们的业务系统 UIF 发送到 Forecast service,它作为 App Mesh 的一个虚拟节点,调用 Data service 进行数据查询。Data service 作为数据平面,会注入 App Mesh 的 sidecar 代理。这两个服务组成了一个 Mesh 网格,并无缝整合在 AWS 的 EKS 中。 下图是网格内部的逻辑视图,展示了如何利用 App Mesh 进行智能路由。Forecast service 作为调用者被定义为虚拟节点,Data service 作为虚拟服务,挂载着虚拟路由,内部根据需要可以设定若干路由规则。用 App Mesh 实现一个金丝雀发布的过程非常简单:假设在 Data service 的新版本(V2)发布前,流量都被指向 V1 版本;此时我们在 App Mesh 里配置好一个新的路由规则,将 10% 的流量指向新的 V2 版本;只需要将新的规则通过 kubectl apply -f new-rule.yaml 应用到集群中,金丝雀发布就可以完成,且无缝切换,对用户透明。 在后续的工作中,我们会先验证 App Mesh 的性能和可靠性,然后逐渐的将更多的流量控制(如超时重试、熔断等)功能添加进来,并总结出一整套可行的实施方案,供大家参考。也欢迎对 Service Mesh 感兴趣的同学加入到我们的团队中,一起学习,共同进步。 解耦是软件开发中永恒的主题,开发人员对消除重复的偏执是推动软件、以及架构模式演进的主要动力。而 Service Mesh 的核心价值就是将服务通信功能从业务逻辑中解耦,并下沉为基础设施,由控制平面统一管理。有人将 Service Mesh、Kubernetes 和 Serverless 技术称为云原生应用开发的三驾马车。Kubernetes 是云应用实际意义上的操作系统;Service Mesh 将服务通信功能剥离,实现了与业务的解耦;Serverless 让你不用关心应用的服务器。这三项技术让我们有能力实现应用开发的终极目标,那就是:只关注业务本身。而它们,也会引领我们通向未来云原生应用的诗和远方。 |
|