8.4 控制平面技术:从微服务架构到单体架构
本节,笔者继续以 Istio 的架构设计为例,讨论服务网格的控制平面设计。
Istio 之所以脱颖而出,最大创新在于它为微服务系统带来了前所未有的控制力:
- 以 Linkerd 代表的第一代服务网格通过 Sidercar 模式控制微服务间所有的流量;
- 以 Istio 为代表的第二代服务网格新增控制平面,控制所有的 Sidecar。于是,Istio 间接掌控了系统中的所有请求和流量。
自发布第一个版本以来,Istio 有着一个堪称优雅的架构设计。Istio 的整个系统分为数据面和控制面:前者通过代理组件 Envoy 负责流量处理;后者根据功能职责不同,由多个微服务(如 Pilot、Galley、Citadel、Mixer)组成。Istio 控制面组件的拆分设计,看似拥有微服务架构所有的优点:职责分离、独立部署、独立的伸缩能力。但实际场景中却没有达到理想中的设计效果,我们思考如下问题:
服务网格控制面的问题
如果业务调用异常,由于接入了服务网格。工程师首先需要排查控制面内各个组件是否正常:首先检查 pilot 是否正常工作,配置是否正常下发至 Sidecar,然后检查 Galley 组件是否正常同步服务实例信息,还需要检查 Sidecar 是否正常注入...
一方面控制面的组件越多,排查问题时需要检查的故障点越多。另一方面,过多的组件设计导致部署的难度也会增加。
服务网格号称下一代微服务架构,用于解决微服务之间运维管理问题,但在服务网格的设计过程中,又引入了一套新的微服务架构,这岂不是“用一套微服务架构设计的系统解决另一套微服务系统的服务治理问题?”,那谁来解决 istio 系统本身的微服务架构问题呢?
在 Istio 推出三年之后,也就是 Istio 的 1.5 版本,开发团队推翻了之前控制面的设计,启用了“复古”的单体架构,引入了的统一组件 istiod,它整合了 Pilot、Citadel 和 Galley 的功能,并以单个二进制文件的形式部署。Istio 1.5 版本的架构调整,其实只是将原有的多进程设计模式转换为单进程的形式,因此,istiod 就需要承担之前组件的所有职责:
- 服务发现与配置分发:从 Kubernetes 等平台获取服务信息,将路由规则和策略转换为 xDS 协议下发至 Envoy 代理。
- 流量管理:管理流量路由规则,包括负载均衡、分流、镜像、熔断、超时与重试等功能。
- 安全管理:生成、分发和轮换服务间的身份认证证书,确保双向 TLS 加密通信;基于角色的访问控制(RBAC)和细粒度的授权策略,限制服务间的访问权限。
- 可观测性支持:协助 Envoy 采集运行时指标(如延迟、错误率、请求流量等),并将数据发送到外部监控系统(如 Prometheus);支持分布式追踪系统(如 Jaeger、Zipkin 和 OpenTelemetry),帮助分析跨服务调用链路;提供访问日志和事件日志的采集功能。
- 配置验证与管理:验证用户提交的网格配置,并将其分发到数据平面,确保一致性和正确性。
图 8-12 Istio 架构及各个组件
通过多进程到单进程的架构调整,Istio 的开发团队以最小的成本实现了整体运维的巨大收益:
- 运维配置变得更加简单,用户只需要部署或升级一个单独的服务组件;
- 更加容易排查错误,因为不需要再横跨多个组件去排查各种错误;
- 更加利于做灰度发布,因为是单一组件,可以非常灵活切换至不同的控制面;
- 避免了组件间的网络开销,因为组件内部可直接共享缓存、配置等,也会降低资源开销;
通过上面的分析,你是否对 Istio 控制平面的拆分架构有了新的看法。看似优雅的架构设计,往往在用户落地过程中,对运维/开发人员带来了意料之外的困难。还真是顺应了一句老话:“没有完美的架构,只有最合适的架构”。