深入解读Service Mesh背后的技术细节 (2)

勿忘初心2018-11-08 12:34

此文已由作者刘超授权网易云社区发布。

欢迎访问网易云社区,了解更多网易技术产品运营经验。


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


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


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



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


Productpage就是个Python程序


productpage是一个简单的用python写的提供restful API的程序。



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


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


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


对于productpage这个程序来讲,他觉得很简单,通过这个域名就可以调用了,既不需要通过服务发现系统获取这个域名,也不需要关心转发,更意识不到自己是部署在kubernetes上的,是否用了service mesh,所以服务之间的通信完全交给了基础设施层。


通过Kubernetes编排productpage


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



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


通过Kubernetes编排reviews



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


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


istioctl对productpage进行定制化之一:嵌入proxy_init作为InitContainer

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


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


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


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



就是这个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。



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



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


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



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


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


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



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


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


深入解析pilot的工作机制




Pilot的工作机制展开后如图所示。


istio config是管理员通过管理接口下发的转发规则。


Service Discovery模块对于Kubernetes来讲,就是创建了一个controller来监听Service创建和删除的事件,当service有变化时,会通知pilot,pilot会根据变化更新下发给envoy的规则。


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


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

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



我们查看envoy的管理端口,可以看到只配置了reviews的v1。


当我们修改路由为v1和v3比例是五十比五十。


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



容器服务是网易云提供的无服务器容器服务,让企业能够快速部署业务,轻松运维服务。容器服务支持弹性伸缩、垂直扩容、灰度升级、服务发现、服务编排、错误恢复及性能监测等功能。点击可免费试用


免费体验云安全(易盾)内容安全、验证码等服务

更多网易技术、产品、运营经验分享请点击