我们都知道istio的VirtualService
和DestinationRule
,是用来进行流量控制的,但是istio
用它们具体做什么事情呢?对envoy
产生了那些影响呢?今天我们就以bookinfo的reviews服务探究一下。
首先要先部署好kubernetes
与istio
,并提前安装好bookinfo
这个联系项目,按照官方步骤就行了。
Destinationrule
先看下默认的envoy
cluster
信息
$ istioctl pc cluster productpage-v1-7f44c4d57c-nwncm
reviews.default.svc.cluster.local 9080 - outbound EDS
再看下reviews.default.svc.cluster.local
的 endpoint
$ 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
会创建不同的cluster
供route
使用。