You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Istio本地限流Network Filter运行一段时间后失效问题排查

问题:Istio本地Network Filter限流一段时间后失效

环境与背景

在K8s集群中运行监听8443端口的HTTPS Go服务,集群边缘部署了监听443端口的Istio入口网关。通过配置Virtual Service(匹配/testgo转发至服务443端口)、Destination Rule(使用SIMPLE TLS)实现了外部https://GATEWAY_HOST/testgo的访问。

注入Istio Sidecar后,为保持后端HTTPS访问将peerAuthentication设为DISABLE,导致官方文档的HTTP本地限流过滤器失效。改用NETWORK_FILTER类型的本地限流后,初始运行正常,但一段时间后出现限流失效的情况,当前使用Istio 1.15版本。

当前EnvoyFilter配置

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: go-server-ratelimit
  namespace: default
spec:
  workloadSelector:
    labels:
      app: web
  configPatches:
    - applyTo: NETWORK_FILTER
      match:
        context: SIDECAR_INBOUND
        listener:
          portNumber: 8443
          filterChain:
            filter:
              name: "envoy.filters.network.tcp_proxy"
      patch:
        operation: INSERT_BEFORE
        value:
          name: envoy.filters.local_ratelimit
          typed_config:
            "@type": type.googleapis.com/udpa.type.v1.TypedStruct
            type_url: type.googleapis.com/envoy.extensions.filters.network.local_ratelimit.v3.LocalRateLimit
            value:
              stat_prefix: local_rate_limiter
              token_bucket:
                max_tokens: 1
                tokens_per_fill: 1
                fill_interval: 60s
              runtime_enabled:
                default_value: true
                runtime_key: go-server-ratelimit
              share_key: go-server-ratelimit

测试脚本

cnt=1
delay=60
while true
do
  http_code=`curl -k -o /dev/null -s -w "%{http_code}" "https://GATEWAY_HOST/testgo/"`
  if [ $http_code -ne 200 ]
  then
        echo "HTTP return code is $http_code after $((cnt-1)) tries, sleeping for $delay seconds"
        sleep $delay
        cnt=1
  else
        echo "HTTP return code is $http_code on try $cnt"
        cnt=$((cnt+1))
  fi
done

异常现象

预期为每分钟仅允许1个HTTP请求成功,但运行一段时间后,过滤器允许多个请求通过,测试输出片段如下:

HTTP return code is 200 on try 1
HTTP return code is 503 after 1 tries, sleeping for 60 seconds
...
HTTP return code is 200 on try 1
HTTP return code is 200 on try 2
HTTP return code is 200 on try 3
HTTP return code is 200 on try 4
...
HTTP return code is 503 after 10 tries, sleeping for 60 seconds

问题根源与解决方案

问题根源

你使用的envoy.filters.network.local_ratelimit是TCP层限流过滤器,它只能针对TCP连接进行限流,无法识别上层的HTTP请求。当客户端开启连接复用(如curl默认启用keep-alive)时,多个HTTP请求会通过同一个TCP连接发送,该过滤器仅在连接建立时消耗1个令牌,后续同一连接内的所有HTTP请求都不会触发限流检查,因此出现“限流失效”的现象——实际是多个请求复用了已通过限流的TCP连接。

正确配置方案

要实现HTTP请求级别的精准限流,必须切换到HTTP_FILTER类型的限流过滤器,同时调整PeerAuthentication配置以支持流量解密:

  1. 调整PeerAuthentication配置
    不要直接设置为DISABLE,改用PERMISSIVE模式允许TLS与非TLS流量,或针对特定服务设为STRICT,确保Sidecar能解密后端HTTPS流量以解析HTTP请求:

    apiVersion: security.istio.io/v1beta1
    kind: PeerAuthentication
    metadata:
      name: default
      namespace: default
    spec:
      mtls:
        mode: PERMISSIVE
    
  2. 使用HTTP_FILTER类型的本地限流EnvoyFilter

    apiVersion: networking.istio.io/v1alpha3
    kind: EnvoyFilter
    metadata:
      name: go-server-ratelimit
      namespace: default
    spec:
      workloadSelector:
        labels:
          app: web
      configPatches:
        - applyTo: HTTP_FILTER
          match:
            context: SIDECAR_INBOUND
            listener:
              portNumber: 8443
              filterChain:
                filter:
                  name: "envoy.filters.network.http_connection_manager"
                  subFilter:
                    name: "envoy.filters.http.router"
          patch:
            operation: INSERT_BEFORE
            value:
              name: envoy.filters.http.local_ratelimit
              typed_config:
                "@type": type.googleapis.com/udpa.type.v1.TypedStruct
                type_url: type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit
                value:
                  stat_prefix: local_rate_limiter
                  token_bucket:
                    max_tokens: 1
                    tokens_per_fill: 1
                    fill_interval: 60s
                  runtime_enabled:
                    default_value: true
                    runtime_key: go-server-ratelimit
                  filter_enabled:
                    runtime_key: local_rate_limit_enabled
                    default_value:
                      numerator: 100
                      denominator: HUNDRED
                  filter_enforced:
                    runtime_key: local_rate_limit_enforced
                    default_value:
                      numerator: 100
                      denominator: HUNDRED
                  response_headers_to_add:
                    - append: false
                      header:
                        key: "x-local-rate-limit"
                        value: "true"
    
  3. 确保Destination Rule配置正确
    保持Sidecar与后端服务的TLS通信配置,确保流量解密正常:

    apiVersion: networking.istio.io/v1beta1
    kind: DestinationRule
    metadata:
      name: web-service
      namespace: default
    spec:
      host: web.default.svc.cluster.local
      trafficPolicy:
        tls:
          mode: SIMPLE
    

临时Workaround(若必须使用NETWORK_FILTER)

如果暂时无法切换到HTTP_FILTER,可在测试脚本中强制关闭连接复用,确保每次请求建立新TCP连接:

http_code=`curl -k -H "Connection: close" -o /dev/null -s -w "%{http_code}" "https://GATEWAY_HOST/testgo/"`

该方案会带来性能损耗,仅作为临时验证使用。


内容的提问来源于stack exchange,提问作者Dattaram Porob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 00:47:31