本文是从零学习envoy笔记第四章 - 带宽限制
  • 从零学习envoy笔记 - Gateway总览
  • 从零学习envoy笔记 - 学习EG API和Gateway API
  • 从零学习envoy笔记 - 快速部署实验环境
  • 从零学习envoy笔记 - 官方Task Backend Routing
  • 从零学习envoy笔记 - 官方Task Backend Utilization Load Balancing
  • 从零学习envoy笔记 - 官方Task Bandwidth Limit
  • 从零学习envoy笔记 - 官方Task Client Traffic Policy

BackendTrafficPolicy

带宽限制 (Bandwidth Limit) 是指 Envoy Gateway 允许用户配置发送到后端和从后端接受的流量的吞吐量。这里不是指限速返回 429,而是 Envoy 会在带宽 token 用完后暂停数据传输,等 token 补充后继续 [1]

带宽限制主要是为了下面一些考虑:

  • 防止一个 backend 消耗完所有的网络
  • 保护上游服务过载
  • 确保在多路由,多租户等场景下的公平使用

需要注意的是,这里限速是针对 Envoy proxy 实例进行的,如果有多个实例,则每个实例自行限速,而不是共享一个限速池

Note: The bandwidth limit is applied per Envoy proxy instance. If the data plane runs multiple replicas, each replica enforces the limit independently. When a BackendTrafficPolicy with bandwidthLimit targets a Gateway, Envoy Gateway applies the same limit to each matching route under that Gateway. The limit is not shared across routes. [1]

实验 - 限制请求带宽

根据前面实验,要保留下面实验的后端

text
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$ kp
NAME                              READY   STATUS    RESTARTS      AGE
envoy-end-blue-69ddb5fdf8-nscgc   1/1     Running   1 (24h ago)   2d
envoy-end-gray-c84b9f77b-bgs7j    1/1     Running   1 (24h ago)   2d
envoy-end-red-6c7f88b949-x55d4    1/1     Running   1 (24h ago)   2d
$ ksv
NAME             TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)         AGE
envoy-end-blue   ClusterIP   10.96.210.236   <none>        90/TCP,80/TCP   2d
envoy-end-gray   ClusterIP   10.96.247.187   <none>        90/TCP,80/TCP   2d
envoy-end-red    ClusterIP   10.96.29.211    <none>        90/TCP,80/TCP   2

创建一个 HTTPRoute ,用于测试 Bandwidth Limit

text
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
cat <<EOF | kubectl apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: bandwidth-gray-red-blue-route
  namespace: default
spec:
  parentRefs:
    - name: eg
  rules:
    - matches:
        - headers:
            - name: Host
              value: gray-bandwidth.example.com
          path:
            type: PathPrefix
            value: /colorful
      backendRefs:
        - name: envoy-end-gray
          port: 90

    - matches:
        - headers:
            - name: Host
              value: red-bandwidth.example.com
          path:
            type: PathPrefix
            value: /colorful
      backendRefs:
        - name: envoy-end-red
          port: 90

    - matches:
        - headers:
            - name: Host
              value: blue-bandwidth.example.com
          path:
            type: PathPrefix
            value: /colorful
      backendRefs:
        - name: envoy-end-blue
          port: 90
EOF

验证 HTTPRoute 和 Gateway 的绑定

text
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$ kubectl get httproute bandwidth-gray-red-blue-route -o yaml
status:
  parents:
  - conditions:
    - lastTransitionTime: "2026-06-19T07:40:14Z"
      message: Route is accepted
      observedGeneration: 1
      reason: Accepted
      status: "True"
      type: Accepted

验证访问

text
1
2
3
4
5
6
7
8
$ curl -i -H "Host: gray-bandwidth.example.com" http://127.0.0.1:8888/colorful
{"message":"hello with gray."}root@DESKTOP-P2F4970:~#

$ curl -i -H "Host: red-bandwidth.example.com" http://127.0.0.1:8888/colorful
{"message":"hello with red."}

$ curl -i -H "Host: blue-bandwidth.example.com" http://127.0.0.1:8888/colorful
{"message":"hello with blue."}root@DESKTOP-P2F4970:~#

配置 Bandwidth Limit 挂载,

text
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
cat <<EOF | kubectl apply -f -
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
  name: bandwidth-gray-request-policy
  namespace: default
spec:
  targetRefs:
    - group: gateway.networking.k8s.io
      kind: HTTPRoute
      name: bandwidth-gray-route
  bandwidthLimit:
    request:
      limit:
        value: "10Ki"
        unit: Second
EOF

测试带宽限速命令

text
1
2
3
4
5
6
dd if=/dev/zero of=/tmp/test.bin bs=1K count=50

time curl -i -X POST \
  -H "Host: gray-bandwidth.example.com" \
  --data-binary @/tmp/test.bin \
  http://127.0.0.1:8888/colorful

这里因为后端不存在 POST 端口所以 404,也无法验证请求带宽限速

实验 - 限制相应带宽

准备 Red 的 HTTPRoute

text
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
cat <<EOF | kubectl apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: bandwidth-red-route
  namespace: default
spec:
  parentRefs:
    - name: eg
  hostnames:
    - "red-bandwidth.example.com"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /colorful
      backendRefs:
        - name: envoy-end-red
          port: 90
EOF

为 Red HTTPRoute 挂载 相应限速,这里为了验证效果,采用了 Hour 限速。

text
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
cat <<EOF | kubectl apply -f -
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
  name: bandwidth-red-response-policy
  namespace: default
spec:
  targetRefs:
    - group: gateway.networking.k8s.io
      kind: HTTPRoute
      name: bandwidth-red-route
  bandwidthLimit:
      response:
        limit:
          value: "12Mi"
          unit: Minute
EOF

验证访问

text
1
time curl -i -H "Host: red-bandwidth.example.com" http://127.0.0.1:8888/colorful

需要注意的是,这里的限速是 1Ki/Hour, 不是所有请求累计 1KiB / Hour,而是单个 Resopones 1KiB / Hour 的限速

实验结果:在 Second / Minute / Hour 三个条件进行实验,发现需要根据时间窗口和大小调整,否则出现500,不确定是否限制住了… , 例如 1/Second, 1Ki / Minute

资源清理

text
1
2
k delete BackendTrafficPolicy  bandwidth-gray-request-policy bandwidth-red-response-policy
k delete httproute bandwidth-gray-red-blue-route  bandwidth-red-route

Reference

[1] Bandwidth Limit