1. 程式人生 > 實用技巧 >istio-流量管理-基於不同版本訪問規則控制

istio-流量管理-基於不同版本訪問規則控制

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