I am endeavoring to implement rate limiting using the components provided by Istio, specifically the EnvoyFilter. My intention is to apply this filter exclusively to HTTP requests with a particular prefix path, such as "/api/serviceA/v1/*". To achieve this, I have deployed an EnvoyFilter within the GATEWAY context and for the gateway workload.
However, I have come to realize that this rate limit is not synchronized across the various gateway pods. Due to the dynamic nature of the gateway pods (autoscaling), the limit also dynamically increases with the number of pods.
Is there a viable method to synchronize this rate limit across the gateway pods without necessitating the deployment of third-party services(like the one here: https://istio.io/latest/docs/tasks/policy-enforcement/rate-limit/#global-rate-limit)?
Alternatively, is it feasible to impose rate limiting for a specific HTTP path prefix directly on the service sidecar pod(with SIDECAR_INBOUND context)?
Here is the problematic filter implementation:
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: gw-rate-limiter
spec:
workloadSelector:
labels:
istio: istio-igw
configPatches:
- applyTo: HTTP_FILTER
match:
context: GATEWAY
listener:
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: http_local_rate_limiter
- applyTo: HTTP_ROUTE
match:
context: GATEWAY
routeConfiguration:
vhost:
name: "some.domain.com:443" # virtual host name
route:
name: "my-named-api-route" # route name inside virtual host
action: "ANY"
patch:
operation: MERGE
value:
typed_per_filter_config:
envoy.filters.http.local_ratelimit:
"@type": type.googleapis.com/udpa.type.v1.TypedStruct
type_url: type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit
value:
stat_prefix: http_local_rate_limiter
token_bucket:
max_tokens: 5
tokens_per_fill: 5
fill_interval: 30s
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: true
header:
key: x-local-rate-limit
value: 'true'
I have tried also using LocalRateLimit descriptors(https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/local_rate_limit_filter#using-rate-limit-descriptors-for-local-rate-limiting) with path key but they only support specific path, not prefix.
I expect this filter either to synchronize between gateway pods or to impose request limits on each of the service pods individually.