Service Mesh(服务网格)诞生于云原生生态领域的潮流中,虽然大家对这一技术生态充满不确定性,甚至难以接受,然而,如果我们消除外面的“杂声”,细心洞察里面的细节,或许能有不一样的收获,毕竟,所有新技术的出现是为了解决业务痛点,而非是为了一些没用意义的炒作。
在上篇文章中,我们浅析了下一代微服务 Service Mesh 相关概念及基本架构原理,接下来我们将在本篇文章中重点介绍一下 Service Mesh 生态中两个非常重要的成员:Linkerd 和 Istio,通过结合对这两个成员的架构学习,使得我们进一步尝试弄明白:到底什么是 Service Mesh ?
下面,我们先来看张图以顺带了解下Service Mesh 微服务生态的产品类型及相关概念,具体如下所示:
基于上述图,我们可以看出,目前在 Service Mesh 生态中,2个核心成员 Linkerd 和 Istio 都是围绕“ Control Plane (控制面板)” 和“ Date Plane (数据面板)” 展开。Control Plane (控制面板)可以为路由流量管理和配置代理,并配置 Mixer 来强制执行策略并收集遥测数据。Date Plane (数据面板)是一组作为 Sidecar 部署的智能代理。这些代理会接收并控制服务网格内不同微服务之间的所有入站和出站网络数据。Sidecar 代理还和 Mixer(通用的策略和遥测系统) 进行沟通。下面我们针对各自成员进行逐一分析,具体如下。
Linkerd
Linkerd 是一种Service Mesh (基于William Morgan的定义,因为就是他们公司的产品,所以它当然是一种Service Mesh),它为云原生应用程序增加了可观察性、可靠性以及安全性,使得我们无需更改代码。例如,Linkerd 可以监控和报告每个服务的成功率和延迟,可以自动重试失败的请求,并且可以加密和验证服务之间的连接(TLS),所有这些都不需要对应用程序本身进行任何修改。
首先,我们先了解下其架构,具体如下所示:
基于上述架构示意图,我们可以看到,整个 Linkerd 体系分为Control Plane (控制平面)和Date Plane (数据平面)。控制平面主要包括诸如 Destination(服务发现)、Identity(证书颁发机构)、Public Api( Web和CLI 端点)以及Prometues等。与其不同的是,数据平面仅涉及应用程序实例及其所依赖的 Linkerd-Proxy。这只是简单的逻辑图,最终的部署我们可能得到每个控制平面组件的三个副本,但有成百上千个数据平面代理。同时,我们也注意到,在数据平面中,Linkerd-Proxy 容器与应用程序容器在同一容器中共同运行。我们将此种模式称为 Sidecar容器。
服务网格的体系结构具有重要意义:一方面,由于代理功能集是为服务到服务的调用而设计,因此只有当我们的应用程序作为服务构建时,服务网格才有意义。我们可以将其与整体组件一起使用,但是运行单个代理服务器将需要大量的组件,并且功能集并不适合。另一个结果是服务网格将需要很多代理。实际上,Linkerd为每个服务的实例添加一个Linkerd-Proxy。(其他一些网状网络实现为每个节点/主机/ VM添加一个代理。这两种方式都有很多。)大量使用代理本身有以下几点含义:
1、数据平面代理应该高效。在设计过程中,我们需要为每个调用添加两个代理跃点,一个在客户端,一个在服务端。
2、代理服务尽可能轻小。毕竟,每一个组件都会消耗内存和CPU等资源,并且这种消耗将随应用程序线性增长。
3、我们将需要一个用于部署和更新大量代理的系统。使得能够解放我们的手动操作。
Control Plane - 控制平面
Linkerd Control Plane 是一组运行在特定 Namespace (默认为 Linkerd )中的服务集。这些服务完成各种诸如,聚合遥测数据,提供面向用户的API,向 Data Plane 代理发送控制数据等操作,这些操作共同驱动 Data Plane 的行为。Control Plane 由四部分组成,具体如下所示:
1、Controller, Controller Deployment 由多个容器 (Public-api、Proxy-api、Destin-
ation、Tap) 组成,这些容器组合起来提供了Control Plane 的功能。
2、Web ,主要提供 Linkerd Dashboard。
3、Prometheus ,Linkerd 提供的 Metrics 由 Prometheus 收集和存储. 但是这个实例被配置为只用来收集和处理 Linkerd 产生的数据。
4、Grafana, Linkerd 提供了许多开箱即用的 Dashboard。可以与现有的Grafana组件结合在一起。
Data Plane - 数据平面
Linkerd Data Plane,由一些轻量级代理组成,作为 Sidecar 容器与服务代码部署在一起(可以理解为每个Pod中,除了有一个Container 运行 Service Code ,还需要有一个 Sidecar Container 运行 Data Proxy)。为了把 现有的服务加入到 Linkerd Service Mesh 中,就需要重新发布所有的 Pod 以便让 Pod 中包含 Data Plane Proxy ( Linkerd Inject 命令就可以完成这个事情)。并且可以通过 CLI 命令 将服务添加到 Data Plane。这些代理透明地拦截与每个pod之间的通信,并添加诸如检测和加密(TLS)之类的功能,以及根据相关策略允许和拒绝相关请求。同时,这些代理并不需要手动进行配置,而是通过 Control Plane 来进行配置。
针对Data Plane - 数据平面中的 Proxy,这些组件是做什么的呢?其主要功能为可感知第7层的TCP 代理,类似Haproxy 和 Nginx。基于不同的架构模型以及业务实现场景,代理的选择各不尽相同。Linkerd使用专门为服务网格构建的Rust “微代理”,简称为Linkerd-Proxy。其他网格使用不同的代理。但其本质都是为了实现某一特定细节。
那么,这些代理能做什么?主要为服务的内外访问提供路由调用。(严格来说,它们既充当“代理”又充当“反向代理”,同时处理请求和响应。)并且它们实现了一个功能集,专注于服务之间的调用。对服务之间流量的关注是使服务网格代理与 API 网关或入口代理(与入口代理)不同的原因,API 网关或入口代理关注从外部世界到整个集群的调用。
Linkerd Data Plane的 Proxy 代理,基于Rust编写,被部署到每个服务的Pod中,成为 Data Plane的一部分。其主要负责接收 Pod 的所有传入流量,并通过 InitContainer拦截所有传出流量,InitContainer配置 Iptables 以正确转发流量。因为它是 Sidecar 模式,用来拦截服务的所有传入和传出流量,所以不需要更改代码,甚至可以将其添加到正在运行的服务中。这些Proxy具有哪些特性呢?通常来讲,主要针对协议的支持,例如,针对非HTTP的4层负载均衡、TLS支持、HTTP,HTTP/2和任意TCP协议透明,零配置以及延迟感知7层负载等等。
针对Linkerd Cli,其主要运行在 Node 节点上,用来与 Control Plane 和 Data Plane 进行交互。借助Cli我们可以查看统计数据,实时调试生产中的数据以及安装升级 Data Plane 等。
接下来,我们再了解下Service Mesh 微服务生态的另外一种体系架构-Istio,具体如下。
Istio
Istio 是 Kubernetes 的本地解决方案,最初由Lyft发布,目前市面上许多技术公司已选择将其作为他们所选择的服务网格。例如,Google,IBM 以及 Microsoft依赖 Istio 作为各自的Kubernetes云服务中提供的默认服务网格。Platform9 Managed Kubernetes服务将很快提供针对混合环境的Istio的完全托管服务。Istio通过使用可缓存信息的Sidecar加载的代理分离了其数据和控制平面,因此不需要为每个调用返回到控制平面。控制平面是同样在Kubernetes集群中运行的Pod,如果服务网格的任何部分中单个Pod发生故障,则可以提供更好的弹性。
我们先了解下其架构,具体如下所示:
基于上述架构示意图,可以看到:Istio Service Mesh 逻辑上也同样分为Data Plane和 Control Plane。Data Plane 由一组以 Sidecar 方式部署的智能代理(Envoy)组成。这些代理可以调节和控制微服务及 Mixer 之间所有的网络通信。Control Plane 则负责管理和配置代理来路由流量。此外控制平面配置 Mixer 以实施策略和收集遥测数据。
下面我们针对Istio 架构中的组件进行简要解析,首先,我们来看下组件Pilot 。
Pilot 为 Envoy Sidecar 提供服务发现功能,为智能路由(例如 A/B 测试、金丝雀部署等)和弹性(超时、重试、熔断器等)提供流量管理功能。它将控制流量行为的高级路由规则转换为特定于 Envoy 的配置,并在运行时将它们传播到 Sidecar。
Pilot 将平台特定的服务发现机制抽象化并将其合成为符合 Envoy 数据平面 API 的任何 Sidecar 都可以使用的标准格式。这种松散耦合使得 Istio 能够在多种环境下运行(例如,Kubernetes、Consul、Nomad),同时保持用于流量管理的相同操作界面。其简要架构如下所示:
关于Galley组件,其主要功能为负责 Istio 的配置验证、获取、处理和分配组件的任务。它将其余的 Istio 组件与从底层平台(例如 Kubernetes)获取用户配置的细节中隔离开来。
接下来,我们再了解下 Citadel 组件, Citadel 组件主要基于其内置身份和凭证管理赋能强大的服务间和最终用户身份验证。可用于升级服务网格中未加密的流量,并为技术人员提供基于服务标识而不是网络控制的强制执行策略的能力。简要的工作流示意图具体可以参考如下:
关于 Mixer 组件,它是一个独立于平台的组件,负责在服务网格上执行访问控制和使用策略,并从 Envoy 代理和其他服务收集遥测数据。代理提取请求级属性,发送到 Mixer 进行评估。有关属性提取和策略评估的更多信息,大家可参考官网中关于 Mixer的相关配置。
Mixer 中包括一个灵活的插件模型,使其能够接入到各种主机环境和基础设施后端,从这些细节中抽象出 Envoy 代理和 Istio 管理的服务。其简要拓扑结构示意图如下所示:
最后,我们来了解下 Istio 体系中的另一个核心组件 Envoy,Istio 使用基于Envoy 代理的扩展版本,Envoy 是以 C++ 开发的高性能代理,用于调解服务网格中所有服务的所有入站和出站流量。Envoy 的许多内置功能被 Istio 发扬光大。其基本功能与 Linkerd 体系架构中的 Linkerd-Proxy 功能基本上一致。比如,所包含的协议支持、负载均衡、动态服务发现、熔断以及其他的类似功能。
在 Istio 架构体系中,Envoy 被部署为 Sidecar,和对应服务在同一个 Kubernetes Pod 中。这允许 Istio 将大量关于流量行为的信号作为属性提取出来,而这些属性又可以在 Mixer 中用于执行策略决策,并发送给监控系统,以提供整个网格行为的信息。除此之外,Sidecar 代理模型还可以将 Istio 的功能添加到现有部署中,而无需重新构建或重写代码。
那么,现在有个问题,既然 Istio 与 Linkerd 都作为 Service Mesh生态中的2大形态,为什么不使用相同的Proxy 呢?至此,关于Service Mesh 生态体系中的 Linkerd 与 Istio 解析到此为止。