istio-流量管理-基於不同版本訪問規則控制
istio-流量管理-基於不同版本訪問規則控制
目前搭建 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 失敗了:
這是因為我們還沒有建立DestinationRule
,DestinationRule
將VirtualService
中指定的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