one can install a rate limit that varies across paths.
in the simplified version (without using the cluster keyword):
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: route-ratelimit-test
namespace: istio-system
...more code here...
patch:
operation: MERGE
value:
route:
rate_limits:
- actions:
- request_headers:
header_name: ":path"
descriptor_key: path
- request_headers:
header_name: ":method"
descriptor_key: method
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
descriptors:
- entries:
- key: path
value: "/v1/a/b/get/*"
- key: method
value: GET
token_bucket:
max_tokens: 1
tokens_per_fill: 1
fill_interval: 60s
...more code here...
using *
for all path deeper than /v1/a/b/get/...
doesn’t work. only exact string match works here.
if the descriptor entry value will be
- key: path
value: "/v1/a/b/get/1"
The rate limiter will be triggered only if you fire
curl http://localhost/v1/a/b/get/1
if the curl command will be changed even by one bit: rate limiter will ignore it.
How can I make it work with regex like for path ?
well I saw I can enhance the envoyfilter by using different actions:
patch:
operation: MERGE
value:
route:
rate_limits:
- actions:
- header_value_match:
descriptor_value: path
headers:
- name: :path
prefix_match: "/v1"
- request_headers:
header_name: ":method"
descriptor_key: method
or as full file :
# https://www.aboutwayfair.com/tech-innovation/understanding-envoy-rate-limits
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: get-ratelimit
namespace: istio-system
spec:
workloadSelector:
# bare in mind , rate limiter workloadSelector can select pods based on labels in the init phase. not later in the lifecycle.
# so , the recommended way, is to look at labels from the relevant deployment/statefulset .
labels:
app: "myapp2"
configPatches:
- applyTo: HTTP_FILTER
match:
context: SIDECAR_INBOUND
listener:
filterChain:
filter:
name: "envoy.filters.network.http_connection_manager"
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: SIDECAR_INBOUND
routeConfiguration:
vhost:
name: "inbound|http|8080"
route:
action: ANY
patch:
operation: MERGE
value:
route:
domain: get-methods
rate_limits:
- actions:
- header_value_match:
descriptor_value: path
headers:
- name: :path
prefix_match: "/v1"
- request_headers:
header_name: ":method"
descriptor_key: method
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
descriptors:
- entries:
- key: path
value: "/v1/very/heavy/action1"
- key: method
value: GET
token_bucket:
max_tokens: 1
tokens_per_fill: 1
fill_interval: 60s
- entries:
- key: path
value: "/v1/healthz"
- key: method
value: GET
token_bucket:
max_tokens: 60
tokens_per_fill: 60
fill_interval: 60s
- entries:
- key: path
value: "/v1/very/light/action"
- key: method
value: POST
token_bucket:
max_tokens: 100
tokens_per_fill: 100
fill_interval: 60s
enable_x_ratelimit_headers: "DRAFT_VERSION_03"
# next line will give the default rate for anything not caught by previous lines.
token_bucket:
max_tokens: 20
tokens_per_fill: 20
fill_interval: 20s
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