我們都知道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
使用。