代理模式的新花样,istio秀肌肉!

原创:小姐姐味道(微信公众号ID:xjjdog),欢迎分享,转载请保留出处。

紧紧抓住最新技术的脉搏,用人话普及前沿技术,是xjjdog的一贯作风,现在也是一种责任和习惯。从漫天飞舞的华丽辞藻中,抓住技术的本质,可以避免喧宾夺主,也可以避免被忽悠。

基础架构,每一波都在革自己的命。ServiceMesh是处于云原生时代的改革尖兵,其中istio以其高贵的身份与绝佳的性能,一骑绝尘,隐隐有成为标准的可能。

接下来,让我们抽丝剥茧,来看一下istio到底是个啥。

1. 中间层是基础架构的绝招

在介绍istio到底为何物的时候,我们先来描述一个问题。

假如你的公司,打算全面拥抱SpringCloud微服务,那么你一定会选择Java语言。然后一些比较古老的项目,都往上面靠。

但总有一些比较顽固的项目,无法用Java重构。比如,你的某个工程是使用C++写的,重构的成本非常大。那怎么办呢?

1.1 sidecar

软件行业有一个永恒不变的真理:如果你想要快速有效的解决两个组件之间的问题,那就加入一个中间层。

无论是概念上的“中台”,还是技术层面的“proxy”,甚至是啰里啰唆的DDD分层,都可以这么玩!

对于网络请求来说,Proxy可以接管所有的流量,然后对这些流量进行转化、分析、调度,就能够把一个丑八怪服务套一层皮,变成一个外观上漂漂亮亮的服务。

解决上面的问题,我们只需要使用SpringCloud兼容的技术开发这个Proxy,然后做一层转化,将请求转化成C++调用,就可以很好的完成工作。调用这个Proxy的请求,压根不会想到后面竟然是C++。

image-20211118162152313.png

通常情况下,我们需要把Proxy和C++服务部署在一台机器上,它们就会有比较好的性能表现;当然,现在容器搞起来之后,就可以运行在两个不同的Docker实例上;再后来,k8s来了,一个Pod里可以直接放上Proxy和C++两个容器实例,它们之间就可以通过localhost通信,成为了一个整体。

这就是sidecar的概念。对这一部分不是很熟悉的同学,可以看以前的一篇文章:《ServiceMesh的关键:边车模式(sidecar);又要开车了》

为什么一定要讲到代理呢?因为istio核心组件,本质上,就是一个sidecar形式的proxy。你要请求后端的服务,就一定要经过istio。它接管了所有的流量,并根据这些流量的属性进行了划分。

image-20211118162827931.png

1.2 proxy的功能

理念就是这么简单。但一旦把微服务里各种乱七八糟的功能,全部交给istio去做,那事情就变得复杂起来。

众所周知,微服务所引入的问题,比它解决的问题还要多。有了配套的设施,微服务才算是真正的微服务。

我们来看一个请求从外围进入微服务后,都要进行哪些动作。

  • 微服务要想被找到彼此,就需要有一个统一的注册中心,当然它本质上是一个配置中心
  • 想要跟踪一个请求在不同运行实例上的运行情况,就需要一个集中的Tracing系统
  • 请求通过RPC调用后端的服务,首先要经过负载均衡,还要熔断、限流、重试、故障转移等。当然一切的基础,需要在安全的前提下进行
  • 一个请求还有更多属性,比如鉴权、加密、认证,灰度等。如果每个功能都做一遍,又复杂又枯燥。
  • 配套的CI/CD等,加快研发流程

关键是,这些功能对于业务开发的同学来说,并没有什么用。业务的同学只需要关注自己的业务逻辑就可以了,但目前我们上面所提到的各种技术术语和功能组件,现阶段的业务开发一点都绕不开。

更要命的是,不论我升级上面的哪一个组件,都需要业务重新引入一个新的SDK版本,然后滚动进行升级。因为它们之所以称之为基础设施,就是因为牵一发而动全身的。

所以我们的部署模式要有一些改变。如果我们的所有应用,都不直接向外提供服务,而是全部通过代理去转发请求,那么它就会变成下面这张图的样子。

image-20211118155953461.png

Envoy Proxy就相当于我们的代理sidecar,而Service AService B,就代表我们真正的微服务。服务实例和代理的数量,是1:1的。

那么我们上面所提到的所有流量,都可以由Envoy来接管---它和你直接调用后面的Service是没什么两样的,但由于它是一个Proxy,那就可以像Aop一样,在外面包一层,干任何事!

所有神奇的事情,都可以在代理发生!

1.3 数据平面和控制平面

如果你以前接触过ServiceMesh,你一定听说过这两个词。

数据平面,其实指的就是我们的Proxy集合。它虽然是个网状,但如果我们把它的概念统一一下,它就叫平面。

那么控制平面,就是配套的控制管理台,以及下发指令的管理后台等。

也就是说,大多数情况下,仅仅数据平面,服务就能运行。但要看框架强不强,还得看控制平面易用不易用。

image-20211118164753062.png

图中的上半部分,就是传说中的数据平面。经过我们上面的介绍,应该对其非常熟了。istio把它搞复杂的地方在于,它加入了证书体系来控制认证和授权。

但如果你的公司是自研ServiceMesh的话,那工作其实就简单的多了。你的工作量全部集中在proxy的开发上。

控制平面,如果不按照istio的规则来,其实也是可有可无的。比如,你的日志收集,可以直接穿透Pod连接到你的ELKB平台,遥测这一环,就可以沿用你公司原来的技术架构。

所以说。

如果你的公司比较新,基础设施还没有完善,那么直接上istio,那是非常棒的,因为大部分基础架构的组件,它都替你做了。

但如果你的公司有些年月,基础设施都开发的差不多了,那切换到istio的基础设施,那就是闲的!你的最好选择,就是开发这样一个代理,然后把流量导到自己的基础组件上。

使用C++或者Go语言而不是Java开发这样的组件,是最好的选择。因为Java开发Agent往往会占用比较多的内存。当然,如果内存对你来说不值钱的话,这话当我没说。

2. 统一是基础架构的首要目标

因为基础架构的范围很大,所以每一种技术都有多种解决方案。比如MQ,比较流行的就有Kafka、RabbitMQ、Pulsar等。

对于社区来说,竞争和差异化是促进创新的原则。但对于一个公司来说,基础架构的统一才是首要目标(那些巨无霸另说)。

所以无论是调度也好,还是流量拦截也罢,这个代理的职责只会变得越来越大。如果技术不统一,那么功能就会成为笛卡尔乘积式的爆炸。istio选用了比较主流的方式,代理通过Envoy来实现,而中间的网络协议,则支持 HTTP/1.1,HTTP/2,gRPC 或者 TCP等主流的通信协议。

统一,是它在这里体现的价值。

在功能上,Pod天然能够将代理和服务绑在一块,所以k8s成了首选的调度平台。当然你非要做类似NodePort一样的机器代理,那也没什么本质的区别。

1__pYrG7dF5AP9eHCa4YuTFgw.png

最终,经过社区的融合(或者说垄断),istio成为了完成统一整个目标的框架。它的职责也越来越多,慢慢演变成了上图的模样。

上半部分依然是雷打不动的数据平面,但istio在控制平面上开了花。

控制中心做了进一步的细分,分成了 Pilot、Mixer、和 Citadel,它们的各自功能如下:

  • Mixer:为整个集群执行访问控制策略管理(限流、限额等),并收集代理所观察到的,服务之间的流量统计数据,也就是遥测(监控、APM等)数据。

  • Pilot:为 Envoy 提供了服务发现流量管理智能路由(AB测试、金丝雀发布等),以及错误处理(超时、重试、熔断)功能。

  • Citadel:为服务之间提供认证和证书管理,可以让服务自动升级成 TLS 协议。

  • Galley:这个组件并不向数据平面直接提供业务能力,而是作为其他控制平面的协调组件,这样解耦的更加彻底,核心功能也越来越多。

End

我们可以到,一个正常的请求,在加入istio之后,就全部变成了proxy和proxy之间的通讯。proxy既代理了入流量,也代理了出流量,所有的流量都从它这里转了一圈,所以它能够拦截和分析任何数据。借助于k8s的助力,服务和proxy之间可以通过localhost通信。

对于微服务架构来说,一个请求会分散到多台机器上,耗时、错误日志等都会变的分散,问题排查起来不得不依赖APM等组件。istio更加彻底,你根本不知道具体的服务节点到底被调度到哪里了,传统的人肉运维方式失效,对上游的工具依赖性更高。

使用istio有很多前置的知识点需要啃掉,比如虚拟化、k8s。新公司直接跳过这两者拥抱istio甚至是更好的选择。但如果你的公司已经有了非常好用的基础设置工具,又与社区不兼容的话,那恐怕只有借鉴理念,自研proxy了。

作者简介:小姐姐味道 (xjjdog),一个不允许程序员走弯路的公众号。聚焦基础架构和Linux。十年架构,日百亿流量,与你探讨高并发世界,给你不一样的味道。我的个人微信xjjdog0,欢迎添加好友,进一步交流。

猜你喜欢

转载自juejin.im/post/7033613419617976357