深度分析:Istio替代Spring Cloud的合理性
一、现有微服务架构
微服务本质上是分布式架构、分布式应用、分布式计算。
分布式计算可以带来的好处有:性能、可靠性、弹性、可扩展性、可用性、稳健性。
而从应用开发者角度看,使用微服务架构必须考虑:断路、服务发现、
客户端负载平衡等组件。也就是说,开发人员需要在应用逻辑中考虑太多的PaaS基础设计相关的内容,所以他们很烦。。。:
现有主流的微服务架构是这样的:
也就是说,通过各种组件拼凑而成,当然,通过现有的模式,搭建实验环境,做Demo展示是完全没问题的,例如此前我做的实验,通过Spring Cloud搭建一个电商:
但老实说,代码比较复杂:
而且这还只是一个实验,如果真的大规模上生产,我相信现有Spring Cloud的复杂度还是非常高的。所以有的客户,只使用了Spring Cloud的某几个组件,而非整套上,这其实是比较明智的。
而架构复杂的原因是:现有微服务模式,需要应用开发人员过多地考虑PaaS基础架构!
二、新一代微服务架构
Istio是新一代微服务架构,这个观点我在去年的文章中已经介绍过了。今天我们看一下这种架构的优势。这个架构的核心观点,就是提供一种:尽量减少开发人员处理其应用程序分布式特性的要求的微服务架构。
如果说目前的微服务架构,只针整个PaaS的第七层,因此开发人员非常累,需要考虑的点很多。而Istio,面向的是PaaS的4-6层。这样,开发人员只需要关注大麦本身即可。
Istio的架构图如下:
Istio分为数据平面和控制平面。
Istio的管理平面有三个核心组件:
Pilot:负责流量管理发现
Mixer负责:访问控制、策略管理、信息收集
Auth:负责认证
Istio的数据平面创建了一个跨平台的服务网格来解决常见的微服务架构问题,如其中包括很多:通信,负载平衡,流量路由,指标,配额,身份验证,速率限制,断路器,超时,自动重试,等等。Istio的数据平面采取sidecars的方式,也就是在一个pod的主容器旁边,增加一个istio的proxy。
我看看一下,在istio模式下,容器的通讯方式。例如Service和ServiceB。ServiceA和ServiceB分别属于两个pod。
我们再看得细一些:
我们查看一个调用istio的应用:
这个pod有两个容器,一个是主应用bookinfo-productpage,一个是istio/proxy。
我们看一下我们如何可以利用Pilot规则控制应用,策略一共有三个:
DestinationPolicy:
●Client-side load-balancing, circuit-breaking
这个策略主要负责应用之间的负载均衡、熔断。
我们看一个设置策略的例子:里面设置了http最大请求连接数等。超出阈值,会触发熔断。
EgressRule
●Enable whitelist access to external (HTTP/S) services
●External access is off by default in Istio
这个策略控制应用访问外部网络,设置白名单的策略。默认是不能访问外部网络的。
RouteRule
●Timeouts, retries, fault injection, http rewriting and redirection
这策略主要设置应用之间通信的路由策略,属于Ingress策略。
我们看一个使用例子,在应用的yaml文件中定义Ingress resource策略:
三、实验验证Istio
使用OCP3.7的环境。先创建项目:
oc new-project istio-system
增加SA权限:
oc adm policy add-scc-to-user anyuid -z istio-ingress-service-account -n istio-system oc adm policy add-scc-to-user anyuid -z istio-grafana-service-account -n istio-system oc adm policy add-scc-to-user anyuid -z istio-prometheus-service-account -n istio-system
oc adm policy add-scc-to-user privileged -z default -n bookinfo
下载istio的包:
curl -L https://git.io/getLatestIstio | sh -
cd istio-0.5.0
export PATH=$PWD/bin:$PATH
安装istio:
kubectl apply -f install/kubernetes/istio.yaml
查看部署的相关istio组件:
截至到目前,istio相关的内容就配好了:
接下来,部署一个应用调用istio,应用的名称叫bookinfo,就是定票信息网站。
这个应用也是一套微服务,有产品描述、评论、评级、详细信息。
不是应用使用一个yaml:samples/bookinfo/kube/bookinfo.yaml,我们看一下这个yaml的主要内容:
我们看一下文件中对详细信息服务的定义:
查看评级服务的定义:
评论服务:
查看产品定义:
yaml文件的最后部分,是调用istio ingress策略的描述:
所以,在istio模式下,对于开发人员而言,不用再过多考虑PaaS基础架构层面的东西。
通过yaml文件部署微服务:
oc adm policy add-scc-to-user privileged -z default -n bookinfo
配置route:
oc expose svcproductpage --name=productpage --path=/productpage--hostname=productpage-bookinfo.example.com
oc expose svc productpage --name=productpage-login --path=/login--hostname=productpage-bookinfo.example.com
接下来,设置ingress路径:
oc get routes productpage -o jsonpath='{.spec.host}'
把Gateway的URL设置成productpage-istio-system.apps.example.com
通过浏览器访问应用:
访问normal user,可以看到用户是json,显示的信息是莎士比亚的作品“错误喜剧”的票据信息,包括预定信息、话剧评论等。
接下来,我们展示如何在线更换路由策略。我们更换的路由策略,实际上就是微服务之间相互调用的策略。
在这个实验中,有多个routes相关的yaml文件。
在没有路由的情况下,页面展示如下(将已有路由删除),里面没有评论相关内容,因为微服务之前的路由被删除了:
创建并使用V1版本的路由:
浏览器访问页面如下(已经出现了评论,但没有出现rating):
创建V3版本的路由:然后将路由在线替换到V3:
重新访问页面(已经可以看到rating的信息):
同样,我们可以设置在多个版本路由之间的访问比率:
然后我们访问页面,在线点击页面刷新:
刷新一次:
再刷新一次(页面回来了):
也就是说,我们可以通过简单的替换路由的方式,改变微服务之间的调用关系。
在Istio中,我们可以部署prometheus、Metrics、Tracing,这些都是istio的addson:
oc apply -f prometheus.yaml
oc expose svc prometheus
oc apply -n istio-system -fhttps://raw.githubusercontent.com/jaegertracing/jaeger-kubernetes/master/all-in-one/jaeger-all-in-one-template.yml
oc expose -nistio-system deployment jaeger-deployment --name=jaeger --port=16686
oc expose svc jaeger
查看产品定义:
yaml文件的最后部分,是调用istio ingress策略的描述:
所以,在istio模式下,对于开发人员而言,不用再过多考虑PaaS基础架构层面的东西。
通过yaml文件部署微服务:
oc adm policy add-scc-to-user privileged -z default -n bookinfo
配置route:
oc expose svcproductpage --name=productpage --path=/productpage--hostname=productpage-bookinfo.example.com
oc expose svc productpage --name=productpage-login --path=/login--hostname=productpage-bookinfo.example.com
接下来,设置ingress路径:
oc get routes productpage -o jsonpath='{.spec.host}'
把Gateway的URL设置成productpage-istio-system.apps.example.com
通过浏览器访问应用:
访问normal user,可以看到用户是json,显示的信息是莎士比亚的作品“错误喜剧”的票据信息,包括预定信息、话剧评论等。
接下来,我们展示如何在线更换路由策略。我们更换的路由策略,实际上就是微服务之间相互调用的策略。
在这个实验中,有多个routes相关的yaml文件。
在没有路由的情况下,页面展示如下(将已有路由删除),里面没有评论相关内容,因为微服务之前的路由被删除了:
创建并使用V1版本的路由:
浏览器访问页面如下(已经出现了评论,但没有出现rating):
创建V3版本的路由:然后将路由在线替换到V3:
重新访问页面(已经可以看到rating的信息):
同样,我们可以设置在多个版本路由之间的访问比率:
然后我们访问页面,在线点击页面刷新:
刷新一次:
再刷新一次(页面回来了):
也就是说,我们可以通过简单的替换路由的方式,改变微服务之间的调用关系。
在Istio中,我们可以部署prometheus、Metrics、Tracing,这些都是istio的addson:
oc apply -f prometheus.yaml
oc expose svc prometheus
oc apply -n istio-system -fhttps://raw.githubusercontent.com/jaegertracing/jaeger-kubernetes/master/all-in-one/jaeger-all-in-one-template.yml
oc expose -nistio-system deployment jaeger-deployment --name=jaeger --port=16686
oc expose svc jaeger
然后可以看到丰富的页面: