• Istio EnvoyFilter+Lua 简单实现动态路由转发


    公众号: 尹安灿 欢迎关注交流

    因为种种原因,我们需要实现一个将服务名和subset携带在http请求的header里面,根据这个来实现将服务转发去特定的istio的服务的subset。

    比如以下example:

    • 携带 service: msg-group tag: gray 的话,将其路由去msg-group 的gray subset。

      该版本返回数据: Call Read from msg-group,By New version!!!!

    • 携带 service: msg-group tag: default 的话,将其路由去msg-group 的default subset。

      改版本返回数据: Call Read from msg-group

    istio的Virtual Service来实现

    大概如下:

    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: onroute-com
      namespace: develop
    spec:
      gateways:
      - msggroup-gateway # 这个gateway - '*' 
      hosts:
      - onroute.com
      http:
      - match:
        - headers:
            service:
              exact: msg-group
            tag:
              exact: gray
        route:
        - destination:
            host: msg-group.develop.svc.cluster.local
            subset: gray
          headers:
            response:
              set:
                test: This value added By static route to gray
      - match:
        - headers:
            service:
              exact: msg-group
        route:
        - destination:
            host: msg-group.develop.svc.cluster.local
            subset: default
          headers:
            response:
              set:
                test: This value added By static route default
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    请求构造及结果如下:

    注:10.99.20.74 是istio-ingressgateway的IP

    请求 msg-group 的 gray 版本

    # curl -v -H "Host: onroute.com" -H "service: msg-group" -H "tag: gray" 10.99.20.74/read
    *   Trying 10.99.20.74:80...
    * Connected to 10.99.20.74 (10.99.20.74) port 80 (#0)
    > GET /read HTTP/1.1
    > Host: onroute.com
    > User-Agent: curl/7.77.0
    > Accept: */*
    > service: msg-group
    > tag: gray
    > 
    * Mark bundle as not supporting multiuse
    < HTTP/1.1 200 OK
    < content-type: text/plain;charset=UTF-8
    < content-length: 43
    < date: Fri, 16 Sep 2022 07:36:35 GMT
    < x-envoy-upstream-service-time: 7
    < server: istio-envoy
    < test: This value added By static route to gray
    < 
    * Connection #0 to host 10.99.20.74 left intact
    Call Read from msg-group,By New version!!!!% 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    请求 msg-group 的 default 版本

    curl -v -H "Host: onroute.com" -H "service: msg-group" -H "tag: default" 10.99.20.74/read
    *   Trying 10.99.20.74:80...
    * Connected to 10.99.20.74 (10.99.20.74) port 80 (#0)
    > GET /read HTTP/1.1
    > Host: onroute.com
    > User-Agent: curl/7.77.0
    > Accept: */*
    > service: msg-group
    > tag: default
    > 
    * Mark bundle as not supporting multiuse
    < HTTP/1.1 200 OK
    < content-type: text/plain;charset=UTF-8
    < content-length: 24
    < date: Fri, 16 Sep 2022 07:38:41 GMT
    < x-envoy-upstream-service-time: 12
    < server: istio-envoy
    < test: This value added By static route default
    < 
    * Connection #0 to host 10.99.20.74 left intact
    Call Read from msg-group%
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    能实现问题,但是有几个小问题

    1. 配置不够灵活,如果面对几百个服务,配置是个巨大的工作量。
    2. 不同的namespace要配置不同的规则。

    用Envoy Filter + Lua来实现

    针对上面提到的问题,如果用EnvoyFiltter来实现动态的路由的话,就可以解决这个问题。

    解决思路都是围绕config.route.v3.RouteAction cluster_header 这个字段来的

    (string) Envoy will determine the cluster to route to by reading the value of the HTTP header named by cluster_header from the request headers. If the header is not found or the referenced cluster does not exist, Envoy will return a 404 response.

    1. 设置route的cluster_header字段为 x-service
    2. 从header读取service和tag的值组合出upstream cluster格式,并将x-service头替换为它
    apiVersion: networking.istio.io/v1alpha3
    kind: EnvoyFilter
    metadata:
      name: onroute-routing
      namespace: istio-system
    spec:
      workloadSelector:
        labels:
          istio: ingressgateway
      configPatches:
      - applyTo: VIRTUAL_HOST
        match:
          context: GATEWAY
        patch:
          operation: ADD
          value:
            name: dynamic_routing
            domains:
              - 'onroute.com'
              - 'onroute.com:*'
            routes:
              - name: "path-matching"
                match:
                  prefix: "/"
                route:
                  cluster_header: "x-service"
      - applyTo: HTTP_FILTER
        match:
          context: GATEWAY
          listener:
            filterChain:
              filter:
                name: "envoy.http_connection_manager"
                subFilter:
                  name: "envoy.router"
        patch:
          operation: INSERT_BEFORE
          value:
           name: envoy.service-helper
           typed_config:
             "@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua"
             inlineCode: |
              function envoy_on_request(request_handle)
                local headers = request_handle:headers()
                local mesh_service = headers:get("service")
                local tag = headers:get("tag")
                if mesh_service ~= nil then
                  if tag ~= nil then
                    request_handle:headers():replace("x-service", "outbound|80|" .. tag .. "|" .. mesh_service .. ".svc.cluster.local")
                  end
                end
              end
    
              function envoy_on_response(response_handle)
                response_handle:headers():add("test", "from envoy filter response")
              end
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    下面是测试结果:

    请求 msg-group的 gray 版本

    curl -v -H "Host: onroute.com" -H "service: msg-group.develop" -H "tag: gray" 10.99.20.74/read
    *   Trying 10.99.20.74:80...
    * Connected to 10.99.20.74 (10.99.20.74) port 80 (#0)
    > GET /read HTTP/1.1
    > Host: onroute.com
    > User-Agent: curl/7.77.0
    > Accept: */*
    > service: msg-group.develop
    > tag: gray
    > 
    * Mark bundle as not supporting multiuse
    < HTTP/1.1 200 OK
    < content-type: text/plain;charset=UTF-8
    < content-length: 43
    < date: Fri, 16 Sep 2022 08:07:29 GMT
    < x-envoy-upstream-service-time: 16
    < server: istio-envoy
    < test: from envoy filter response
    < 
    * Connection #0 to host 10.99.20.74 left intact
    Call Read from msg-group,By New version!!!!%
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    请求 msg-group的 default 版本

    curl -v -H "Host: onroute.com" -H "service: msg-group.develop" -H "tag: default" 10.99.20.74/read
    *   Trying 10.99.20.74:80...
    * Connected to 10.99.20.74 (10.99.20.74) port 80 (#0)
    > GET /read HTTP/1.1
    > Host: onroute.com
    > User-Agent: curl/7.77.0
    > Accept: */*
    > service: msg-group.develop
    > tag: default
    > 
    * Mark bundle as not supporting multiuse
    < HTTP/1.1 200 OK
    < content-type: text/plain;charset=UTF-8
    < content-length: 24
    < date: Fri, 16 Sep 2022 08:12:40 GMT
    < x-envoy-upstream-service-time: 14
    < server: istio-envoy
    < test: from envoy filter response
    < 
    * Connection #0 to host 10.99.20.74 left intact
    Call Read from msg-group%
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    参考资料

  • 相关阅读:
    java基于微信小程序的停车场自动收费管理系统 uniapp 小程序
    柠檬文案:水果柠檬宣传文案
    vue3.0 01 项目的创建与setup组合式写法的基本使用 watch与watchEffect基本用法
    kubesz(一键安装k8s)
    图形渲染技术-目标变换
    云服务器及域名到期后,公安联网注销指南
    运放噪声频率曲线-运放噪声计算-运算放大器
    Linux性能优化--性能工具:磁盘I/O
    kafka的 ack 应答机制
    防火墙基础技术
  • 原文地址:https://blog.csdn.net/MichaelJScofield/article/details/126948885