VirtualService Routing для сервисов с похожим подмножеством имен

Мне нужно определить два VirtualService для одного и того же хоста, т.е.

хост: http://customerA.test.example.com, будет использоваться для обслуживания двух служб, а именно «SRV» и «SRVUI»

Чтобы достичь этого, я, соответственно, определил виртуальную службу как:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: srv
  namespace: srv-test01
spec:
  gateways:
  - http-gateway
  hosts:
  - customerA.test.example.com
  http:
  - match:
    - uri:
        prefix: /srv
    route:
    - destination:
        host: srv.srv-test01.svc.cluster.local
        port:
          number: 8080

а также

 apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: srvui
      namespace: srv-test01
    spec:
      gateways:
      - http-gateway
      hosts:
      - customerA.test.example.com
      http:
      - match:
        - uri:
            prefix: /srvui
        route:
        - destination:
            host: srvui.srv-test01.svc.cluster.local
            port:
              number: 8080

Это привело к тому, что envoy conf на istio-ingress-gateway as (оба virtualService находятся в одном пространстве имен)

"name": "customerA.test.example.com:80",
        "domains": [
         "customerA.test.example.com",
         "customerA.test.example.com:80"
        ],
        "routes": [
         {
          "match": {
           "prefix": "/srv"
          },
          "route": {
           "cluster": "outbound|8080||srv.srv-test01.svc.cluster.local",
           "timeout": "0s",
           "max_grpc_timeout": "0s"
          },
          "decorator": {
           "operation": "srv.srv-test01.svc.cluster.local:8080/srv*"
          },
          "per_filter_config": {
           "mixer": {
            "forward_attributes": {
             "attributes": {
              "destination.service.host": {
               "string_value": "srv.srv-test01.svc.cluster.local"
              },
              "destination.service.uid": {
               "string_value": "istio://srv-test01/services/srv"
              },
              "destination.service.namespace": {
               "string_value": "srv-test01"
              },
              "destination.service.name": {
               "string_value": "srv"
              },
              "destination.service": {
               "string_value": "srv.srv-test01.svc.cluster.local"
              }
             }
            },
            "mixer_attributes": {
             "attributes": {
              "destination.service.host": {
               "string_value": "srv.srv-test01.svc.cluster.local"
              },
              "destination.service.uid": {
               "string_value": "istio://srv-test01/services/srv"
              },
              "destination.service.name": {
               "string_value": "srv"
              },
              "destination.service.namespace": {
               "string_value": "srv-test01"
              },
              "destination.service": {
               "string_value": "srv.srv-test01.svc.cluster.local"
              }
             }
            }
           }
          }
         },
         {
          "match": {
           "prefix": "/srvui"
          },
          "route": {
           "cluster": "outbound|8080||srvui.srv-test01.svc.cluster.local",
           "timeout": "0s",
           "max_grpc_timeout": "0s"
          },
          "decorator": {
           "operation": "srvui.srv-test01.svc.cluster.local:8080/srvui*"
          },
          "per_filter_config": {
           "mixer": {
            "forward_attributes": {
             "attributes": {
              "destination.service.namespace": {
               "string_value": "srv-test01"
              },
              "destination.service.name": {
               "string_value": "srvui"
              },
              "destination.service": {
               "string_value": "srvui.srv-test01.svc.cluster.local"
              },
              "destination.service.host": {
               "string_value": "srvui.srv-test01.svc.cluster.local"
              },
              "destination.service.uid": {
               "string_value": "istio://srv-test01/services/srv"
              }
             }
            },
            "mixer_attributes": {
             "attributes": {
              "destination.service.host": {
               "string_value": "srvui.srv-test01.svc.cluster.local"
              },
              "destination.service.uid": {
               "string_value": "istio://srv-test01/services/srv"
              },
              "destination.service.name": {
               "string_value": "srvui"
              },
              "destination.service.namespace": {
               "string_value": "srv-test01"
              },
              "destination.service": {
               "string_value": "srvui.srv-test01.svc.cluster.local"
              }
             }
            }
           }
          }
         }
        ]
       },

Однако проблема здесь в том, что даже запросы, поступающие для / srvui, заканчиваются на / srv virtual-service, журналы на istio-ingress-gateway

[2019-02-04T05:46:20.822Z] "**GET /srvHTTP/1.1**" 404 - 0 1077 3 2 "xx.xx.xx.xx, xx.xx.xx.xx" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36" "5fa6611c-07ab-954c-b871-09398bd6c2e4" "customerA.test.example.com" "10.192.21.210:8080" outbound|8080||srv.srv-test01.svc.cluster.local - 10.192.11.185:80 10.192.20.101:36536  ---> **end up on correct service on backend as per virtualService defination**



[2019-02-04T05:46:40.864Z] "**GET /srvuiHTTP/1.1**" 404 - 0 1079 3 1 "xx.xx.xx.xx, 10.192.10.101" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36" "58e17520-a5df-9c90-9ec4-62dbc2bc1307" "customerA.test.example.com" "10.192.21.210:8080" outbound|8080||srv.srv-test01.svc.cluster.local - 10.192.11.185:80 10.192.10.101:54352  ---> Even the context is srvui it is ending up on srv backend.

похоже, что это зависит от нумерации VirtualService в его conf, чтобы маршрутизация вступила в силу,

если мы сначала настроим srvui virtualService, а затем маршрутизация srv произойдет правильно.

однако проблема заключается в том, что нам необходимо поддерживать развертывание этих служб в пронумерованном порядке, чего я бы хотел избежать.

Я не могу использовать «точное» вместо «префикса», потому что тогда мне нужно было бы определить более 100 точных путей URI.

Другое решение - изменить имя контекста службы, чтобы они не выглядели как подмножества друг друга, как здесь srv и srvui, и, таким образом, istio-ingress-gateway может правильно маршрутизировать его, однако это также требует изменения приложения.

любезно дайте мне знать, есть ли другое решение, которое я мог бы реализовать здесь.


person Ruchir Bharadwaj    schedule 04.02.2019    source источник


Ответы (1)


Это не удивительно, поскольку srv является подмножеством srvui.

Вы должны иметь возможность использовать совпадение regex вместо exact или prefix. См. https://istio.io/docs/reference/config/istio.networking.v1alpha3/#HTTPMatchRequest для получения более полной документации.

URI для сопоставления значений чувствительны к регистру и имеют следующий формат:

  • точное: значение для точного совпадения строки
  • prefix: значение для соответствия на основе префикса
  • regex: значение для совпадения стиля ECMAscript на основе регулярного выражения
person Paul Annetts    schedule 05.02.2019