Service Mesh如此火热,背后的技术细节你了解多少?

点击上方“程序员大咖”,选择“置顶公众号”

关键时刻,第一时间送达!640?640?wx_fmt=gif















































































































































































































































































































    先不说楚枫的这般年纪,能够踏入元武一重说明了什么,最主要的是,楚枫在刚刚踏入核心地带时,明明只是灵武七重,而在这两个月不到的时间,连跳两重修为,又跳过一个大境界,踏入了元武一重,这般进步速度,简直堪称变态啊。


    “这楚枫不简单,原来是一位天才,若是让他继续成长下去,绝对能成为一号人物,不过可惜,他太狂妄了,竟与龚师兄定下生死约战,一年时间,他再厉害也无法战胜龚师兄。”有人认识到楚枫的潜力后,为楚枫感到惋惜。


    “哼,何须一年,此子今日就必败,巫九与龚师兄关系甚好,早就看他不顺眼了,如今他竟敢登上生死台挑战巫九,巫九岂会放过他?”但也有人认为,楚枫今日就已是在劫难逃。


    “何人挑战老子?”就在这时,又是一声爆喝响起,而后一道身影自人群之中掠出,最后稳稳的落在了比斗台上。


    这位身材瘦弱,身高平平,长得那叫一个猥琐,金钩鼻子蛤蟆眼,嘴巴一张牙带色儿,说话臭气能传三十米,他若是当面对谁哈口气,都能让那人跪在地上狂呕不止。


    不过别看这位长得不咋地,他在核心地带可是鼎鼎有名,剑道盟创建者,青龙榜第九名,正是巫九是也。


    “你就是巫九?”楚枫眼前一亮,第一次发现,世间还有长得如此奇葩的人。


    巫九鼻孔一张,大嘴一咧,拍着那干瘪的肚子,得意洋洋的道:“老子就是巫九,你挑战老子?”


    “不是挑战你,是要宰了你。”楚枫冷声笑道。


    “好,老子满足你这个心愿,长老,拿张生死状来,老子今日在这里了解了这小子。”巫九扯开嗓子,对着下方吼了一声。


    如果他对内门长老这么说话,也就算了,但是敢这么跟核心长老说话的,他可真是算作胆肥的,就连许多核心弟子,都是倒吸了一口凉气,心想这楚枫够狂,想不到这巫九更狂。


    不过最让人无言的就是,巫九话音落下不久,真有一位核心长老自人群走出,缓缓得来到了比斗台上,左手端着笔墨,右手拿着生死状,来到了巫九的身前。


    “我去,这巫九什么身份,竟能这般使唤核心长老?”有人吃惊不已,那长老修为不低,乃是元武七重,比巫九还要高两个层次,但却这般听巫九的话,着实让人吃惊不已。


    “这你就不知道了吧,巫九在前些时日,拜了钟离长老为师尊,已正式得到钟离长老的亲传。”有人解释道。


    “钟离长老?可是那位性情古怪的钟离一护?”


    “没错,就是他。”


    “天哪,巫九竟然拜入了他的门下?”


    人们再次大吃一惊,那钟离一护在青龙宗可是赫赫有名,若要是论其个人实力,在青龙宗内绝对能够排入前三,连护宗六老单打独斗都不会是他的对手。


    只不过那钟离一护,如同诸葛青云一样,也是一位客卿长老,所以在青龙宗内只是挂个头衔,什么事都不管,更别说传授宗内弟子技艺了,如今巫九竟然能拜入他老人家门下,着实让人羡慕不已。


    “恩怨生死台,的确可以决斗生死,但必须要有所恩怨,你们两个人,可有恩怨?”那位长老开口询问道。































































































在 Kubernetes 称为容器编排的标准之后,Service Mesh 开始火了起来,但是很多文章讲概念的多,讲技术细节的少,所以专门写一篇文章,来解析 Service Mesh 背后的技术细节。


640?wx_fmt=png

Service Mesh 是 Kubernetes 支撑微服务能力拼图的最后一块


Kubernetes 是一个奇葩所在,它的组件复杂,概念复杂。在没有实施微服务之前,你可能会觉得为什么 Kubernetes 要设计的这么复杂,但是一旦你要实施微服务,你会发现 Kubernetes 中的所有概念,都是有用的。

640?wx_fmt=png

在我们微服务设计的十个要点中,我们会发现 Kubernetes 都能够有相应的组件和概念,提供相应的支持。


其中最后的一块拼图就是服务发现,与熔断限流降级。


众所周知,Kubernetes 的服务发现是通过 Service 来实现的,服务之间的转发是通过 kube-proxy 下发 iptables 规则来实现的。


这个只能实现最基本的服务发现和转发能力,不能满足高并发应用下的高级的服务特性,比较 Spring Cloud 和 Dubbo 有一定的差距,于是 Service Mesh 诞生了。


它期望讲熔断,限流,降级等特性,从应用层,下沉到基础设施层去实现,从而使得 Kubernetes 和容器全面接管微服务。


以 Istio 为例讲述 Service Mesh 中的技术关键点


640?wx_fmt=png

就如 SDN 一样,Service Mesh 将服务请求的转发分为控制面和数据面,因而分析它,也是从数据面先分析转发的能力,然后再分析控制面如何下发命令。今天这篇文章重点讲述两个组件 Envoy 和 Pilot。


一切从 Envoy 开始


我们首先来看,如果没有融入 Service Mesh,Envoy 本身能够做什么事情呢?


Envoy 是一个高性能的 C++ 写的 Proxy 转发器,那 Envoy 如何转发请求呢?需要定一些规则,然后按照这些规则进行转发。


规则可以是静态的,放在配置文件中的,启动的时候加载,要想重新加载,一般需要重新启动,但是 Envoy 支持热加载和热重启,一定程度上缓解了这个问题。


当然最好的方式是规则设置为动态的,放在统一的地方维护,这个统一的地方在 Envoy 眼中看来称为 Discovery Service,过一段时间去这里拿一下配置,就修改了转发策略。

640?wx_fmt=png

无论是静态的,还是动态的,在配置里面往往会配置如上图中的四个东西:

  • Listener,也即 Envoy 既然是 Proxy,专门做转发,就得监听一个端口,接入请求,然后才能够根据策略转发,这个监听的端口称为 Listener。

  • Route,有时候多个 Cluster 具有类似的功能,但是是不同的版本号,可以通过 Route 规则,选择将请求路由到某一个版本号,也即某一个 Cluster。

  • Cluster,一个 Cluster 是具有完全相同行为的多个 Endpoint,也即如果有三个容器在运行,就会有三个 IP 和端口。

    但是部署的是完全相同的三个服务,他们组成一个 Cluster,从 Cluster 到 Endpoint 的过程称为负载均衡,可以轮询等。

  • Endpoint,是目标的 IP 地址和端口,这个是 Proxy 最终将请求转发到的地方。


这四个的静态配置的例子如下:

640?wx_fmt=png

如图所示,Listener 被配置为监听本地 127.0.0.1 的 10000 接口,Route 配置为某个 URL 的前缀转发到哪个 Cluster,Cluster 里面配置负载均衡策略,Hosts 里面是所有的 Endpoint。


如果你想简单的将 Envoy 使用起来,不用什么 Service Mesh,那么一个进程,加上这个配置文件,就可以了,就能够转发请求了。


对于动态配置,也应该配置发现中心,也即 Discovery Service,对于上述四种配置,各对应相应的 DS,所以有 LDS、RDSCDSEDS。


动态配置的例子如下:

640?wx_fmt=png

控制面 Pilot 的工作模式


数据面 Envoy 可以通过加装静态配置文件的方式运行,而动态信息,需要从 Discovery Service 去拿。


Discovery Service 就是部署在控制面的,在 Istio 中,是 Pilot。

640?wx_fmt=png

如上图,为 Pilot 的架构,最下面一层是 Envoy 的 API,就是提供 Discovery Service 的 API。


这个 API 的规则由 Envoy 定,但是不是 Pilot 调用 Envoy,而是 Envoy 去主动调用 Pilot 的这个 API。


Pilot 最上面一层称为 Platform Adapter,这一层是干什么的呢?这一层不是 Kubernetes,Mesos 调用 Pilot,而是 Pilot 通过调用 Kubernetes 来发现服务之间的关系。


这是理解 Istio 比较绕的一个点。也即 Pilot 使用 Kubernetes 的 Service,仅仅使用它的服务发现功能,而不使用它的转发功能。


Pilot 通过在 Kubernetes 里面注册一个 Controller 来监听事件,从而获取 Service 和 Kubernetes 的 Endpoint 以及 Pod 的关系。


但是在转发层面,就不会再使用 kube-proxy 根据 service 下发的 iptables 规则进行转发了,而是将这些映射关系转换成为 Pilot 自己的转发模型,下发到 Envoy 进行转发,Envoy 不会使用 kube-proxy 的那些 iptables 规则。


这样就把控制面和数据面彻底分离开来,服务之间的相互关系是管理面的事情,不要和真正的转发绑定在一起,而是绕到 Pilot 后方。


Pilot 另外一个对外的接口是 Rules API,这是给管理员的接口,管理员通过这个接口设定一些规则,这些规则往往是应用于 Routes、ClustersEndpoints 的。


而都有哪些 Clusters 和 Endpoints,是由 Platform Adapter 这面通过服务发现得到的。


自动发现的这些 Clusters 和 Endpoints,外加管理员设置的规则,形成了 Pilot 的数据模型,其实就是他自己定义的一系列数据结构,然后通过 Envoy API 暴露出去,等待 Envoy 去拉取这些规则。

640?wx_fmt=png

常见的一种人工规则是 Routes,通过服务发现,Pilot 可以从 Kubernetes 那里知道 Service B 有两个版本,一般是两个 Deployment,属于同一个 Service。


管理员通过调用 Pilot 的 Rules API,来设置两个版本之间的 Route 规则,一个占 99% 的流量,另一个占 1% 的流量。


这两方面信息形成 Pilot 的数据结构模型,然后通过 Envoy API 下发,Envoy 就会根据这个规则设置转发策略了。

640?wx_fmt=png

另一个常用的场景就是负载均衡,Pilot 通过 Kubernetes 的 Service 发现 Service B 包含一个 Deployment,但是有三个副本。


于是通过 Envoy API 下发规则,使得 Envoy 在这三个副本之间进行负载均衡,而非通过 Kubernetes 本身 Service 的负载均衡机制。


以 Istio 为例解析 Service Mesh 的技术细节


了解了 Service Mesh 的大概原理,接下来我们通过一个例子来解析其中的技术细节。


凡是试验过 Istio 的同学都应该尝试过下面这个 BookInfo 的例子,不很复杂,但是麻雀虽小五脏俱全。

640?wx_fmt=png

在这个例子中,我们重点关注 ProductPage 这个服务,对 Reviews 服务的调用,这里涉及到路由策略和负载均衡。


Productpage 就是个 Python 程序


Productpage 是一个简单的用 Python 写的提供 Restful API 的程序。

640?wx_fmt=png

在里面定义了很多的 Route,来接收 API 请求,并做相应的操作。


在需要请求其他服务,例如 reviews、ratings 的时候,则需要向后方发起 restful 调用。

640?wx_fmt=png

从代码可以看出,Productpage 对于后端的调用,都是通过域名来的。


对于 Productpage 这个程序来讲,他觉得很简单,通过这个域名就可以调用了,既不需要通过服务发现系统获取这个域名,也不需要关心转发。


更意识不到自己是部署在 Kubernetes 上的,是否用了 Service Mesh,所以服务之间的通信完全交给了基础设施层。


通过 Kubernetes 编排 Productpage


有了 Productpage 程序,接下来就是将它部署到 Kubernetes 上,这里没有什么特殊的,用的就是 Kubernetes 默认的编排文件。

640?wx_fmt=png

首先定义了一个 Deployment,使用 bookinfo 的容器镜像,然后定义一个 Service,用于这个 Deployment 的服务发现。


通过 Kubernetes 编排 Reviews


640?wx_fmt=png

这个稍微有些复杂,定义了三个 Deployment,但是版本号分别为 V1、V2、V3,但是 Label 都是 app:reviews。


最后定义了一个 Service,对应的 Label 是app:reviews,作为这三个 Deployment 的服务发现。


Istioctl 对 Productpage 进行定制化之一:嵌入 proxy_init 作为 InitContainer。


到目前为止,一切正常,接下来就是见证奇迹的时刻,也即 Istio 有个工具 Istioctl 可以对于 Yaml 文件进行定制化。


定制化的第一项就是添加了一个 InitContainer,这种类型的 Container 可以做一些初始化的工作后,成功退出,Kubernetes 不会保持它长期运行。

640?wx_fmt=png

在这个 InitContainer 里面做什么事情呢?


我们登录进去发现,在这个 InitContainer 里面运行了一个 Shell 脚本。

640?wx_fmt=png

就是这个 Shell 脚本在容器里面写入了大量的 iptables 规则。


首先定义的一条规则是 ISTIO_REDIRECT 转发链,这条链不分三七二十一,都将网络包转发给 Envoy 的 15000 端口。


但是一开始这条链没有被挂到 iptables 默认的几条链中,所以不起作用。


接下来就是在 PREROUTING 规则中,使用这个转发链,从而进入容器的所有流量,都被先转发到 Envoy 的 15000 端口。


Envoy 作为一个代理,已经被配置好了,将请求转发给 Productpage 程序。


Productpage 程序接受到请求,会转向调用外部的 reviews 或者 ratings,从上面的分析我们知道,Productpage 只是做普通的域名调用。


当 Productpage 往后端进行调用的时候,就碰到了 output 链,这个链会使用转发链,将所有出容器的请求都转发到 Envoy 的 15000 端口。


这样无论是入口的流量,还是出口的流量,全部用 Envoy 做成了汉堡包。


Envoy 根据服务发现的配置,知道 reviews 或者 ratings 如何访问,于是做最终的对外调用。


这个时候 iptables 规则会对从 Envoy 出去的流量做一个特殊处理,允许它发出去,不再使用上面的 output 规则。


Istioctl 对 Productpage 进行定制化之二:嵌入 Proxy 容器作为 Sidecar。


Istioctl 做的第二项定制化是嵌入 Proxy 容器作为 Sidecar,如下图:

640?wx_fmt=png

这个似乎看起来更加复杂,但是进入容器我们可以看到,启动了两个进程。

640?wx_fmt=png

一个是我们熟悉的 Envoy,它有一个配置文件是 /etc/istio/proxy/envoy-rev0.json。


我们再前面讲述 Envoy 的时候说过,有了配置文件,Envoy 就能够转发了,我们先来看看配置文件里面都有啥。

640?wx_fmt=png

在这里面配置了 Envoy 的管理端口,等一下我们会通过这个端口查看 Envoy 被 Pilot 下发了哪些转发策略。


然后就是动态资源,也即从各种 Discovery Service 去拿转发策略。


还有就是静态资源,也即静态配置的,需要重启才能加载的。

640?wx_fmt=png

这就是 pilot-agent 的作用,它是 Envoy 的一个简单的管理器,因为有些静态资源,如果是 TLS 的证书,Envoy 还不支持动态下发,因而需要重新静态配置,然后 pilot-agent 负责将 Envoy 进行热重启加载。


好在 Envoy 有良好的热重启机制,重启的时候,会先启动一个备用进程,将转发的统计数据通过 Shared Memory 在两个进程间共享。


深入解析 Pilot 的工作机制


640?wx_fmt=png

Pilot 的工作机制展开后如上图所示,istio config 是管理员通过管理接口下发的转发规则。


Service Discovery 模块对于 Kubernetes 来讲,就是创建了一个 Controller 来监听 Service 创建和删除的事件。


当 Service 有变化时,会通知 Pilot,Pilot 会根据变化更新下发给 Envoy 的规则。


Pilot 将管理员输入的转发策略配置和服务发现的当前状态,变成 Pilot 自己的数据结构模型,然后暴露成 Envoy 的 API,由于是 Envoy 来调用,因而要实现一个服务端,这里有 LDS、RDSCDSEDS。


接下来我们看,在 Pilot 上配置 Route 之后会发生什么?

640?wx_fmt=png

如上图,我们将所有的流量都发给版本 1。

640?wx_fmt=png

我们查看 Envoy 的管理端口,可以看到只配置了 Reviews 的 V1。

640?wx_fmt=png

当我们修改路由为 V1 和 V3 比例是五十比五十。

640?wx_fmt=png

可以看到 Envoy 的管理端口,路由有了两个版本的配置,也对应后端的两个 IP 地址。

出处:转载自刘超的通俗云计算微信公众号


640.jpeg

  • 作者:刘超

  • https://mp.weixin.qq.com/s/dWVQZhA2wqeKO-qPv4Waxw

  • 程序员大咖整理发布,转载请联系作者获得授权

640?wx_fmt=gif640?【点击成为源码大神】

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值