成功最有效的方法就是向有经验的人学习!

envoyfilter之listener filter用法

1什么是listener filter

listener filter中文名称是监听器过滤器的意思。

从envoy架构图中可以看出listener filters是所有filter中,首先起作用的过滤器。它的主要作用有 检测协议、解析协议,通过它们解析出的信息被用于匹配 filter_chains 中的 filter 。

2有哪些listener filter

  • envoy.filters.listener.http_inspector
    https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/listener/http_inspector/v3/http_inspector.proto#extension-envoy-filters-listener-http-inspector
  • envoy.filters.listener.original_dst
    https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/listener/original_dst/v3/original_dst.proto#extension-envoy-filters-listener-original-dst
  • envoy.filters.listener.original_src
    https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/listener/original_src/v3/original_src.proto#extension-envoy-filters-listener-original-src
  • envoy.filters.listener.proxy_protocol
    https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/listener/proxy_protocol/v3/proxy_protocol.proto#extension-envoy-filters-listener-proxy-protocol
  • envoy.filters.listener.tls_inspector
    https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/listener/tls_inspector/v3/tls_inspector.proto#extension-envoy-filters-listener-tls-inspector
  • envoy.filters.udp_listener.dns_filter
    https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/udp/dns_filter/v3/dns_filter.proto#extension-envoy-filters-udp-listener-dns-filter
  • envoy.filters.udp_listener.udp_proxy
    https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/udp/udp_proxy/v3/udp_proxy.proto#extension-envoy-filters-udp-listener-udp-proxy

http_inspector:

判断应用层的数据是否使用 HTTP 协议,如果是,续继判断 HTTP 协议的版本号(HTTP 1.0、HTTP 1.1、HTTP 2)

original_dst:

用来读取 socket 的配置项 SO_ORIGINAL_DST,在使用 透明代理模式(https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/lds.proto#envoy-api-field-listener-transparent) 时用到,在 envoy 中,用该 filter 获取报文的原始目地地址

original_src

用于透明代理(https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/lds.proto#envoy-api-field-listener-transparent),让 uptream 看到的是请求端的 IP,双方均感知不到 envoy 的存在 。

Original Source(https://www.envoyproxy.io/docs/envoy/latest/configuration/listener_filters/original_src_filter) 有点类似于 lvs 的 DR 模式(http://www.linuxvirtualserver.org/VS-DRouting.html) ,假设 downstream 的 IP 是 10.1.2.3,envoy 的 IP 是 10.2.2.3。envoy 将报文转发给 upstream 时复用 downstream 的源 IP,upstream 看到的源 IP 是 downstream 的 IP 10.1.2.3,不是 envoy 的 IP 10.2.2.3。

与 lvs 的 DR 模式(http://www.linuxvirtualserver.org/VS-DRouting.html) 区别是,在 lvs 中,upsteram 是直接将回应包发送给 downstream,而 envoy 的文档中强调,必须通过配置网络环境,让 uptream 的回应包发送到 envoy ,再由 envoy 转发。

原始地址的使用方式:

session粘性:基于ip的hash

安全策略:黑白名单设置

日志和stats

proxy_protocol

解析代理协议,用该 filter 可以解析出真实的源 IP,已知支持 HAProxy Proxy Protocol(https://www.haproxy.org/download/1.9/doc/proxy-protocol.txt)

tls_inspector

用来判断是否使用 TLS 协议,如果是 TLS 协议,解析出 Server Name、Negotiation 信息,解析出来的信息用于 FilterChain 的匹配。

dns_filter

dns过滤器允许envoy执行通过一个授权的服务器查询dns,他可以指定dns服务器,也可以静态指定dns,或者通过外部文件设置静态dns。

udp_proxy

enovy通过这个filter实现一个非透明的udp代理。缺少透明指的是上游服务会看到envoy的源ip和端口而不是客户端的。所有的数据包,从客户端到envoy到上游,回来,再从上游到envoy到客户端。使用use_original_src_ip(https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/udp/udp_proxy/v3/udp_proxy.proto#envoy-v3-api-msg-extensions-filters-udp-udp-proxy-v3-udpproxyconfig) 字段,udp proxy可以实现透明代理,但是他只代理ip,不透明代理端口。

3实战

3.1http_inspector

listener-filter-http_inspector.yaml

kubectl apply -f listener-filter-http_inspector.yaml -n istio

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: listener
  namespace: istio 
spec:
  workloadSelector:
    labels:
      app: productpage
  configPatches:
  - applyTo: LISTENER
    match:
      context: SIDECAR_INBOUND
    patch:
      operation: ADD
      value:
        name: proxy
        address:
          socket_address:
            protocol: TCP
            address: 0.0.0.0
            port_value: 8083
        metadata:
          filter_metadata:
            envoy.lb:
              test: test
        listener_filters:
          - name: envoy.filters.listener.http_inspector
            typedConfig:
              '@type': type.googleapis.com/envoy.extensions.filters.listener.http_inspector.v3.HttpInspector 
        filter_chains:
        - filter_chain_match:
            "transport_protocol": "raw_buffer"
          filters:
          - name: "envoy.filters.network.http_connection_manager"
            typed_config:
              "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager"
              stat_prefix: ingress_proxy
              route_config:
                name: route_a
                virtual_hosts:
                - name: envoy_cyz
                  domains:
                  - "*"
                  routes:
                  - match:
                      prefix: "/"
                    route:
                      cluster: cluster123
              http_filters:
              - name: "envoy.filters.http.router"
                typed_config:
                  "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router"
  - applyTo: CLUSTER
    patch:
      operation: ADD
      value: 
        name: "cluster123"
        type: STATIC
        connect_timeout: 0.5s
        lb_policy: ROUND_ROBIN
        load_assignment:
          cluster_name: cluster123
          endpoints:
          - lb_endpoints:
            - endpoint:
                address:
                  socket_address:
                    address: 127.0.0.1
                    port_value: 9080

3.2original_dst

listener-filter-original_dst.yaml

kubectl apply -f listener-filter-original_dst.yaml -n istio

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: listener
  namespace: istio 
spec:
  workloadSelector:
    labels:
      app: productpage
  configPatches:
  - applyTo: LISTENER
    match:
      context: SIDECAR_INBOUND
    patch:
      operation: ADD
      value:
        name: proxy
        address:
          socket_address:
            protocol: TCP
            address: 0.0.0.0
            port_value: 8083
        metadata:
          filter_metadata:
            envoy.lb:
              test: test
        listener_filters:
        - name: envoy.filters.listener.original_dst
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.filters.listener.original_dst.v3.OriginalDst
        filter_chains:
        - filter_chain_match:
            "transport_protocol": "raw_buffer"
          filters:
          - name: "envoy.filters.network.http_connection_manager"
            typed_config:
              "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager"
              stat_prefix: ingress_proxy
              route_config:
                name: route_a
                virtual_hosts:
                - name: envoy_cyz
                  domains:
                  - "*"
                  routes:
                  - match:
                      prefix: "/"
                    route:
                      cluster: cluster123
              http_filters:
              - name: "envoy.filters.http.router"
                typed_config:
                  "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router"
  - applyTo: CLUSTER
    patch:
      operation: ADD
      value: 
        name: "cluster123"
        type: STATIC
        connect_timeout: 0.5s
        lb_policy: ROUND_ROBIN
        load_assignment:
          cluster_name: cluster123
          endpoints:
          - lb_endpoints:
            - endpoint:
                address:
                  socket_address:
                    address: 127.0.0.1
                    port_value: 9080

3.3original_src

listener-filter-original_src.yaml

kubectl apply -f listener-filter-original_src.yaml -n istio

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: listener
  namespace: istio 
spec:
  workloadSelector:
    labels:
      app: productpage
  configPatches:
  - applyTo: LISTENER
    match:
      context: SIDECAR_INBOUND
    patch:
      operation: ADD
      value:
        name: proxy
        address:
          socket_address:
            protocol: TCP
            address: 0.0.0.0
            port_value: 8083
        metadata:
          filter_metadata:
            envoy.lb:
              test: test
        listener_filters:
        - name: envoy.filters.listener.proxy_protocol
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.filters.listener.proxy_protocol.v3.ProxyProtocol
        - name: envoy.filters.listener.original_src
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.filters.listener.original_src.v3.OriginalSrc
            mark: 123
        filter_chains:
        - filter_chain_match:
            "transport_protocol": "raw_buffer"
          filters:
          - name: "envoy.filters.network.http_connection_manager"
            typed_config:
              "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager"
              stat_prefix: ingress_proxy
              route_config:
                name: route_a
                virtual_hosts:
                - name: envoy_cyz
                  domains:
                  - "*"
                  routes:
                  - match:
                      prefix: "/"
                    route:
                      cluster: cluster123
              http_filters:
              - name: "envoy.filters.http.router"
                typed_config:
                  "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router"
  - applyTo: CLUSTER
    patch:
      operation: ADD
      value: 
        name: "cluster123"
        type: STATIC
        connect_timeout: 0.5s
        lb_policy: ROUND_ROBIN
        load_assignment:
          cluster_name: cluster123
          endpoints:
          - lb_endpoints:
            - endpoint:
                address:
                  socket_address:
                    address: 127.0.0.1
                    port_value: 9080

3.4proxy_protocol

listener-filter-proxy_protocol.yaml

kubectl apply -f listener-filter-proxy_protocol.yaml -n istio

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: listener
  namespace: istio 
spec:
  workloadSelector:
    labels:
      app: productpage
  configPatches:
  - applyTo: LISTENER
    match:
      context: SIDECAR_INBOUND
    patch:
      operation: ADD
      value:
        name: proxy
        address:
          socket_address:
            protocol: TCP
            address: 0.0.0.0
            port_value: 8083
        metadata:
          filter_metadata:
            envoy.lb:
              test: test
        listener_filters:
        - name: envoy.filters.listener.proxy_protocol
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.filters.listener.proxy_protocol.v3.ProxyProtocol
        - name: envoy.filters.listener.original_src
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.filters.listener.original_src.v3.OriginalSrc
            mark: 123
        filter_chains:
        - filter_chain_match:
            "transport_protocol": "raw_buffer"
          filters:
          - name: "envoy.filters.network.http_connection_manager"
            typed_config:
              "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager"
              stat_prefix: ingress_proxy
              route_config:
                name: route_a
                virtual_hosts:
                - name: envoy_cyz
                  domains:
                  - "*"
                  routes:
                  - match:
                      prefix: "/"
                    route:
                      cluster: cluster123
              http_filters:
              - name: "envoy.filters.http.router"
                typed_config:
                  "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router"
  - applyTo: CLUSTER
    patch:
      operation: ADD
      value: 
        name: "cluster123"
        type: STATIC
        connect_timeout: 0.5s
        lb_policy: ROUND_ROBIN
        load_assignment:
          cluster_name: cluster123
          endpoints:
          - lb_endpoints:
            - endpoint:
                address:
                  socket_address:
                    address: 127.0.0.1
                    port_value: 9080

3.5tls_inspector

listener-filter-tls_inspector.yaml

kubectl apply -f listener-filter-tls_inspector.yaml -n istio

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: listener
  namespace: istio 
spec:
  workloadSelector:
    labels:
      app: productpage
  configPatches:
  - applyTo: LISTENER
    match:
      context: SIDECAR_INBOUND
    patch:
      operation: ADD
      value:
        name: proxy
        address:
          socket_address:
            protocol: TCP
            address: 0.0.0.0
            port_value: 8083
        metadata:
          filter_metadata:
            envoy.lb:
              test: test
        listener_filters:
          - name: envoy.filters.listener.tls_inspector
            typedConfig:
              '@type': type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector
          - name: envoy.filters.listener.http_inspector
            typedConfig:
              '@type': type.googleapis.com/envoy.extensions.filters.listener.http_inspector.v3.HttpInspector
        filter_chains:
        - filter_chain_match:
            "transport_protocol": "raw_buffer"
          filters:
          - name: "envoy.filters.network.http_connection_manager"
            typed_config:
              "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager"
              stat_prefix: ingress_proxy
              route_config:
                name: route_a
                virtual_hosts:
                - name: envoy_cyz
                  domains:
                  - "*"
                  routes:
                  - match:
                      prefix: "/"
                    route:
                      cluster: cluster123
              http_filters:
              - name: "envoy.filters.http.router"
                typed_config:
                  "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router"
  - applyTo: CLUSTER
    patch:
      operation: ADD
      value: 
        name: "cluster123"
        type: STATIC
        connect_timeout: 0.5s
        lb_policy: ROUND_ROBIN
        load_assignment:
          cluster_name: cluster123
          endpoints:
          - lb_endpoints:
            - endpoint:
                address:
                  socket_address:
                    address: 127.0.0.1
                    port_value: 9080

3.6dns_filter

还在开发中,不建议生产环境使用,目前isito没有集成,会报错

3.6.1client_config,server_config

listener-filters-dns_filter.yaml

kubectl apply -f listener-filters-dns_filter.yaml -n istio

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: listener
  namespace: istio 
spec:
  workloadSelector:
    labels:
      app: productpage
  configPatches:
  - applyTo: LISTENER
    match:
      context: SIDECAR_INBOUND
    patch:
      operation: ADD
      value:
        name: proxy
        address:
          socket_address:
            protocol: TCP
            address: 0.0.0.0
            port_value: 8083
        metadata:
          filter_metadata:
            envoy.lb:
              test: test
        listener_filters:
        - name: envoy.filters.udp_listener.dns_filter
          typed_config:
            "@type": "type.googleapis.com/envoy.extensions.filters.udp.dns_filter.v3.DnsFilterConfig"
            stat_prefix: "dns_filter_prefix"
            client_config:
              resolution_timeout: 5s
              dns_resolution_config:
                dns_resolver_options:
                  use_tcp_for_dns_lookups: false
                  no_default_search_domain: false
                resolvers:
                - socket_address:
                    address: "8.8.8.8"
                    port_value: 53
                - socket_address:
                    address: "8.8.4.4"
                    port_value: 53
              max_pending_lookups: 256
            server_config:
              inline_dns_table:
                virtual_domains:
                  - name: "www.domain1.com"
                    endpoint:
                      address_list:
                        address:
                        - 10.0.0.1
                        - 10.0.0.2
                  - name: "www.domain2.com"
                    endpoint:
                      address_list:
                        address:
                          - 2001:8a:c1::2800:7
                  - name: "www.domain3.com"
                    endpoint:
                      address_list:
                        address:
                        - 10.0.3.1
                  - name: "www.domain4.com"
                    endpoint:
                      cluster_name: cluster_0
                  - name: "voip.domain5.com"
                    endpoint:
                      service_list:
                        services:
                          - service_name: "sip"
                            protocol: { number: 6 }
                            ttl: 86400s
                            targets:
                            - host_name: "primary.voip.domain5.com"
                              priority: 10
                              weight: 30
                              port: 5060
                            - host_name: "secondary.voip.domain5.com"
                              priority: 10
                              weight: 20
                              port: 5060
                            - host_name: "backup.voip.domain5.com"
                              priority: 10
                              weight: 10
                              port: 5060
        filter_chains:
        - filter_chain_match:
            "transport_protocol": "raw_buffer"
          filters:
          - name: "envoy.filters.network.http_connection_manager"
            typed_config:
              "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager"
              stat_prefix: ingress_proxy
              route_config:
                name: route_a
                virtual_hosts:
                - name: envoy_cyz
                  domains:
                  - "*"
                  routes:
                  - match:
                      prefix: "/"
                    route:
                      cluster: cluster123
              http_filters:
              - name: "envoy.filters.http.router"
                typed_config:
                  "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router"
  - applyTo: CLUSTER
    patch:
      operation: ADD
      value: 
        name: "cluster123"
        type: STATIC
        connect_timeout: 0.5s
        lb_policy: ROUND_ROBIN
        load_assignment:
          cluster_name: cluster123
          endpoints:
          - lb_endpoints:
            - endpoint:
                address:
                  socket_address:
                    address: 127.0.0.1
                    port_value: 9080

3.6.2external_dns_table

listener-filters-dns_filter.yaml

kubectl apply -f listener-filters-dns_filter.yaml -n istio

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: listener
  namespace: istio 
spec:
  workloadSelector:
    labels:
      app: productpage
  configPatches:
  - applyTo: LISTENER
    match:
      context: SIDECAR_INBOUND
    patch:
      operation: ADD
      value:
        name: proxy
        address:
          socket_address:
            protocol: TCP
            address: 0.0.0.0
            port_value: 8083
        metadata:
          filter_metadata:
            envoy.lb:
              test: test
        listener_filters:
        - name: envoy.filters.udp_listener.dns_filter
          typed_config:
            '@type': 'type.googleapis.com/envoy.extensions.filters.udp.dns_filter.v3.DnsFilterConfig'
            stat_prefix: "my_prefix"
            server_config:
              external_dns_table:
                filename: "/home/ubuntu/configs/dns_table.json"
        filter_chains:
        - filter_chain_match:
            "transport_protocol": "raw_buffer"
          filters:
          - name: "envoy.filters.network.http_connection_manager"
            typed_config:
              "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager"
              stat_prefix: ingress_proxy
              route_config:
                name: route_a
                virtual_hosts:
                - name: envoy_cyz
                  domains:
                  - "*"
                  routes:
                  - match:
                      prefix: "/"
                    route:
                      cluster: cluster123
              http_filters:
              - name: "envoy.filters.http.router"
                typed_config:
                  "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router"
  - applyTo: CLUSTER
    patch:
      operation: ADD
      value: 
        name: "cluster123"
        type: STATIC
        connect_timeout: 0.5s
        lb_policy: ROUND_ROBIN
        load_assignment:
          cluster_name: cluster123
          endpoints:
          - lb_endpoints:
            - endpoint:
                address:
                  socket_address:
                    address: 127.0.0.1
                    port_value: 9080

/home/ubuntu/configs/dns_table.json

{
  "virtual_domains": [
    {
      "name": "www.suffix1.com",
      "endpoint": {
        "address_list": {
          "address": [ "10.0.0.1", "10.0.0.2" ]
        }
      }
    },
    {
      "name": "www.suffix2.com",
      "endpoint": {
        "address_list": {
          "address": [ "2001:8a:c1::2800:7" ]
        }
      }
    }
  ]
}

3.7udp_proxy

listener-filters-udp_proxy.yaml

kubectl apply -f listener-filters-udp_proxy.yaml -n istio

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: listener
  namespace: istio 
spec:
  workloadSelector:
    labels:
      app: udp
  configPatches:
  - applyTo: LISTENER
    match:
      context: SIDECAR_INBOUND
    patch:
      operation: ADD
      value:
        name: proxy-udp
        address:
          socket_address:
            protocol: UDP
            address: 127.0.0.1
            port_value: 1234
        udp_listener_config:
          downstream_socket_config:
            max_rx_datagram_size: 9000
        listener_filters:
        - name: envoy.filters.udp_listener.udp_proxy
          typed_config:
            '@type': type.googleapis.com/envoy.extensions.filters.udp.udp_proxy.v3.UdpProxyConfig
            stat_prefix: service
            cluster: service_udp
            upstream_socket_config:
              max_rx_datagram_size: 9000
  - applyTo: CLUSTER
    patch:
      operation: ADD
      value: 
        name: service_udp
        type: STATIC
        lb_policy: ROUND_ROBIN
        load_assignment:
          cluster_name: service_udp
          endpoints:
          - lb_endpoints:
            - endpoint:
                address:
                  socket_address:
                    address: 127.0.0.1
                    port_value: 1235
赞(0) 打赏
未经允许不得转载:陈桂林博客 » envoyfilter之listener filter用法
分享到

大佬们的评论 抢沙发

全新“一站式”建站,高质量、高售后的一条龙服务

微信 抖音 支付宝 百度 头条 快手全平台打通信息流

橙子建站.极速智能建站8折购买虚拟主机

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续给力更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫打赏

微信扫一扫打赏

登录

找回密码

注册