通过Envoy Gateway配置限流
限流是一种用于控制客户端向服务端发送请求速率的防护机制。其核心目的是防止系统因突发流量过载,确保服务的稳定性和高可用性。通常表示为一段时间内的请求数,例如每分钟100个请求或每秒10个请求等。
Envoy代理实现限流主要有两种方式:本地(Local)限流和全局(Global)限流。两者核心区别在于统计范围:本地限流在每个Envoy实例上独立计数,而全局限流则在所有实例间共享计数。为了更直观地说明,假设集群中已部署一个有5个Envoy实例的网关,并且配置了100请求/分钟的限流策略,两者的最终效果会完全不同:
- 本地限流:每个Envoy实例只能感知到达自身的流量,各自独立计数。因此,整个系统理论上最多可处理5 * 100 = 500请求/分钟。这会导致后端服务实际承受的总负载远超预期。
- 全局限流:所有网关实例共享统一的流量计数。通过引入Redis作为中心化、高性能的分布式计数器,确保无论请求落在哪一个Envoy实例上,都能基于全局统一的配额进行扣减,从而实现精准的跨实例限流控制。因此,整个系统的总流量会被严格控制在100请求/分钟,无论后端有多少个实例在运行。
Envoy Gateway插件支持全局限流功能,开启该功能之后会自动部署一个限流服务,该服务负责集中管理并动态提供全局的限流策略与实时流量数据,并基于限流策略对传入的请求进行限流。
本文提供Global级别和Local级别不同场景的配置示例。更多关于限流策略的完整参数说明,请参见BackendTrafficPolicy。
注意事项
关闭全局限流功能前需要确保当前全局限流策略已删除,否则会导致访问路由异常。具体操作步骤请参见如何关闭全局限流功能。
前提条件
- 当前集群已安装Envoy Gateway插件,并且插件状态为运行中。
- 集群中已创建后端应用及对应的Service。 本文中后端应用为Nginx,Service名称为backend,Service端口为3000。您可以将以下YAML内容保存为backend.yaml,然后执行kubectl apply -f backend.yaml命令。
apiVersion: apps/v1 kind: Deployment metadata: name: backend namespace: default spec: replicas: 2 selector: matchLabels: app: backend version: v1 template: metadata: labels: app: backend version: v1 spec: containers: - name: container-1 image: nginx:latest imagePullSecrets: - name: default-secret --- apiVersion: v1 kind: Service metadata: name: backend labels: app: backend version: v1 namespace: default spec: selector: app: backend version: v1 ports: - name: cce-service-0 targetPort: 80 port: 3000 protocol: TCP type: ClusterIP
创建Global级别的限流策略
Envoy Gateway的全局限流依赖Redis作为计数器,实现多个Envoy网关实例的实时流量精确汇总与超限拦截。本文采用自建Redis服务的方式。
步骤一:部署Redis
- 请参见通过kubectl连接集群,使用kubectl连接集群。
- 创建redis-service.yaml。
kind: Namespace apiVersion: v1 metadata: name: redis-system --- apiVersion: apps/v1 kind: StatefulSet metadata: name: redis namespace: redis-system labels: app: redis spec: serviceName: "redis" replicas: 1 selector: matchLabels: app: redis template: metadata: labels: app: redis spec: containers: - image: redis:latest name: redis ports: - containerPort: 6379 resources: limits: cpu: 1500m memory: 512Mi requests: cpu: 200m memory: 256Mi --- apiVersion: v1 kind: Service metadata: name: redis namespace: redis-system labels: app: redis spec: ports: - name: redis port: 6379 protocol: TCP targetPort: 6379 selector: app: redis - 部署Redis服务。
kubectl apply -f redis-service.yaml
步骤二:开启插件全局限流功能
- 登录CCE控制台,单击集群名称进入集群。
- 在左侧导航栏中选择“插件中心”,在右侧找到Envoy Gateway插件,单击“编辑”。
- 开启全局限流功能并配置Redis服务地址。
本文使用集群内Redis地址:redis.redis-system.svc.cluster.local:6379

- 单击“确定”,完成插件升级。
步骤三:创建Gateway和HTTPRoute
创建Gateway和HTTPRoute资源,后续的限流规则将会应用到该路由规则上。
- 创建ratelimit.yaml。
apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: my-gateway #Gateway名称 namespace: default spec: gatewayClassName: envoy-gateway #GatewayClass名称 listeners: - name: http protocol: HTTP #协议 port: 80 #监听端口 --- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute #资源类型为HTTPRoute metadata: name: ratelimit #HTTPRoute名称 namespace: default spec: parentRefs: - name: my-gateway #Gateway名称 hostnames: - "www.example.com" #域名 rules: - backendRefs: - group: "" kind: Service name: backend #已创建的service名称 port: 3000 #service的端口 weight: 1 - 部署Gateway和HTTPRoute资源。
kubectl apply -f ratelimit.yaml
步骤四:创建限流策略(BackendTrafficPolicy)
- 场景一:限制访问频率
- 场景二:对指定用户进行限流
- 场景三:对除某个用户外的其他用户进行限流
- 场景四:根据客户端IP进行限流(仅CCE Turbo集群使用独享ELB场景支持)
创建Local级别的限流策略
Local级别的限流策略不依赖Redis,每个Envoy实例只能感知到达自身的流量,各自独立计数。
步骤一:创建Gateway和HTTPRoute
创建Gateway和HTTPRoute资源,后续的限流规则将会应用到该路由规则上。
- 创建ratelimit.yaml。
apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: my-gateway #Gateway名称 namespace: default spec: gatewayClassName: envoy-gateway #GatewayClass名称 listeners: - name: http protocol: HTTP #协议 port: 80 #监听端口 --- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute #资源类型为HTTPRoute metadata: name: ratelimit #HTTPRoute名称 namespace: default spec: parentRefs: - name: my-gateway #Gateway名称 hostnames: - "www.example.com" #域名 rules: - backendRefs: - group: "" kind: Service name: backend #已创建的service名称 port: 3000 #service的端口 weight: 1 - 部署Gateway和HTTPRoute资源。
kubectl apply -f ratelimit.yaml
步骤二:创建限流策略(BackendTrafficPolicy)
Local级别的限流策略支持的场景和Global级别一致,以限制访问频率为例,配置Local限流规则,限制请求为每分钟3次。
- 创建backendtrafficpolicy.yaml。
apiVersion: gateway.envoyproxy.io/v1alpha1 kind: BackendTrafficPolicy metadata: name: multiple-rules-example namespace: default spec: targetRefs: - group: gateway.networking.k8s.io kind: HTTPRoute name: ratelimit # 限流的HTTPRoute名称 rateLimit: type: Local # Local级别的限流策略 local: # 此处与Global级别限流策略存在差异 rules: # 限流规则:限制访问频率,每分钟3次 - limit: requests: 3 unit: Minute - 部署限流规则。
kubectl apply -f backendtrafficpolicy.yaml
- 修改Envoy实例个数。
- 登录CCE控制台,单击集群名称进入集群。
- 在左侧导航栏中选择“插件中心”,在右侧找到Envoy Gateway插件,单击“编辑”。
- 修改envoy组件个数为2。
- 单击“确定”,完成插件升级。
- 测试请求限流情况。
for i in {1..8}; do curl -I --header "Host: www.example.com" http://xx.xx.xx.xx/ ; sleep 1; done预期输出如下:
HTTP/1.1 200 OK server: nginx/1.23.2 date: Sat, 30 May 2026 08:40:34 GMT content-type: text/html content-length: 615 last-modified: Wed, 19 Oct 2022 07:56:21 GMT etag: "634fada5-267" accept-ranges: bytes x-ratelimit-limit: 3 x-ratelimit-remaining: 2 x-ratelimit-reset: 0 HTTP/1.1 200 OK server: nginx/1.23.2 date: Sat, 30 May 2026 08:40:35 GMT content-type: text/html content-length: 615 last-modified: Wed, 19 Oct 2022 07:56:21 GMT etag: "634fada5-267" accept-ranges: bytes x-ratelimit-limit: 3 x-ratelimit-remaining: 2 x-ratelimit-reset: 0 HTTP/1.1 200 OK server: nginx/1.23.2 date: Sat, 30 May 2026 08:40:36 GMT content-type: text/html content-length: 615 last-modified: Wed, 19 Oct 2022 07:56:21 GMT etag: "634fada5-267" accept-ranges: bytes x-ratelimit-limit: 3 x-ratelimit-remaining: 1 x-ratelimit-reset: 0 HTTP/1.1 200 OK server: nginx/1.23.2 date: Sat, 30 May 2026 08:40:37 GMT content-type: text/html content-length: 615 last-modified: Wed, 19 Oct 2022 07:56:21 GMT etag: "634fada5-267" accept-ranges: bytes x-ratelimit-limit: 3 x-ratelimit-remaining: 1 x-ratelimit-reset: 0 HTTP/1.1 200 OK server: nginx/1.23.2 date: Sat, 30 May 2026 08:40:38 GMT content-type: text/html content-length: 615 last-modified: Wed, 19 Oct 2022 07:56:21 GMT etag: "634fada5-267" accept-ranges: bytes x-ratelimit-limit: 3 x-ratelimit-remaining: 0 x-ratelimit-reset: 15 HTTP/1.1 200 OK server: nginx/1.23.2 date: Sat, 30 May 2026 08:40:39 GMT content-type: text/html content-length: 615 last-modified: Wed, 19 Oct 2022 07:56:21 GMT etag: "634fada5-267" accept-ranges: bytes x-ratelimit-limit: 3 x-ratelimit-remaining: 0 x-ratelimit-reset: 15 HTTP/1.1 429 Too Many Requests content-length: 18 content-type: text/plain x-ratelimit-limit: 3 x-ratelimit-remaining: 0 x-ratelimit-reset: 13 date: Sat, 30 May 2026 08:40:40 GMT HTTP/1.1 429 Too Many Requests content-length: 18 content-type: text/plain x-ratelimit-limit: 3 x-ratelimit-remaining: 0 x-ratelimit-reset: 13 date: Sat, 30 May 2026 08:40:41 GMT
前6次请求返回了200,第7、8次请求返回429,说明2个实例每个实例每分钟可以访问3次,一共6次,本地限流规则生效。
常见问题
如何关闭全局限流功能
关闭全局限流功能前需要确保当前全局限流策略已删除,或全部修改为本地级别的限流策略。具体操作步骤如下:
- 查询Global级别的限流策略。
kubectl get backendtrafficpolicy -A -o jsonpath='{range .items[?(@.spec.rateLimit.type=="Global")]}{.metadata.namespace}{"/"}{.metadata.name}{"\n"}{end}' - 删除限流策略或修改成本地级别的限流策略。 将限流策略修改为本地级别的示例如下:
apiVersion: gateway.envoyproxy.io/v1alpha1 kind: BackendTrafficPolicy metadata: name: multiple-rules-example namespace: default spec: targetRefs: - group: gateway.networking.k8s.io kind: HTTPRoute name: ratelimit rateLimit: type: Global # 修改成Local global: #修改成local rules: - limit: requests: 3 unit: Minute - 重新执行步骤1,再次检查是否修改完成。
