4.1.4 示例

下面通过一个简单的示例来了解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 服务的调用的结果