这是「 Istio 系列 」的第一篇文章。
作为本系列的开篇,主要介绍服务网格所解决的痛点,以及 Istio 的功能和组件。
本篇大纲
在之前的一篇文章 云原生思想 中,说过软件架构是从 单体 -> 微服务 -> 基于 k8s 上的微服务 -> 服务网格
逐步演进的。
而原因,在文章中也给出了答案:
为了将业务和基础设施解耦
这短短一句话却是服务架构的终极目标。
微服务架构流行至今,沉淀出了一套属于自己的模式[1]:
微服务模式
图中几个主要的点:
这些 非业务性 的基础功能都是 微服务需要治理的问题 。
我们把上述长篇大论所涉及的功能点提炼一下:
微服务治理
可以看出微服务治理还是蛮多东西的,要是我们一一来手动解决,岂不累死去。因此各种微服务框架出场了,比如 Java 体系的 Spring Cloud ,Go 体系的 kratos、Go Zero 和 Go Kit 等。这些框架的共同点都是 用来帮助我们在开发过程中快速引入各种服务治理的组件。
当然,你还可以把大部分的功能下沉到 Kubernetes 来解决,如服务注册发现,负载均衡等。
上面我们说到,微服务架构的难题:服务治理 ,可以通过微服务框架引入各种治理组件。
但这种方式带有 侵入性 ,想要集成某种治理功能,除了引入相关依赖库,还需要 在业务代码中增加非业务功能的代码或注解 。另外,治理组件往往还比较 复杂 ,开发人员需要一定的学习周期才能 快速上手业务开发 。
除此之外,还有升级成本高、版本碎片化严重、中间件演变困难、治理功能不全等 问题[2] 存在。
即便我们还可以搭配 Kubernetes 来解决大部分的治理功能,减轻 业务开发 的压力,但并不意味着可以省心了。在细粒化的层面上,Kubernetes 往往是心有余而力不足。
熔断、限流、监控、认证、授权、安全、负载均衡等都有可能面临 细化管理的需求[3] 。例如服务调用时的负载均衡,往往需要根据流量特征,调整负载均衡的层次、算法等,而 Kubernetes 的 DNS 尽管能实现一定程度的负载均衡,但通常并不能满足这些额外的需求。
这也证明了 软件开发没有银弹 。
为了应对上诉的 痛点 ,服务架构再次演进到了 服务网格(Service Mesh) 。
Service Mesh 的起源可以追溯到 2016-09-29 ,由开发出 Linkerd 的 Buoyant 公司在 SF Microservices 公开场合上首次提出。这也正式让 Service Mesh 的概念从 Buoyant 公司内部走向社区。
Servicemesh布道[4]
自此,Service Mesh ,国内翻译作 服务网格 ,以其独特的理念,开始流行,甚至在技术社区,有人指出 Service Mesh 将会是下一代的微服务架构基础。
服务网格到底有多大的魔力。
Buoyant 公司的 CEO Willian Morgan 在他的这篇文章 WHAT’S A SERVICE MESH? AND WHY DO I NEED ONE?[5] 中解释了什么是 Service Mesh,以及为什么云原生应用需要 Service Mesh。
总结一下,大概是:
服务网格被定义为一个专门的基础设施层,用于管理服务与服务之间的通信,使其可管理、可见、可控制。 服务网格负责通过构成现代云原生应用的复杂服务拓扑来可靠地传递请求。 服务网格通常是作为一组轻量级的网络代理与应用程序部署在一起,应用程序是无感知的。
按照服务网格的定义,最终我们会得到如下的部署模型:
图源 pattern_service_mesh[6]
绿色部分 是实际的应用程序,蓝色部分 便是网络代理,这在服务网格中被称为 Sidecar (边车模式,类似连接到摩托车的边车),Sidecar 边车应用与应用程序共享相同的生命周期,与应用程序一起创建和退出。
Sidecar 只负责 服务间网络通信 。还需要有个组件来统一管理所有 Sidecar 的配置。在服务网格中,负责配置管理的部分就叫 控制平面(control plane) ,负责网络通信的部分叫 数据平面(data plane) 。数据平面和控制平面一起构成了服务网格的基本架构 。
pattern_service_mesh
在服务网格中,所有出站入站的流量都会通过 Sidecar 进行 处理和转发 ,这样之前所说的 微服务治理的功能就可以由服务网格来承担了 。
最重要的是服务网格不需要在应用层面加入额外的处理代码(非侵入性),就可以提供几乎不亚于程序代码级别的细化管理能力。
侵入式微服务框架 => 基于 Kubernetes 完成大部分微服务治理功能 => 基于服务网格解耦微服务治理和业务逻辑。
归根结底,就是那个宗旨:为了将业务和基础设施解耦 ,让业务开发人员专心实现业务,而无需理会业务无关的功能。
另提一嘴。服务网格和 Kubernetes 是相辅相成的关系 。Kubernetes 的本质是对应用的部署和管理,服务网格是对 Kubernetes 中的 Service 更上层的抽象 。而 Sidecar 就是作为一个 边车代理容器和业务应用容器共同部署在 Pod 里面 。
图源 istio-handbook[7]
业界第一款服务网格产品是 Buoyant 公司开发的 Linkerd ,如果说它是第一代产品,那么 Istio[8] 就是现今服务网格的第二代产品。本篇就不过多讲述它们之间的爱恨情仇了。如果感兴趣,可以在 Service Mesh 的发展史[9] 中了解。
相比于侵入式架构,非侵入式的服务网格最大的特性就是 对应用透明 。
作为现今服务网格的明星级产品,Istio 可以非常轻松地创建出一个网络,将微服务应用接入进来,而服务的代码只需很少甚至无需更改。
Istio 通过在整个环境中部署一个特殊的 Sidecar 代理为服务添加 Istio 的支持,而代理会拦截微服务之间的所有网络通信,然后使用其控制平面的功能来配置和管理 Istio,这包括:
即便有不同的需求,由于 Istio 的 可扩展性 设计,也都可以轻松应对。
从 宏观 上看,Istio 以统一的方式提供了许多跨服务网络的关键功能:
我们说过服务网格从逻辑上分为 数据平面和控制平面 。
在 Istio 中数据平面默认使用 Envoy 作为 Sidecar 代理(也支持使用 MOSN ),而控制平面则由 Istiod 提供支持。
Istio 架构
Envoy[10] 是一个用 C++ 开发的高性能代理。
Istio 将 Envoy 代理作为一个 Sidecar 容器注入到应用容器旁边,之后该代理拦截该服务所有入站和出站流量。
这些注入的 Envoy 代理们一起构成了服务网格的数据平面,并且在 Istio 中, Envoy 代理是唯一与数据平面流量交互的组件。
除了负载均衡、断路器、故障注入等基本功能,Envoy 还支持基于 WebAssembly(WASM)的可插拔扩展模型。这种可扩展性使我们能够执行自定义策略,并为网格中的流量生成遥测数据。
在 Istio 1.5 版本之前,控制平面的 Pilot、Citadel 和 Galley 组件是分散、独立部署的。而之后,出于 性能和易用性 方面考虑,这三个组件整合为一个单体结构 Istiod 。因此 Istio 的控制平面是一个 单进程、多模块 的组织形态。
Istiod 主要提供服务发现、配置和证书管理等功能。
Istiod 将采用 YAML 编写的控制流量行为的高级路由规则转换为 Envoy 特定配置,并在运行时把这个配置传播给网格中的所有 Sidecar。
按模块进一步细分的话:
作为「 Istio 系列 」的第一篇文章,主要想先让大家对 服务网格和 Istio 有个概念理解。
在下一篇中,再继续讲述 Istio 的安装以及入门使用。
感谢阅读到这里!关注我,下次见。
[1]
微服务模式: https://microservices.io/patterns/index.html
[2]
微服务治理问题: https://www.servicemesher.com/istio-handbook/concepts/overview.html
[3]
细化管理的需求: http://icyfenix.cn/architecture/architect-history/post-microservices.html
[4]
Servicemesh布道: https://skyao.io/learning-servicemesh/trend/2016/servicemesh.html
[5]
WHAT’S A SERVICE MESH? AND WHY DO I NEED ONE?: https://buoyant.io/what-is-a-service-mesh/
[6]
图源 pattern_service_mesh: https://philcalcado.com/2017/08/03/pattern_service_mesh.html
[7]
图源 istio-handbook: https://www.servicemesher.com/istio-handbook/concepts/microservices-in-post-kubernetes-era.html
[8]
Istio: https://istio.io/latest/zh/
[9]
Service Mesh 的发展史: https://istio.cn/t/topic/54
[10]
Envoy: https://www.envoyproxy.io/