ServiceMesh的理念从根本上将分布式框架中的服务注册/发现,服务治理,管理等内容从应用中分离出来,由SideCar来提供分布式框架中数据面的功能,让应用只关注其业务本身,简化了应用开发,其思想类似于SDN,我认为是未来分布式框架演进的方向。本文记录了笔者学习Istio官网文档中Example的过程,有误的地方请指出,本文中的istio环境是基于k8s搭建的,具体如何在k8s集群中搭建istio,请参考官方文档。 首先给出Bookinfo Application的应用架构图,如图所示,用户请求到product page后,product page会去请求Details应用以及Reviews,Reviews应用还会去请求Ratings,其中Reviews分为三个版本,product page会轮询选择一个版本进行访问。
接下来我们对Bookinfo Application进行部署 ,这里我们选择手工注入sideCar的方式来部署: 第一步:部署应用
**istioctl kube-inject -f samples/bookinfo/platform/kube/bookinfo.yaml | kubectl apply -f -**注入成功后,会在k8s的default namespace下生成相应的pod和service,如上面程序调用示意图所示,productpage,ratings,reviews这三个服务之间的调用都是通过service的域名来完成的.
第二步:将productpage通过node port方式映射 首先生成一个bookinfo应用的网关,通过这个网关,集群外部就能访问这个应用的productpage页面了,网关的实现是istio的gateway,其概念类似于k8s中的ingress。生成命令如下: kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml 接下来按照官网的步骤找到网关的地址和端口,就可以访问应用的页面了,测试结果如下面三幅图所示,因Reviews初始的时候会有三个版本,所以每次访问productpage的时候,都会访问到Reviews三个版本中的其中一个版本,他们分别是黑色星星,没有星星和红色的星星。
接下来就可以按照istio官网给的文档来验证它的功能了: 1.Configuring Request Routing(配置请求路由),个人理解这个功能点是控制服务之间的路由,例如我们能够将请求reviews服务的流量都路由到v1版本。
**kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml**配置文件如下: [root@master istio-1.0.2]# cat samples/bookinfo/networking/virtual-service-all-v1.yaml apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: productpage spec: hosts: - productpage http: - route: - destination: host: productpage subset: v1 — apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: reviews spec: hosts: - reviews http: - route: - destination: host: reviews subset: v1 — apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: ratings spec: hosts: - ratings http: - route: - destination: host: ratings subset: v1 — apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: details spec: hosts: - details http: - route: - destination: host: details subset: v1 —
可以看到,我们通过定义了4个virtualService,分别将访问productpage,ratings,reviews,details服务的流量路由到v1版本,通过访问productpage的页面可以看出,无论我们怎么刷新,Reviews部分都没有星星显示出来,因为我们定义了规则,将流量至访问Reviews-v1的版本。 这里我们简单解释下virtualService,virtualService主要用于定义访问某服务请求的路由。 2.Route based on user identity(基于用户身份的路由) 顾名思义,istio提供根据用户的身份将流量路由到指定的版本,当然这里要求应用支持,例如在本例中,productpage服务请求reviews服务的header中就携带了用户身份的信息。我们通过kubectl提交如下yaml文件,可以看到我们定义了一个virtualService,告诉istio,将header中end-user为jason的流量路由到reviews的v2版本。
kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml [root@master istio-1.0.2]# cat samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: reviews spec: hosts: - reviews http: - match: - headers: end-user: exact: jason route: - destination: host: reviews subset: v2 - route: - destination: host: reviews我们登陆到productpage界面,通过jason的账号登陆后,无论如何刷新,我们到看到reviews为黑色的星星.
完成了上述的实验,接下来我们进行下一个任务Fault Injection 3.Fault Injection(错误注入) Istio之所以提供这个功能,是为了让我们能够测试应用服务的弹性和可靠性,通过Istio,我们能够模拟服务之间调用的延时和错误率,首先我们执行如下命令,我们在yaml文件中创建了一个virtualService,告诉istio,将用户为jason的请求路由到reviews的v1版本,并在请求之间加入7秒的延时。
kubectl apply -f samples/bookinfo/networking/virtual-service-ratings-test-delay.yaml [root@master istio-1.0.2]# cat samples/bookinfo/networking/virtual-service-ratings-test-delay.yaml apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: ratings spec: hosts: - ratings http: - match: - headers: end-user: exact: jason fault: delay: percent: 100 fixedDelay: 7s route: - destination: host: ratings subset: v1 - route: - destination: host: ratings subset: v1可以看到,通过jason登陆后,页面在6秒后响应,证明上述规则生效。当然细心的读者可能返现,为什么reviews部分我们得到了错误的信息,那是因为Istio提供的这个案例中,productpage请求reviews服务的时候,在应用内部设置了一个6秒的超时时间,超过6秒后,直接在reviews部分返回错误,当然为了得到正确的结果,我们可以将固定延时时间调到6秒以内,这里我们改成2.8秒。
4.Traffic Shifting(流量转移) 这里istio同样提供了流量转移的方法,例如某个服务有多个版本,我们能够通过 istio将流量按照一定比例丛v1版本迁移到v2版本,甚至到最后将流量完全迁移到v2上面,这样能够帮助我们将流量从旧版本迁移到新的版本上面来。这里我们定义了virtualService,让50%的流量路由到reviews的v1版本,另外50%的流量路由到reviews的v2版本。
kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-50-v3.yaml [root@master istio-1.0.2]# cat samples/bookinfo/networking/virtual-service-reviews-50-v3.yaml apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: reviews spec: hosts: - reviews http: - route: - destination: host: reviews subset: v1 weight: 50 - destination: host: reviews subset: v3 weight: 50这里就不截图了,通过不断刷新productpage页面,并记录我们访问到v1和v3版本的次数,我们可以大致看到页面的访问量趋于1:1。
5.Setting Request Timeouts(设置服务超时时间) Istio也为我们提供了服务调用之间的超时时间,默认为15秒,这里我们将调用reviews-v2版本的超时时间设置成0.5秒,同时将reviews调用ratings的延迟设置为2秒,这样能够保证productpage在调用reviews服务的时候,不能够在0.5秒以内返回,从而达到超时时间的设置要求,设置如下图所示:
cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: reviews spec: hosts: - reviews http: - route: - destination: host: reviews subset: v2 EOF cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: ratings spec: hosts: - ratings http: - fault: delay: percent: 100 fixedDelay: 2s route: - destination: host: ratings subset: v1 EOF cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: reviews spec: hosts: - reviews http: - route: - destination: host: reviews subset: v2 timeout: 0.5s EOF如上图所示,在请求productpage后,reviews部分返回了错误,并且可以观察到响应时间在1秒左右。
以上是本次实验的内容,后续其它的实验请继续关注笔者后续的分享。
