近期,服务网格(Service Mesh)越加流行红火,各类社区讨论也层出不穷。面对如此火热的技术,我们不免有些疑问:服务网格究竟是什么,服务网格解决了什么?本文尝试简单讲解服务网格的架构设计,并介绍其流行解决方案 Istio。
从分布式系统聊起
现代的应用已经很少采用单体架构了,当分布式架构成为主流,系统组件间的网络调用变成了自然而然的问题。
当然服务数目比较少的时候,服务可以通过配置文件来记录其他服务的网络位置,进行调用时只需要读取配置即可,但当系统越来越庞大、自动化程度越来越高,配置文件这种方式便会成为一种负担。因此会引入 服务中心 来统一管理所有的服务,类似一个系统级的 DNS,来帮助某个服务来找到所依赖的服务。
上图便是一种常见的服务中心流程,Spring 全家桶中的 Eureka 便是采取这种模式。这种模式的特征比较明显:1. 服务会自注册,2. 服务主动去 Service Name System 中查询其他服务的地址。换句话说,服务是知道有服务中心存在的,并且有部分逻辑会侵入代码。
当然,还有不侵入代码的架构方式,就是把服务的注册、发现下沉到基础设施,在宿主机上运行代理进程,服务通过代理对其他组件发起访问。
如上图,服务本身可能并不知道服务中心或者代理的存在,但是整个系统依然拥有了服务注册、服务发现的能力。
服务网格的网格
说起最能体现服务网格 “样子” 的图片,肯定是这一张:
绿色的部分就是我们自己定义的服务,而蓝色的部分,便是 Sidecar。其工作原理,类似于上面提到的第二种服务发现模式,不过是高配版,因为并非在宿主机部署 Proxy,而是每个服务都拥有自己的 Proxy(Sidecar)。
但也只有 Proxy 是不够的,还需要一个 Service Name System,服务网格仅有 Sidecar 也是不够的,还需要一个控制平面:
只不过控制平面并不只是作为注册中心,还有很多强大的功能,下面,我便以具体的服务网格解决方案:Istio 来介绍。
Istio
Istio 服务网格逻辑上分为 数据平面 和 控制平面。
- 数据平面 由一组以 sidecar 方式部署的智能代理组成。这些代理可以调节和控制微服务及 Mixer 之间所有的网络通信。
- 控制平面 负责管理和配置代理来路由流量。此外控制平面配置 Mixer 以实施策略和收集遥测数据。
官方推荐使用 Envoy 作为 Sidecar。Envoy 是一个 C++ 写的高性能代理,根据官方描述,Envoy 具有动态服务发现、负载均衡、多协议支持等优点,如果是通过 Kubernetes 部署,只需要将 Envoy 和业务服务放在同一个 Pod,经过简单配置,便可接入网格。
Istio 的控制平面采用方便拓展的设计结构,主要由 Pilot、Mixer、Citadel 组件组成,并可以根据自己的需求插拔或者拓展。
Pilot 起到了前文提到的 Service Name System 的作用,担当服务发现、智能路由、流量管控的大任。
Mixer 主要的作用检查和遥测,比如前置条件检查(如认证、白名单等),配额检查(如判断服务的访问频率是否超标等),监控(如链路追踪、日志等)。
也正是因为 Mixer 在整个网络中起到了无微不至的大管家角色,在被人诟病性能问题时首当其冲。不过好在 Mixer 是一个比较独立的组件,如果系统已经有自己比较完善的监控、认证方案,也可以不启用 Mixer。
Istio 中,所有服务间的通讯全部是经过 Sidecar 的,而 Citadel 便是负责两个服务间通讯的安全问题,其提供了终端用户认证、流量加密的能力。
Istio 的组件比较简单,但也就是其简单的架构,帮我们完成和掩盖了大量复杂的事情。当然,Istio 并不是唯一的选择,老牌的 Linkerd,华为、阿里根据自己的需求改进并开源的 SM 解决方案,都是很不错的选择。
如何看待服务网格
如何看待当下火热的服务网格呢?在此之前,我们先看它为我们解决了什么?
- 流量管理
- 安全
- 可观测性
那除此之外,对使用者来说,又带来了什么隐患?
- 架构变复杂,运维难度升级
- 需要去了解,有一定的学习成本
- 每次请求都加了两跳,排错困难、性能隐患
因此,如果引入服务网格不是为了解决当前面临的问题,就没有引入的必要,还是那句老话:“如无必要勿增实体”,何况这个实体还是个黑盒子。不过,如果引入服务网格是为了解决当前的问题,那需要想清楚自己是否承受的起上面提到的隐患,毕竟没有东西会是银弹。