istio学习笔记之多VirtualService绑定同一Gateway端口实践

1.虚拟主机域名匹配

路由匹配时将请求报文中的host标头值与此处列表项进行匹配检测

1.1 方案设计

1.1.1 gateway设定

(1)gateway单独部署在一个namespace中,其他不同namespace的vs均绑定到这一个gateway上

(2)gateway使用HTTP协议

(3)gateway端口使用80

(4)gateway的限制域为’*'(即不限制)

1.1.2 VirtualService设定

(1)分别位于两个namespace中

(2)分别限制spec.hosts,通过限制域来进行域匹配

(3)spec.http.route.destination.host尽量使用FQDN(全限定域名)

(4)绑定方式使用namespace/gateway,跨namespace绑定

1.1.3服务设定

(1)本实验采用同一个服务,请求服务接口返回该pod的子网IP,以此区分流量走向

(2)deployment的spec.replicas设置为1

(3)deployment+service与VirtualService对应部署在相同namespace

1.2 部署

1.2.1 部署服务

cat demo-java.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: demo-java
  labels:
    istio-injection: enabled
---
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
  labels:
    app: demo-java
  name: demo-java
  namespace: java-demo-devops
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: demo-java
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: demo-java
    spec:
      containers:
      - image: 192.168.8.39:9090/demo/demo:SNAPSHOT-master-34
        imagePullPolicy: IfNotPresent
        name: java-demo
        ports:
        - containerPort: 8080
          protocol: TCP
        resources: {
    
    }
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {
    
    }
      terminationGracePeriodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: demo-java
    version: v1
  name: demo-java
  namespace: java-demo-devops
spec:
  ports:
  - name: http
    port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    app: demo-java
  sessionAffinity: None
  type: ClusterIP
---
apiVersion: v1
kind: Namespace
metadata:
  name: demo
  labels:
    istio-injection: enabled  
---
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
  labels:
    app: demo-java
  name: demo-java
  namespace: demo
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: demo-java
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: demo-java
    spec:
      containers:
      - image: 192.168.8.39:9090/demo/demo:SNAPSHOT-master-34
        imagePullPolicy: IfNotPresent
        name: java-demo
        ports:
        - containerPort: 8080
          protocol: TCP
        resources: {
    
    }
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {
    
    }
      terminationGracePeriodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: demo-java
    version: v1
  name: demo-java
  namespace: demo
spec:
  ports:
  - name: http
    port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    app: demo-java
  sessionAffinity: None
  type: ClusterIP
kubectl apply -f demo-java.yaml
#查看
[root@master istio-demo]# kubectl get all -n demo
NAME                             READY   STATUS    RESTARTS   AGE
pod/demo-java-6bbd4bd86f-hh74k   2/2     Running   0          21h

NAME                TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
service/demo-java   ClusterIP   10.1.79.232   <none>        8080/TCP   7d20h

NAME                        READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/demo-java   1/1     1            1           7d20h

NAME                                   DESIRED   CURRENT   READY   AGE
replicaset.apps/demo-java-6bbd4bd86f   1         1         1       7d20h
[root@master istio-demo]# kubectl get all -n java-demo-devops 
NAME                                    READY   STATUS        RESTARTS   AGE
pod/demo-java-6bbd4bd86f-2cbtg          2/2     Running       0          20h
NAME                     TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
service/demo-java        ClusterIP   10.1.100.157   <none>        8080/TCP         20h

NAME                        READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/demo-java   1/1     1            1           20h

NAME                                   DESIRED   CURRENT   READY   AGE
replicaset.apps/demo-java-6bbd4bd86f   1         1         1       20h
[root@master istio-demo]# 

#查看pod的IP
[root@master istio-demo]# kubectl get endpoints -n demo 
NAME        ENDPOINTS             AGE
demo-java   10.244.166.145:8080   7d20h
[root@master istio-demo]# kubectl get endpoints -n java-demo-devops 
NAME        ENDPOINTS             AGE
demo-java   10.244.166.146:8080   20h
[root@master istio-demo]# 

1.2.2 部署gateway

cat gateway-80.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: istio-gateway
---
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: gateway-80
  namespace: istio-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - hosts:
    - '*'
    port:
      name: http
      number: 80
      protocol: HTTP
kubectl apply -f  gateway-80.yaml
#查看
[root@master istio-demo]# kubectl get gateways.networking.istio.io -n istio-gateway 
NAME         AGE
gateway-80   28h
[root@master istio-demo]#

1.2.3 部署virtual service

cat vs-demo-java.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: demo-java
  namespace: demo
spec:
  hosts:
  - 'test.wangjb.com'  #限制访问域
  gateways:
  - istio-gateway/gateway-80
  http:
  - route:
    - destination:
        host: demo-java.demo.svc.cluster.local  #FQDN
        port: 
          number: 8080
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: demo-java
  namespace: java-demo-devops
spec:
  hosts:
  - 'test2.wangjb.com'   #限制访问域
  gateways:
  - istio-gateway/gateway-80
  http:
  - route:
    - destination:
        host: demo-java.java-demo-devops.svc.cluster.local   #FQDN
        port: 
          number: 8080
kubectl apply -f vs-demo-java.yaml

#查看
[root@master istio-demo]# kubectl get vs -n demo 
NAME        GATEWAYS                       HOSTS                 AGE
demo-java   ["istio-gateway/gateway-80"]   ["test.wangjb.com"]   22h
[root@master istio-demo]# kubectl get vs -n java-demo-devops 
NAME        GATEWAYS                       HOSTS                  AGE
demo-java   ["istio-gateway/gateway-80"]   ["test2.wangjb.com"]   21h
[root@master istio-demo]#

1.3 访问验证

1.3.1 配置域名

首先配置一下域名,因为我们是本地验证,所以就没必要去配置DNS了,直接改一下hosts文件即可
在这里插入图片描述

1.3.2 查看istio-ingressgateway映射端口

80端口是istio-ingressgateway默认映射的端口(当然我们也可以自己修改),查看一下映射

[root@master istio-demo]# kubectl get svc -n istio-system istio-ingressgateway 
NAME                   TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)                                                                     AGE
istio-ingressgateway   LoadBalancer   10.1.39.203   <pending>     15021:30326/TCP,80:31080/TCP,443:31443/TCP,20001:32001/TCP,8800:32080/TCP   11d

获取80端口映射为31080

1.3.3 请求服务接口

1.3.3.1 IP请求

预料之中的404
在这里插入图片描述

1.3.3.2 test.wangjb.com

在这里插入图片描述
在这里插入图片描述

1.3.3.3 test2.wangjb.com

在这里插入图片描述
在这里插入图片描述

1.3.4 分析

从1.3.3的验证我们可以看到,预期与结果相吻合,我们再来看一下istio的路由策略,进一步验证我们的猜想

1.3.4.1 获取路由配置名称

因为我们的服务端口是8080,所以我们可以通过如下方式来获取路由配置名称

[root@master istio-demo]# istioctl -n istio-system pc listeners istio-ingressgateway-6fd6665c9c-nm22r --port 8080 -o json
[
    {
    
    
        "name": "0.0.0.0_8080",
        "address": {
    
    
            "socketAddress": {
    
    
                "address": "0.0.0.0",
                "portValue": 8080
            }
        },
        "filterChains": [
            {
    
    
                "filters": [
                    {
    
    
                        "name": "envoy.filters.network.http_connection_manager",
                        "typedConfig": {
    
    
                            "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager",
                            "statPrefix": "outbound_0.0.0.0_8080",
                            "rds": {
    
    
                                "configSource": {
    
    
                                    "ads": {
    
    },
                                    "initialFetchTimeout": "0s",
                                    "resourceApiVersion": "V3"
                                },
                                "routeConfigName": "http.8080"
                            },
                            "httpFilters": [
                                {
    
    
                                    "name": "istio.metadata_exchange",
                                    "typedConfig": {
    
    
                                        "@type": "type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm",
                                        "config": {
    
    
                                            "vmConfig": {
    
    
                                                "runtime": "envoy.wasm.runtime.null",
                                                "code": {
    
    
                                                    "local": {
    
    
                                                        "inlineString": "envoy.wasm.metadata_exchange"
                                                    }
                                                }
                                            },
                                            "configuration": {
    
    
                                                "@type": "type.googleapis.com/envoy.tcp.metadataexchange.config.MetadataExchange"
                                            }
                                        }
                                    }
                                },
                                {
    
    
                                    "name": "istio.alpn",
                                    "typedConfig": {
    
    
                                        "@type": "type.googleapis.com/istio.envoy.config.filter.http.alpn.v2alpha1.FilterConfig",
                                        "alpnOverride": [
                                            {
    
    
                                                "alpnOverride": [
                                                    "istio-http/1.0",
                                                    "istio",
                                                    "http/1.0"
                                                ]
                                            },
                                            {
    
    
                                                "upstreamProtocol": "HTTP11",
                                                "alpnOverride": [
                                                    "istio-http/1.1",
                                                    "istio",
                                                    "http/1.1"
                                                ]
                                            },
                                            {
    
    
                                                "upstreamProtocol": "HTTP2",
                                                "alpnOverride": [
                                                    "istio-h2",
                                                    "istio",
                                                    "h2"
                                                ]
                                            }
                                        ]
                                    }
                                },
                                {
    
    
                                    "name": "envoy.filters.http.fault",
                                    "typedConfig": {
    
    
                                        "@type": "type.googleapis.com/envoy.extensions.filters.http.fault.v3.HTTPFault"
                                    }
                                },
                                {
    
    
                                    "name": "envoy.filters.http.cors",
                                    "typedConfig": {
    
    
                                        "@type": "type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors"
                                    }
                                },
                                {
    
    
                                    "name": "istio.stats",
                                    "typedConfig": {
    
    
                                        "@type": "type.googleapis.com/udpa.type.v1.TypedStruct",
                                        "typeUrl": "type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm",
                                        "value": {
    
    
                                            "config": {
    
    
                                                "configuration": {
    
    
                                                    "@type": "type.googleapis.com/google.protobuf.StringValue",
                                                    "value": "{\n  \"debug\": \"false\",\n  \"stat_prefix\": \"istio\",\n  \"disable_host_header_fallback\": true\n}\n"
                                                },
                                                "root_id": "stats_outbound",
                                                "vm_config": {
    
    
                                                    "code": {
    
    
                                                        "local": {
    
    
                                                            "inline_string": "envoy.wasm.stats"
                                                        }
                                                    },
                                                    "runtime": "envoy.wasm.runtime.null",
                                                    "vm_id": "stats_outbound"
                                                }
                                            }
                                        }
                                    }
                                },
                                {
    
    
                                    "name": "envoy.filters.http.router",
                                    "typedConfig": {
    
    
                                        "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router"
                                    }
                                }
                            ],
                            "tracing": {
    
    
                                "clientSampling": {
    
    
                                    "value": 100
                                },
                                "randomSampling": {
    
    
                                    "value": 1
                                },
                                "overallSampling": {
    
    
                                    "value": 100
                                },
                                "customTags": [
                                    {
    
    
                                        "tag": "istio.authorization.dry_run.allow_policy.name",
                                        "metadata": {
    
    
                                            "kind": {
    
    
                                                "request": {
    
    }
                                            },
                                            "metadataKey": {
    
    
                                                "key": "envoy.filters.http.rbac",
                                                "path": [
                                                    {
    
    
                                                        "key": "istio_dry_run_allow_shadow_effective_policy_id"
                                                    }
                                                ]
                                            }
                                        }
                                    },
                                    {
    
    
                                        "tag": "istio.authorization.dry_run.allow_policy.result",
                                        "metadata": {
    
    
                                            "kind": {
    
    
                                                "request": {
    
    }
                                            },
                                            "metadataKey": {
    
    
                                                "key": "envoy.filters.http.rbac",
                                                "path": [
                                                    {
    
    
                                                        "key": "istio_dry_run_allow_shadow_engine_result"
                                                    }
                                                ]
                                            }
                                        }
                                    },
                                    {
    
    
                                        "tag": "istio.authorization.dry_run.deny_policy.name",
                                        "metadata": {
    
    
                                            "kind": {
    
    
                                                "request": {
    
    }
                                            },
                                            "metadataKey": {
    
    
                                                "key": "envoy.filters.http.rbac",
                                                "path": [
                                                    {
    
    
                                                        "key": "istio_dry_run_deny_shadow_effective_policy_id"
                                                    }
                                                ]
                                            }
                                        }
                                    },
                                    {
    
    
                                        "tag": "istio.authorization.dry_run.deny_policy.result",
                                        "metadata": {
    
    
                                            "kind": {
    
    
                                                "request": {
    
    }
                                            },
                                            "metadataKey": {
    
    
                                                "key": "envoy.filters.http.rbac",
                                                "path": [
                                                    {
    
    
                                                        "key": "istio_dry_run_deny_shadow_engine_result"
                                                    }
                                                ]
                                            }
                                        }
                                    },
                                    {
    
    
                                        "tag": "istio.canonical_revision",
                                        "literal": {
    
    
                                            "value": "latest"
                                        }
                                    },
                                    {
    
    
                                        "tag": "istio.canonical_service",
                                        "literal": {
    
    
                                            "value": "istio-ingressgateway"
                                        }
                                    },
                                    {
    
    
                                        "tag": "istio.mesh_id",
                                        "literal": {
    
    
                                            "value": "cluster.local"
                                        }
                                    },
                                    {
    
    
                                        "tag": "istio.namespace",
                                        "literal": {
    
    
                                            "value": "istio-system"
                                        }
                                    }
                                ]
                            },
                            "httpProtocolOptions": {
    
    },
                            "serverName": "istio-envoy",
                            "streamIdleTimeout": "0s",
                            "useRemoteAddress": true,
                            "forwardClientCertDetails": "SANITIZE_SET",
                            "setCurrentClientCertDetails": {
    
    
                                "subject": true,
                                "cert": true,
                                "dns": true,
                                "uri": true
                            },
                            "upgradeConfigs": [
                                {
    
    
                                    "upgradeType": "websocket"
                                }
                            ],
                            "normalizePath": true,
                            "pathWithEscapedSlashesAction": "KEEP_UNCHANGED",
                            "requestIdExtension": {
    
    
                                "typedConfig": {
    
    
                                    "@type": "type.googleapis.com/envoy.extensions.request_id.uuid.v3.UuidRequestIdConfig",
                                    "useRequestIdForTraceSampling": true
                                }
                            }
                        }
                    }
                ]
            }
        ],
        "trafficDirection": "OUTBOUND"
    }
]

可以从中得到"routeConfigName": “http.8080”

我们再根据http.8080去获取路由信息

1.3.4.2 获取路由配置
[root@master istio-demo]# istioctl -n istio-system pc routes istio-ingressgateway-6fd6665c9c-nm22r --name http.8080 -o json
[
    {
    
    
        "name": "http.8080",
        "virtualHosts": [
            {
    
    
                "name": "test.wangjb.com:80",
                "domains": [
                    "test.wangjb.com"
                ],
                "routes": [
                    {
    
    
                        "match": {
    
    
                            "prefix": "/"
                        },
                        "route": {
    
    
                            "cluster": "outbound|8080||demo-java.demo.svc.cluster.local",
                            "timeout": "0s",
                            "retryPolicy": {
    
    
                                "retryOn": "connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes",
                                "numRetries": 2,
                                "retryHostPredicate": [
                                    {
    
    
                                        "name": "envoy.retry_host_predicates.previous_hosts",
                                        "typedConfig": {
    
    
                                            "@type": "type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicate"
                                        }
                                    }
                                ],
                                "hostSelectionRetryMaxAttempts": "5",
                                "retriableStatusCodes": [
                                    503
                                ]
                            },
                            "maxStreamDuration": {
    
    
                                "maxStreamDuration": "0s",
                                "grpcTimeoutHeaderMax": "0s"
                            }
                        },
                        "metadata": {
    
    
                            "filterMetadata": {
    
    
                                "istio": {
    
    
                                    "config": "/apis/networking.istio.io/v1alpha3/namespaces/demo/virtual-service/demo-java"
                                }
                            }
                        },
                        "decorator": {
    
    
                            "operation": "demo-java.demo.svc.cluster.local:8080/*"
                        }
                    }
                ],
                "includeRequestAttemptCount": true
            },
            {
    
    
                "name": "test2.wangjb.com:80",
                "domains": [
                    "test2.wangjb.com"
                ],
                "routes": [
                    {
    
    
                        "match": {
    
    
                            "prefix": "/"
                        },
                        "route": {
    
    
                            "cluster": "outbound|8080||demo-java.java-demo-devops.svc.cluster.local",
                            "timeout": "0s",
                            "retryPolicy": {
    
    
                                "retryOn": "connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes",
                                "numRetries": 2,
                                "retryHostPredicate": [
                                    {
    
    
                                        "name": "envoy.retry_host_predicates.previous_hosts",
                                        "typedConfig": {
    
    
                                            "@type": "type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicate"
                                        }
                                    }
                                ],
                                "hostSelectionRetryMaxAttempts": "5",
                                "retriableStatusCodes": [
                                    503
                                ]
                            },
                            "maxStreamDuration": {
    
    
                                "maxStreamDuration": "0s",
                                "grpcTimeoutHeaderMax": "0s"
                            }
                        },
                        "metadata": {
    
    
                            "filterMetadata": {
    
    
                                "istio": {
    
    
                                    "config": "/apis/networking.istio.io/v1alpha3/namespaces/java-demo-devops/virtual-service/demo-java"
                                }
                            }
                        },
                        "decorator": {
    
    
                            "operation": "demo-java.java-demo-devops.svc.cluster.local:8080/*"
                        }
                    }
                ],
                "includeRequestAttemptCount": true
            }
        ],
        "validateClusters": false,
        "ignorePortInHostMatching": true
    }
]

可以看到virtualHosts有两个配置,分别是test.wangjb.com:80test2.wangjb.com:80,对应的domains分别为test.wangjb.comtest2.wangjb.com

route对应关系为

test.wangjb.com:80 —— outbound|8080||demo-java.demo.svc.cluster.local

test2.wangjb.com:80 —— outbound|8080||demo-java.java-demo-devops.svc.cluster.local

知识补充:

istioctl pc(istioctl proxy-config):检索代理配置信息

例如,使用如下方式可以检索特定pod中的Envoy实例的集群配置信息。

$ istioctl proxy-config cluster [flags]

使用如下方式可以检索特定pod中的Envoy实例的bootstrap配置信息。

$ istioctl proxy-config bootstrap [flags]

使用如下方式可以检索特定pod中的Envoy实例的listener(监听器)配置信息。

$ istioctl proxy-config listener [flags]

使用如下方式可以检索特定pod中的Envoy实例的route(路由)配置信息。

$ istioctl proxy-config route [flags]

使用如下方式可以检索特定pod中的Envoy实例的endpoint (后端)配置信息。

$ istioctl proxy-config endpoints [flags]

2.http.match路由匹配

2.1 方案设计

2.1.1 gateway设定

(1)gateway单独部署在一个namespace中,其他不同namespace的vs均绑定到这一个gateway上

(2)gateway使用HTTP协议

(3)gateway端口使用80

(4)gateway的限制域为’*'(即不限制)

2.1.2 VirtualService设定

(1)分别位于两个namespace中

(2)spec.hosts为"*",即不限制访问host

(3)两个服务分别设置不同的.spec.http.match,服务A为.spec.http.match.uri={ {“prefix”: “/systemInfo01/”}},服务B为.spec.http.match.uri={ {“prefix”: “/systemInfo02/”}}

(4)spec.http.route.destination.host尽量使用FQDN(全限定域名)

(5)绑定方式使用namespace/gateway,跨namespace绑定

2.1.3服务设定

(1)本实验采用同一个服务,请求服务接口返回该pod的子网IP,以此区分流量走向

(2)deployment的spec.replicas设置为1

(3)deployment+service与VirtualService对应部署在相同namespace

2.2 部署

2.2.1 部署服务

同1.2.1不变

2.2.2 部署gateway

同1.2.2不变

2.2.3 部署virtual service

cat vs-demo-java.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: demo-java
  namespace: demo
spec:
  hosts:
  - '*'
  gateways:
  - istio-gateway/gateway-80
  http:
  - match:
    - uri:
        prefix: /systemInfo01/
    route:
    - destination:
        host: demo-java.demo.svc.cluster.local
        port: 
          number: 8080

---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: demo-java
  namespace: java-demo-devops
spec:
  hosts:
  - '*'
  gateways:
  - istio-gateway/gateway-80
  http:
  - match:
    - uri:
        prefix: /systemInfo02/
    route:
    - destination:
        host: demo-java.java-demo-devops.svc.cluster.local
        port: 
          number: 8080
kubectl apply -f vs-demo-java.yaml

#查看
[root@master istio-demo]# kubectl get vs -n demo
NAME        GATEWAYS                       HOSTS   AGE
demo-java   ["istio-gateway/gateway-80"]   ["*"]   69m
[root@master istio-demo]# kubectl get vs -n java-demo-devops 
NAME        GATEWAYS                       HOSTS   AGE
demo-java   ["istio-gateway/gateway-80"]   ["*"]   72m
[root@master istio-demo]# 

2.3 访问验证

2.3.1 请求服务接口

2.3.1.1 请求/systemInfo01/hostInfo

在这里插入图片描述
在这里插入图片描述

2.3.2.2 请求/systemInfo02/hostInfo

在这里插入图片描述
在这里插入图片描述

注意:

前缀匹配一定要写后边的”/“,比如前缀匹配应该写成”/systemInfo/“,而最好不要写成”/systemInfo“,因为当用第二种写法的时候,如果其他的前缀匹配中有前缀相似的uri时,会导致匹配出现问题,比如”/systemInfo“与”/systemInfo01“同时存在时,路由会优先匹配”/systemInfo“,而不去匹配”/systemInfo01“

2.3.2 分析

2.3.1 获取路由配置
[root@master istio-demo]# istioctl -n istio-system pc routes istio-ingressgateway-6fd6665c9c-nm22r --name http.8080 -o json
[
    {
    
    
        "name": "http.8080",
        "virtualHosts": [
            {
    
    
                "name": "*:80",
                "domains": [
                    "*"
                ],
                "routes": [
                    {
    
    
                        "match": {
    
    
                            "prefix": "/systemInfo02/",
                            "caseSensitive": true
                        },
                        "route": {
    
    
                            "cluster": "outbound|8080||demo-java.java-demo-devops.svc.cluster.local",
                            "timeout": "0s",
                            "retryPolicy": {
    
    
                                "retryOn": "connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes",
                                "numRetries": 2,
                                "retryHostPredicate": [
                                    {
    
    
                                        "name": "envoy.retry_host_predicates.previous_hosts",
                                        "typedConfig": {
    
    
                                            "@type": "type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicate"
                                        }
                                    }
                                ],
                                "hostSelectionRetryMaxAttempts": "5",
                                "retriableStatusCodes": [
                                    503
                                ]
                            },
                            "maxStreamDuration": {
    
    
                                "maxStreamDuration": "0s",
                                "grpcTimeoutHeaderMax": "0s"
                            }
                        },
                        "metadata": {
    
    
                            "filterMetadata": {
    
    
                                "istio": {
    
    
                                    "config": "/apis/networking.istio.io/v1alpha3/namespaces/java-demo-devops/virtual-service/demo-java"
                                }
                            }
                        },
                        "decorator": {
    
    
                            "operation": "demo-java.java-demo-devops.svc.cluster.local:8080/systemInfo02/*"
                        }
                    },
                    {
    
    
                        "match": {
    
    
                            "prefix": "/systemInfo01",
                            "caseSensitive": true
                        },
                        "route": {
    
    
                            "cluster": "outbound|8080||demo-java.demo.svc.cluster.local",
                            "timeout": "0s",
                            "retryPolicy": {
    
    
                                "retryOn": "connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes",
                                "numRetries": 2,
                                "retryHostPredicate": [
                                    {
    
    
                                        "name": "envoy.retry_host_predicates.previous_hosts",
                                        "typedConfig": {
    
    
                                            "@type": "type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicate"
                                        }
                                    }
                                ],
                                "hostSelectionRetryMaxAttempts": "5",
                                "retriableStatusCodes": [
                                    503
                                ]
                            },
                            "maxStreamDuration": {
    
    
                                "maxStreamDuration": "0s",
                                "grpcTimeoutHeaderMax": "0s"
                            }
                        },
                        "metadata": {
    
    
                            "filterMetadata": {
    
    
                                "istio": {
    
    
                                    "config": "/apis/networking.istio.io/v1alpha3/namespaces/demo/virtual-service/demo-java"
                                }
                            }
                        },
                        "decorator": {
    
    
                            "operation": "demo-java.demo.svc.cluster.local:8080/systemInfo01*"
                        }
                    }
                ],
                "includeRequestAttemptCount": true
            }
        ],
        "validateClusters": false,
        "ignorePortInHostMatching": true
    }
]

可以看到此处virtualHosts中只有一个domains,而在routes中根据不同的match到达不同的route

这种情况的应用可以用于来自同一domains的请求需要根据uri转发至不同service的情况,为了安全起见,这种情况也可以设置sepc.hosts的值为指定域。

3. Istio官方提醒

当为已存在的host创建第二个及更多的 VirtualService时,istio-pilot 会将额外的路由规则合并到host现有配置中。但是,在使用此功能时,有一些注意事项。

  1. 尽管会保留任何给定源 VirtualService 中规则的评估顺序,但跨资源的顺序是不确定的。换句话说,无法保证片段配置中规则的评估顺序,因此,只有在片段规则之间没有冲突的规则或者顺序依赖性时,它才具有可预测的行为。
  2. 片段中应该只有一个“catch-all”规则(即与任何请求路径或 header 都匹配的规则)。所有这些“catch-all”规则将在合并配置中移至列表的末尾,但是由于它们捕获了所有请求,因此,首先应用的那个规则,实际上会覆盖并禁用其它的规则。
  3. 如果想将 VirtualService 绑定到网关,则只能以这种方式进行分段。sidecar不支持host合并。

也可以使用类似的合并语义和限制将 DestinationRule 分段。

  1. 在这里,它应该只是同一host的多个 DestinationRule 中任何给定子集的一种定义。如果有多个同名,则使用第一个定义,并丢弃随后的所有重复项。不支持子集内容的合并。
  2. 同一host只能有一个顶级的 trafficPolicy。在多个 DestinationRule 中定义了顶级 trafficPolicy 时,将使用第一个策略。之后的所有顶级 trafficPolicy 配置都将被丢弃。
  3. VirtualService 合并不同, DestinationRule 合并在 sidecar 和 gateway 中均有效。

猜你喜欢

转载自blog.csdn.net/Mrheiiow/article/details/128478492