istio(2):流量管理-基于不同版本访问规则控制

istio-流量管理-基于不同版本访问规则控制

https://www.qikqiak.com/istio-book/traffic-control/2.%E5%9F%BA%E4%BA%8EBookinfo%E8%BF%9B%E8%A1%8Cistio%E6%B5%81%E9%87%8F%E7%AE%A1%E7%90%86%E7%9A%84%E9%85%8D%E7%BD%AE%E5%92%8C%E5%BA%94%E7%94%A8%E5%AD%A6%E4%B9%A0.html?q=

 

 

目前搭建 Bookinfo 应用我们只用到了下面两个资源文件:

samples/bookinfo/platform/kube/bookinfo.yaml

samples/bookinfo/networking/bookinfo-gateway.yaml

 

前者就是通常的k8s定义的 Deployment 和 Service 的 yaml 文件,只是在部署时使用istioctl kube-inject对这个文件定义的pod注入了sidecar代理,后者定义了这个应用的外部访问入口gateway,以及应用内部 productpage 服务的VirtualService规则,而其他内部服务的访问规则还没有被定义。

可以看到当前集群中的gateway:

[root@k8s-master ~]# kubectl get gateway --all-namespaces
NAMESPACE   NAME               AGE
default     bookinfo-gateway   2d22h
[root@k8s-master ~]# istioctl get gateway
Command "get" is deprecated, Use `kubectl get` instead (see https://kubernetes.io/docs/tasks/tools/install-kubectl)
GATEWAY NAME       HOSTS     NAMESPACE   AGE
bookinfo-gateway   *         default     2d
[root@k8s-master ~]#

 

 

 

现在访问应用界面并刷新,会看到 Reviews 有时不会显示评分,有时候会显示不同样式的评分,因为后面有3个不同的Reviews 服务版本,而没有配置该服务的路由规则route rule的情况下,该服务的几个实例会被随机访问到,有的版本服务会进一步调用 Ratings 服务,有的不会。

 

不同服务版本访问规则的基本使用

v3版本

现在我们来对 Reviews 服务添加一条路由规则,启用samples/bookinfo/networking/virtual-service-reviews-v3.yaml 定义的VirtualService规则,内容如下:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
    - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v3

 

 

这样,所有访问 reviews 服务的流量就会被引导到 reviews 服务对应的 subset 为 v3 的 Pod 中。启用这条规则:

 

# kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-v3.yaml
The VirtualService "reviews" is invalid: []: Invalid value: map[string]interface {}{"apiVersion":"networking.istio.io/v1alpha3", "kind":"VirtualService", "metadata":map[string]interface {}{"annotations":map[string]interface {}{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"networking.istio.io/v1alpha3\",\"kind\":\"VirtualService\",\"metadata\":{\"annotations\":{},\"name\":\"reviews\",\"namespace\":\"default\"},\"spec\":{\"hosts\":[\"reviews\"],\"http\":[{\"route\":[{\"destination\":{\"host\":\"reviews\",\"subset\":\"v3\"}}],\"weight\":1}]}}\n"}, "creationTimestamp":"2019-11-11T02:31:37Z", "generation":1, "name":"reviews", "namespace":"default", "uid":"6e26b97e-18d9-4c38-87fa-a9f524f3184d"}, "spec":map[string]interface {}{"hosts":[]interface {}{"reviews"}, "http":[]interface {}{map[string]interface {}{"route":[]interface {}{map[string]interface {}{"destination":map[string]interface {}{"host":"reviews", "subset":"v3"}}}, "weight":1}}}}: validation failure list:
spec.http.route.weight in body is required

#我们修改一下
# cat samples/bookinfo/networking/virtual-service-reviews-v3.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
    - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v3
      weight : 1


[root@k8s-master istio-1.3.1]# vim samples/bookinfo/networking/virtual-service-reviews-v3.yaml
[root@k8s-master istio-1.3.1]# kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-v3.yaml
virtualservice.networking.istio.io/reviews created

 

然后查看所有的路由规则:

 

[root@k8s-master istio-1.3.1]# istioctl get virtualservices
Command "get" is deprecated, Use `kubectl get` instead (see https://kubernetes.io/docs/tasks/tools/install-kubectl)
VIRTUAL-SERVICE NAME   GATEWAYS           HOSTS     #HTTP     #TCP      NAMESPACE   AGE
bookinfo               bookinfo-gateway   *             1        0      default     2d
reviews                                   reviews       1        0      default     1m
[root@k8s-master istio-1.3.1]# kubectl get virtualservices
NAME       GATEWAYS             HOSTS       AGE
bookinfo   [bookinfo-gateway]   [*]         2d23h
reviews                         [reviews]   114s
[root@k8s-master istio-1.3.1]#

 

 

可以看到 reviews 的VirtualService已经创建成功了,但是此时刷新应用页面,发现访问 Reviews 失败了:

 

 

 

这是因为我们还没有创建DestinationRuleDestinationRuleVirtualService中指定的subset与 pod 的{labels:{version: v3}}关联起来。

在 samples/bookinfo/networking/destination-rule-all.yaml 文件中有定义所有该应用中要用到的所有DestinationRule,其中有一段就是对 Reviews 相关的 DestinationRule 的定义:

# cat  samples/bookinfo/networking/destination-rule-all.yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: productpage
spec:
  host: productpage
  subsets:
  - name: v1
    labels:
      version: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews
spec:
  host: reviews
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
  - name: v3
    labels:
      version: v3
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: ratings
spec:
  host: ratings
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
  - name: v2-mysql
    labels:
      version: v2-mysql
  - name: v2-mysql-vm
    labels:
      version: v2-mysql-vm
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: details
spec:
  host: details
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
---

 

 

可以看到 DestinationRule 中定义了 subsets 集合,其中 labels 就和我们之前 service 的 labelselector 一样是去匹配 Pod 的 labels 标签的,比如我们这里 subsets 中就包含一个名为 v3 的 subset,而这个 subset 匹配的就是具有 version=v3 这个 label 标签的 Pod 集合,再回到之前的 samples/bookinfo/platform/kube/bookinfo.yaml 文件中,我们可以发现 reviews 的 Deployment 确实有声明不同的 labels->version:

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: reviews-v3
  labels:
    app: reviews
    version: v3
spec:
  replicas: 1
  selector:
    matchLabels:
      app: reviews
      version: v3
  template:
    metadata:
      labels:
        app: reviews
        version: v3
    spec:
      serviceAccountName: bookinfo-reviews
      containers:
      - name: reviews
        image: docker.io/istio/examples-bookinfo-reviews-v3:1.15.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 9080

 

 

通过 DestinationRule 将 VirtualService 与 service 不同的版本关联起来了。

现在我们直接创建 DestinationRule 资源:

# kubectl apply -f   samples/bookinfo/networking/destination-rule-all.yaml
destinationrule.networking.istio.io/productpage created
destinationrule.networking.istio.io/reviews created
destinationrule.networking.istio.io/ratings created
destinationrule.networking.istio.io/details created

 

创建完成后,我们就可以查看目前我们网格中的 DestinationRules:

 

# kubectl get destinationrules.networking.istio.io
NAME          HOST          AGE
details       details       29s
productpage   productpage   29s
ratings       ratings       29s
reviews       reviews       29s

# istioctl get destinationrule
Command "get" is deprecated, Use `kubectl get` instead (see https://kubernetes.io/docs/tasks/tools/install-kubectl)
DESTINATION-RULE NAME   HOST          SUBSETS                      NAMESPACE   AGE
details                 details       v1,v2                        default     2m
productpage             productpage   v1                           default     2m
ratings                 ratings       v1,v2,v2-mysql,v2-mysql-vm   default     2m
reviews                 reviews       v1,v2,v3                     default     2m

 

此时再访问应用就成功了,多次刷新页面发现 Reviews 都展示的是 v3 版本带红色星的 Ratings,说明我们VirtualService 的配置成功了。

 

 

v1版本

首先移除刚刚创建的 VirtualService 对象:

 

[root@k8s-master bookinfo]# kubectl get virtualservices
NAME       GATEWAYS             HOSTS       AGE
bookinfo   [bookinfo-gateway]   [*]         2d23h
reviews                         [reviews]   15m
[root@k8s-master bookinfo]# istioctl delete virtualservice reviews
Command "delete" is deprecated, Use `kubectl delete` instead (see https://kubernetes.io/docs/tasks/tools/install-kubectl)
Deleted config: virtualservice reviews
[root@k8s-master bookinfo]# kubectl get virtualservices
NAME       GATEWAYS             HOSTS   AGE
bookinfo   [bookinfo-gateway]   [*]     2d23h

 

现在我们再去访问 Bookinfo 应用又回到最初随机访问 Reviews 的情况了

 

 

来对 Reviews 服务添加一条路由规则,启用samples/bookinfo/networking/virtual-service-reviews-v1.yaml 定义的VirtualService规则,内容如下:

 

cp samples/bookinfo/networking/virtual-service-reviews-v3.yaml samples/bookinfo/networking/virtual-service-reviews-v1.yaml
# cat samples/bookinfo/networking/virtual-service-reviews-v1.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
    - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v1
      weight : 1

 

 

 

这样,所有访问 reviews 服务的流量就会被引导到 reviews 服务对应的 subset 为 v1的 Pod 中。启用这条规则:

[root@k8s-master istio-1.3.1]# kubectl apply -f  samples/bookinfo/networking/virtual-service-reviews-v1.yaml
virtualservice.networking.istio.io/reviews created
[root@k8s-master istio-1.3.1]# kubectl get virtualservices
NAME       GATEWAYS             HOSTS       AGE
bookinfo   [bookinfo-gateway]   [*]         2d23h
reviews                         [reviews]   3s
[root@k8s-master istio-1.3.1]#

 

DestinationRule不用动

 

此时再访问应用就成功了,多次刷新页面发现 Reviews 都展示的是 v1 版本,没有星星的ratings

 

posted on 2019-11-12 10:24  光阴8023  阅读(557)  评论(0编辑  收藏  举报