Istio (envoy) 匹配不存在 header 的速率限制
Istio (envoy) rate limits for matching the absence of a header
我们想实施 envoyFilters
,允许我们对没有特定 header 的所有流量应用每分钟最多 20 个请求的本地速率限制。想法是限制对所有 non-authenticated 用户的请求量,这些用户应该缺少 header x-user-auth: some_value
.
所有请求都是针对同一个 Kubernetes 服务并且来自 different/undetermined 个来源。我们没有使用任何 Istio ingressgateway
,但是作为这些请求电路的一部分的所有 pods 都注入了 Istio sidecar 代理。
这是如何实现的?
查看 Envoy 的速率限制服务 documentation,没有明显的方法可以根据 headers 限制请求速率。
但是,Istio 的 Request Routing and Rate Limits.
可能会实现这样的配置
创建 route based on user identity 匹配 headers
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
...
spec:
hosts:
- foo
http:
- match:
- headers:
x-user-auth:
exact: <some_value>
route:
- destination:
host: foo
subset: bar
- route:
- destination:
host: foo
subset: baz
并使用 local rate limiting 创建服务。
希望此配置将使用 x-user-auth
header 的请求重定向到 non-limited 服务(bar),并将其他所有人重定向到有限的服务(baz)。
我没有使用本地速率限制,而是充当我们的速率限制器的外部服务 - 我在本文中对其进行了更详细的描述:https://domagalski-j.medium.com/istio-rate-limits-for-egress-traffic-8697df490f68
所以在我的情况下,这只是调整 envoy actions. I've changed it from generic_key to request_headers - as you can read in the docs 的问题,request_headers 有一个选项:skip_if_absent - 如果留空,那么如果给定的 header 是未附加到请求,请求不会转发到速率限制器服务。
您正在尝试对没有特定 header 的所有内容进行速率限制,因此也许 "header_value_match" 操作更适合您,因为它具有您可以使用的“expect_match”字段。
这是我在 istio 中使用的 EnvoyFilter:
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: route-httpbin
namespace: default
spec:
workloadSelector:
labels:
app: bastion-box
configPatches:
- applyTo: HTTP_ROUTE
match:
context: SIDECAR_OUTBOUND
routeConfiguration:
vhost:
name: "httpbin.org:80"
route:
name: "default"
patch:
operation: MERGE
value:
route:
rate_limits:
- actions:
- request_headers:
header_name: "X-Client-Id"
descriptor_key: "clientId"
- request_headers:
header_name: "X-Credential-Username"
descriptor_key: "username"
我还发现这篇文章对理解 envoy 过滤器非常有帮助:
https://www.aboutwayfair.com/tech-innovation/understanding-envoy-rate-limits
我们想实施 envoyFilters
,允许我们对没有特定 header 的所有流量应用每分钟最多 20 个请求的本地速率限制。想法是限制对所有 non-authenticated 用户的请求量,这些用户应该缺少 header x-user-auth: some_value
.
所有请求都是针对同一个 Kubernetes 服务并且来自 different/undetermined 个来源。我们没有使用任何 Istio ingressgateway
,但是作为这些请求电路的一部分的所有 pods 都注入了 Istio sidecar 代理。
这是如何实现的?
查看 Envoy 的速率限制服务 documentation,没有明显的方法可以根据 headers 限制请求速率。
但是,Istio 的 Request Routing and Rate Limits.
可能会实现这样的配置
创建 route based on user identity 匹配 headers
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
...
spec:
hosts:
- foo
http:
- match:
- headers:
x-user-auth:
exact: <some_value>
route:
- destination:
host: foo
subset: bar
- route:
- destination:
host: foo
subset: baz
并使用 local rate limiting 创建服务。
希望此配置将使用 x-user-auth
header 的请求重定向到 non-limited 服务(bar),并将其他所有人重定向到有限的服务(baz)。
我没有使用本地速率限制,而是充当我们的速率限制器的外部服务 - 我在本文中对其进行了更详细的描述:https://domagalski-j.medium.com/istio-rate-limits-for-egress-traffic-8697df490f68
所以在我的情况下,这只是调整 envoy actions. I've changed it from generic_key to request_headers - as you can read in the docs 的问题,request_headers 有一个选项:skip_if_absent - 如果留空,那么如果给定的 header 是未附加到请求,请求不会转发到速率限制器服务。 您正在尝试对没有特定 header 的所有内容进行速率限制,因此也许 "header_value_match" 操作更适合您,因为它具有您可以使用的“expect_match”字段。
这是我在 istio 中使用的 EnvoyFilter:
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: route-httpbin
namespace: default
spec:
workloadSelector:
labels:
app: bastion-box
configPatches:
- applyTo: HTTP_ROUTE
match:
context: SIDECAR_OUTBOUND
routeConfiguration:
vhost:
name: "httpbin.org:80"
route:
name: "default"
patch:
operation: MERGE
value:
route:
rate_limits:
- actions:
- request_headers:
header_name: "X-Client-Id"
descriptor_key: "clientId"
- request_headers:
header_name: "X-Credential-Username"
descriptor_key: "username"
我还发现这篇文章对理解 envoy 过滤器非常有帮助: https://www.aboutwayfair.com/tech-innovation/understanding-envoy-rate-limits