Istio Bookinfo

Posted by hujin on April 15, 2022

架构图

在k8s中通过deployment安装一些微服务并通过service暴露出来,包括

  • productpage: python编写,服务主界面,或者叫index页面,页面中会访问其他微服务
  • reviews: java编写,书籍评价微服务
  • details: ruby编写,书籍详情信息微服务
  • ratings: nodejs编写,数据推荐指数微服务,rating service的后端pod有三个,分别对应三个version

部署

部署原始应用(deployment/service等)

1
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml

查看安装结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@controller01 ~]# kubectl get svc
NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
details       ClusterIP   10.96.192.251   <none>        9080/TCP   87s
kubernetes    ClusterIP   10.96.0.1       <none>        443/TCP    119d
productpage   ClusterIP   10.96.93.53     <none>        9080/TCP   86s
ratings       ClusterIP   10.96.137.195   <none>        9080/TCP   87s
reviews       ClusterIP   10.96.146.191   <none>        9080/TCP   86s

[root@controller01 ~]# kubectl get pods -owide
NAME                              READY   STATUS    RESTARTS   AGE   IP               NODE           NOMINATED NODE   READINESS GATES
details-v1-66b6955995-n4rwz       2/2     Running   0          92s   10.244.114.172   controller01   <none>           <none>
productpage-v1-5d9b4c9849-mjrcf   2/2     Running   0          91s   10.244.114.141   controller01   <none>           <none>
ratings-v1-fd78f799f-ckf66        2/2     Running   0          92s   10.244.114.187   controller01   <none>           <none>
reviews-v1-6549ddccc5-gtstf       2/2     Running   0          92s   10.244.114.175   controller01   <none>           <none>
reviews-v2-76c4865449-sz5dr       2/2     Running   0          92s   10.244.114.188   controller01   <none>           <none>
reviews-v3-6b554c875-jdpn6        2/2     Running   0          92s   10.244.114.143   controller01   <none>           <none>

此时服务可以通过k8s原生的service访问成功,且rating service有三个后端pod,所以平均切换

修改productpage service类型,改成nodeport(之前是clusterip)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
kubectl edit svc productpage
apiVersion: v1
kind: Service
metadata:
  labels:
    app: productpage
    service: productpage
  name: productpage
spec:
  clusterIP: 112.96.53.21
  clusterIPs:
  - 112.96.53.21
  ports:
  - name: http
    nodePort: 30607
    port: 9080
    protocol: TCP
    targetPort: 9080
  selector:
    app: productpage
  type: NodePort

通过http://[管理IP]:[svc-nodeport]/productpage来访问productpage服务

上面演示的是原生k8s的service功能,通过管理IP和nodeport的方式访问productpage服务,下面我们将通过istio的方式来访问微服务

启用istio 注入功能

允许default namespace自动注入istio sidecar

1
kubectl label namespace default istio-injection=enabled

重新部署所有微服务,注入istio sidecar

1
2
kubectl delete -f samples/bookinfo/platform/kube/bookinfo.yaml
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml

创建gateway

这里创建gateway,保证流量可以进入ingressgateway,并进行转发

1
2
3
4
5
6
7
8
[root@controller01 ~]# kubectl apply -f istio-1.11.2/samples/bookinfo/networking/bookinfo-gateway.yaml 
gateway.networking.istio.io/bookinfo-gateway created
virtualservice.networking.istio.io/bookinfo created


[root@controller01 ~]# kubectl get gateway
NAME               AGE
bookinfo-gateway   109s

获取Istio Ingress Gateway的外部端口:

注意这里的31460 nodeport,需要通过这个访问bookinfo入口服务

1
2
3
[root@controller01 ~]# kubectl get svc -n istio-system |grep gateway
istio-egressgateway    ClusterIP      10.96.188.75    <none>        80/TCP,443/TCP                                                               4m8s
istio-ingressgateway   LoadBalancer   10.96.156.24    <pending>     15021:31717/TCP,80:31460/TCP,443:30052/TCP,31400:32767/TCP,15443:30069/TCP   4m8s

创建destination rules, 配置路由访问规则:

1
2
3
4
5
6
7
8
kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml

[root@nested-istio-node1 networking]# kubectl get destinationrule 
NAME          HOST          AGE
details       details       15h
productpage   productpage   15h
ratings       ratings       15h
reviews       reviews       15h

此时bookinfo的virtualservice只是将流量转发到productpage这个destination v1上,其他destination只是创建,未被引用

此时访问页面,页面中review微服务还是会三个版本平均切换的

智能路由

根据版本路由

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml

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
---

这里创建了几个service,并将流量都转发到各自的v1 destinationrule上(demo中只有rating有多版本),访问服务,发现不管怎么刷页面,都看不到星星,因为v1版本没星星

根据用户路由

在vs中定义转发规则,如果发现header中有个jason用户信息,转发到v2,否则转发到v1后端pod

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
kubectl delete -f samples/bookinfo/networking/virtual-service-all-v1.yaml
kubectl apply -f 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
        subset: v1

再次访问,用jason用户登录就能看到黑星星,而其它方式看到的页面都是无星星

故障注入

注入错误让jason用户有个7s的延迟:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-delay.yaml

cat samples/bookinfo/networking/virtual-service-reviews-test-delay.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
  - reviews
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    fault:
      delay:
        percentage:
          value: 100.0
        fixedDelay: 7s
    route:
    - destination:
        host: reviews
        subset: v2
  - route:
    - destination:
        host: reviews
        subset: v3

使用jason用户访问页面会有7s延迟,其他用户则转发到v3版本的reviews

链路切换

把100%流量切到v1

1
kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml

页面不论刷几遍,都没有星星

v1 v3各50%流量

1
kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-50-v3.yaml

刷新页面, 一会有红星,一会没星,50%的概率

把100%流量切到v3

1
kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-v3.yaml

刷新页面,我们看到的都是红心了