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