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 <
如上图所示,在请求productpage后,reviews部分返回了错误,并且可以观察到响应时间在1秒左右。
以上是本次实验的内容,后续其它的实验请继续关注笔者后续的分享。