istio的 VirtualService 与 DestinationRule 都分别做了什么

我们都知道istio的VirtualServiceDestinationRule,是用来进行流量控制的,但是istio用它们具体做什么事情呢?对envoy产生了那些影响呢?今天我们就以bookinfo的reviews服务探究一下。

首先要先部署好kubernetesistio,并提前安装好bookinfo这个联系项目,按照官方步骤就行了。

Destinationrule

先看下默认的envoy cluster信息

$ istioctl pc cluster productpage-v1-7f44c4d57c-nwncm

reviews.default.svc.cluster.local                            9080      -              outbound      EDS

再看下reviews.default.svc.cluster.localendpoint

$ istioctl pc endpoint productpage-v1-7f44c4d57c-nwncm --cluster "outbound|9080||reviews.default.svc.cluster.local"

ENDPOINT             STATUS      OUTLIER CHECK     CLUSTER
172.17.0.13:9080     HEALTHY     OK                outbound|9080||reviews.default.svc.cluster.local
172.17.0.14:9080     HEALTHY     OK                outbound|9080||reviews.default.svc.cluster.local
172.17.0.15:9080     HEALTHY     OK                outbound|9080||reviews.default.svc.cluster.local

可以看到reviews.default.svc.cluster.local cluster后面挂着三个endpoint,与预期一致

接下来添加reviews的 DestinationRule

$ cat destination-rule-reviews.yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews
spec:
  host: reviews
  trafficPolicy:
    loadBalancer:
      simple: RANDOM
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
  - name: v3
    labels:
      version: v3

$ kubectl apply -f destination-rule-reviews.yaml

再看下cluster 的情况

reviews.default.svc.cluster.local                            9080      -              outbound      EDS
reviews.default.svc.cluster.local                            9080      v1             outbound      EDS
reviews.default.svc.cluster.local                            9080      v2             outbound      EDS
reviews.default.svc.cluster.local                            9080      v3             outbound      EDS

发现在原有的cluster基础上新添加了三个cluster,分别是v1,v2,v3版本
再看下endpoint

172.17.0.13:9080                HEALTHY     OK                outbound|9080|v2|reviews.default.svc.cluster.local
172.17.0.13:9080                HEALTHY     OK                outbound|9080||reviews.default.svc.cluster.local
172.17.0.14:9080                HEALTHY     OK                outbound|9080|v1|reviews.default.svc.cluster.local
172.17.0.14:9080                HEALTHY     OK                outbound|9080||reviews.default.svc.cluster.local
172.17.0.15:9080                HEALTHY     OK                outbound|9080|v3|reviews.default.svc.cluster.local

发现不同的cluster也出现了对应的endpoint
现在可以知道DestinationRule是用来改写cluster的,不同的cluster有响应的endpoint,这样方便route

VirtualService

先查看 9080 的route信息

$ istioctl pc route productpage-v1-7f44c4d57c-nwncm --name 9080 -o json
...
{
                "name": "reviews.default.svc.cluster.local:9080",
                "domains": [
                    "reviews.default.svc.cluster.local",
                    "reviews.default.svc.cluster.local:9080",
                    "reviews",
                    "reviews:9080",
                    "reviews.default.svc.cluster",
                    "reviews.default.svc.cluster:9080",
                    "reviews.default.svc",
                    "reviews.default.svc:9080",
                    "reviews.default",
                    "reviews.default:9080",
                    "10.100.34.243",
                    "10.100.34.243:9080"
                ],
                "routes": [
                    {
                        "name": "default",
                        "match": {
                            "prefix": "/"
                        },
                        "route": {
                            "cluster": "outbound|9080||reviews.default.svc.cluster.local",
                            "timeout": "0s",
                            "retryPolicy": {
                                "retryOn": "connect-failure,refused-stream,unavailable,cancelled,resource-exhausted,retriable-status-codes",
                                "numRetries": 2,
                                "retryHostPredicate": [
                                    {
                                        "name": "envoy.retry_host_predicates.previous_hosts"
                                    }
                                ],
                                "hostSelectionRetryMaxAttempts": "5",
                                "retriableStatusCodes": [
                                    503
                                ]
                            },
                            "maxGrpcTimeout": "0s"
                        },
                        "decorator": {
                            "operation": "reviews.default.svc.cluster.local:9080/*"
                        }
                    }
                ]
            }

...

默认情况下,当访问reviews.default.svc.cluster.local服务时候,会将流量转发到 outbound|9080||reviews.default.svc.cluster.local。从上面可以知道这个cluster后面挂着三个不同版本的endpoint,所以在访问的时候是轮训出现的。
下面设置 virtualService,只允许访问v1版本。

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

$ kubectl apply -f virtual-service-reviews-v1.yaml

在看下route的情况

"routes": [
                    {
                        "match": {
                            "prefix": "/"
                        },
                        "route": {
                            "cluster": "outbound|9080|v1|reviews.default.svc.cluster.local",
                            "timeout": "0s",
                            "retryPolicy": {
                                "retryOn": "connect-failure,refused-stream,unavailable,cancelled,resource-exhausted,retriable-status-codes",
                                "numRetries": 2,
                                "retryHostPredicate": [
                                    {
                                        "name": "envoy.retry_host_predicates.previous_hosts"
                                    }
                                ],
                                "hostSelectionRetryMaxAttempts": "5",
                                "retriableStatusCodes": [
                                    503
                                ]
                            },
                            "maxGrpcTimeout": "0s"
                        },
                        "metadata": {
                            "filterMetadata": {
                                "istio": {
                                    "config": "/apis/networking.istio.io/v1alpha3/namespaces/default/virtual-service/reviews"
                                }
                            }
                        },
                        "decorator": {
                            "operation": "reviews.default.svc.cluster.local:9080/*"
                        }
                    }
                ]
            }

发现流量只会转发到 reviews 的 v1 版本,v1版本的cluster只会有v1的endpoint,所以现在只能访问v1版本的reviews。
再设置权重访问v2,v3版本。

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

再看下route信息

"routes": [
                    {
                        "match": {
                            "prefix": "/"
                        },
                        "route": {
                            "weightedClusters": {
                                "clusters": [
                                    {
                                        "name": "outbound|9080|v2|reviews.default.svc.cluster.local",
                                        "weight": 50
                                    },
                                    {
                                        "name": "outbound|9080|v3|reviews.default.svc.cluster.local",
                                        "weight": 50
                                    }
                                ]
                            },

可以发现envoy会根据权重讲流量转发到v2,v3版本。

总结

至此我们清楚了,VirtualService是用来修改route规则的,这样就可以将流量转发到不同的cluster。而 DestinationRule 会创建不同的clusterroute使用。

posted @ 2020-05-06 17:02  goerzh  阅读(2957)  评论(0编辑  收藏  举报