下面通过一个简单的示例来了解Istio中的路由控制能力。部署版本v1的服务service1、service2、service3、service4与service5及其Deployment资源,其中service1会调用service2,service2调用service3,以此类推。
注意
执行以下kubectl命令之前,请先创建命名空间servicedependency,并为命名空间servicedependency打上标签istio-injection=enabled。例如可以通过命令kubectl create ns servicedependency来创建命令空间,通过命令kubectl label ns servicedependency istio-injection=enabled设置标签。
下载本书所使用的示例代码之后,切换到目录traffic-sample1可以查看所有相关的代码文件。下面是app.yaml中定义的service1的yaml示例:
apiVersion: v1
kind: Service
metadata:
name: service1
labels:
app: service1
spec:
ports:
- port: 5678
name: http
selector:
app: service1
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: service1-v1
spec:
replicas: 1
template:
metadata:
labels:
app: service1
version: v1
spec:
containers:
- name: service1
image: registry.cn-beijing.aliyuncs.com/istio-samples/mirrorservice:rev-dep-call
imagePullPolicy: Always
env:
- name: myself
value: "service1"
- name: serviceName
value: "service2.servicedependency"
ports:
- containerPort: 5678
---
部署版本v2的服务service1~5对应的Deployment资源,从下面的service1的yaml示例(可参见app-v2.yaml)可以看出,通过标签version:v2来指定的当前服务的版本:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: service1-v2
spec:
replicas: 1
template:
metadata:
labels:
app: service1
version: v2
spec:
containers:
- name: service1
image: registry.cn-beijing.aliyuncs.com/istio-samples/mirrorservice:rev-dep-call
imagePullPolicy: Always
env:
- name: myself
value: "service1"
- name: serviceName
value: "service2.servicedependency"
ports:
- containerPort: 5678
---
DestinationRule定义的策略决定了经过路由处理之后的流量的访问策略。具体定义可以参见文件destinationrule.yaml,内容摘录如下:
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: service1
spec:
host: service1
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: service2
spec:
host: service2
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: service3
spec:
host: service3
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: service4
spec:
host: service4
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: service5
spec:
host: service5
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
---
VirtualService定义了一系列针对指定服务的流量路由规则。每个路由规则都针对特定协议的匹配规则。如果流量符合这些特征,就会根据规则发送到服务注册表中的目标服务(或者目标服务的子集或版本)。具体定义可参见文件virtualservice-v1.yaml,内容摘录如下:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: service1
spec:
hosts:
- service1
http:
- route:
- destination:
host: service1
subset: v1
weight: 100
- destination:
host: service1
subset: v2
weight: 0
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: service2
spec:
hosts:
- service2
http:
- route:
- destination:
host: service2
subset: v1
weight: 100
- destination:
host: service2
subset: v2
weight: 0
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: service3
spec:
hosts:
- service3
http:
- route:
- destination:
host: service3
subset: v1
weight: 100
- destination:
host: service3
subset: v2
weight: 0
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: service4
spec:
hosts:
- service4
http:
- route:
- destination:
host: service4
subset: v1
weight: 100
- destination:
host: service4
subset: v2
weight: 0
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: service5
spec:
hosts:
- service5
http:
- route:
- destination:
host: service5
subset: v1
weight: 100
- destination:
host: service5
subset: v2
weight: 0
---
创建命名空间servicedependency之后,执行以下命令:
kubectl apply -n servicedependency -f app.yaml kubectl apply -n servicedependency -f app-v2.yaml kubectl apply -n servicedependency -f virtualservice-v1.yaml
启动测试程序:
kubectl apply -n servicedependency -f sleep.yaml
kubectl exec -it $(kubectl get pod -l app=sleep -n servicedependency -o jsonpath=
{.items..metadata.name}) -c sleep -n servicedependency sh
添加如下脚本到test.sh文件:
for i in `seq 1000` do curl -I http://service1.servicedependency:5678; sleep 1; done;
设置为执行模式,并执行测试:
chmod +x test.sh ./test.sh
打开Kiali控制台UI可以看到如图4-6所示的效果。

图4-6 Kiali控制台UI
通过修改权重比例,使得流量切换到版本v2:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: service1
spec:
hosts:
- service1
http:
- route:
- destination:
host: service1
subset: v1
weight: 0
- destination:
host: service1
subset: v2
weight: 100
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: service2
spec:
hosts:
- service2
http:
- route:
- destination:
host: service2
subset: v1
weight: 0
- destination:
host: service2
subset: v2
weight: 100
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: service3
spec:
hosts:
- service3
http:
- route:
- destination:
host: service3
subset: v1
weight: 0
- destination:
host: service3
subset: v2
weight: 100
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: service4
spec:
hosts:
- service4
http:
- route:
- destination:
host: service4
subset: v1
weight: 0
- destination:
host: service4
subset: v2
weight: 100
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: service5
spec:
hosts:
- service5
http:
- route:
- destination:
host: service5
subset: v1
weight: 0
- destination:
host: service5
subset: v2
weight: 100
---
执行上述版本v2的VirtualService,启用版本v2的服务:
kubectl apply -n servicedependency -f virtualservice-v2.yaml
此时,从Kiali控制台UI上可以看到服务的调用从v1切换到了v2,如图4-7所示。

图4-7 服务的调用的结果