使用ASM全局限流实现源IP分别限流

简介: 本文介绍了如何在ASM中实现基于源IP的全局限流,防止恶意请求。内容包括前提条件、准备工作、部署步骤及验证方法,帮助用户通过配置限流策略保障业务入口的稳定性与安全性。

对于业务入口来说,为了实现公平访问,防止某些客户端恶意发送大量请求,会有需要根据不同的请求源IP分别限制每个IP的请求速率的需求。本文主要阐述如何基于ASM的全局限流能力实现源IP分别限流场景。

前提条件

  • 已添加Kubernetes托管版集群到ASM实例,且ASM实例为1.25及以上。具体操作,请参见添加集群到ASM实例。
  • 已为Kubernetes集群中的default命名空间开启自动注入。具体操作,请参见启用自动注入。
  • 已创建名为ingressgateway的入口网关,并开启80端口。具体操作,请参见创建入口网关。

准备工作

  1. 部署全局限流服务依赖的redis服务(可使用Tair替代)
kubectl apply -f- <<EOF
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: registry-cn-hangzhou.ack.aliyuncs.com/dev/redis:6.0.6-for-ack-gateway
          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
EOF
  1. 部署全局限流服务
kubectl apply -f- <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
  name: ratelimit-config
data:
  config.yaml: |
    {}
---
apiVersion: v1
kind: Service
metadata:
  name: ratelimit
  labels:
    app: ratelimit
spec:
  ports:
  - name: http-port
    port: 8080
    targetPort: 8080
    protocol: TCP
  - name: grpc-port
    port: 8081
    targetPort: 8081
    protocol: TCP
  - name: http-debug
    port: 6070
    targetPort: 6070
    protocol: TCP
  selector:
    app: ratelimit
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ratelimit
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ratelimit
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: ratelimit
        sidecar.istio.io/inject: "false"
    spec:
      containers:
        # Latest image from https://hub.docker.com/r/envoyproxy/ratelimit/tags
      - image: registry-cn-hangzhou-vpc.ack.aliyuncs.com/acs/envoy-ratelimit:v1.4.0-g2210ce0-aliyun
        imagePullPolicy: Always
        name: ratelimit
        command: ["/bin/ratelimit"]
        env:
        - name: LOG_LEVEL
          value: debug
        - name: REDIS_SOCKET_TYPE
          value: tcp
        - name: REDIS_URL
          value: redis.redis-system.svc.cluster.local:6379
        - name: USE_STATSD
          value: "false"
        - name: RUNTIME_ROOT
          value: /data
        - name: RUNTIME_SUBDIRECTORY
          value: ratelimit
        - name: RUNTIME_WATCH_ROOT
          value: "false"
        - name: RUNTIME_IGNOREDOTFILES
          value: "true"
        ports:
        - containerPort: 8080
        - containerPort: 8081
        - containerPort: 6070
        volumeMounts:
        - name: config-volume
          # $RUNTIME_ROOT/$RUNTIME_SUBDIRECTORY/$RUNTIME_APPDIRECTORY/config.yaml
          mountPath: /data/ratelimit/config
      volumes:
      - name: config-volume
        configMap:
          name: ratelimit-config
EOF
  1. 部署示例服务和路由规则
kubectl apply -f- <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
  name: httpbin
---
apiVersion: v1
kind: Service
metadata:
  name: httpbin
  labels:
    app: httpbin
    service: httpbin
spec:
  ports:
  - name: http
    port: 8000
    targetPort: 80
  selector:
    app: httpbin
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpbin
spec:
  replicas: 1
  selector:
    matchLabels:
      app: httpbin
      version: v1
  template:
    metadata:
      labels:
        app: httpbin
        version: v1
      annotations:
        sidecar.istio.io/inject: "true"
    spec:
      serviceAccountName: httpbin
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/acs/httpbin:latest
        imagePullPolicy: IfNotPresent
        name: httpbin
        ports:
        - containerPort: 80
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: httpbin-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: httpbin
spec:
  gateways:
    - httpbin-gateway
  hosts:
    - bf2.example.com
  http:
    - name: httpbin-route
      route:
        - destination:
            host: httpbin
            port:
              number: 8000

实践步骤

  1. 部署asmglobalratelimiter资源
kubectl apply -f- <<EOF
apiVersion: istio.alibabacloud.com/v1
kind: ASMGlobalRateLimiter
metadata:
  name: global-test2
  namespace: istio-system
spec:
  configs:
    - limit:
        quota: 100000
        unit: SECOND
      limit_overrides:
        - limit:
            quota: 1
            unit: MINUTE
          request_match:
            remote_address:
              distinct: true
      match:
        vhost:
          name: bf2.example.com
          port: 80
          route:
            name_match: httpbin-route
      name: httpbin
  isGateway: true
  rateLimitService:
    host: ratelimit.default.svc.cluster.local
    port: 8081
    timeout:
      seconds: 5
  workloadSelector:
    labels:
      app: istio-ingressgateway
EOF
  1. 执行以下命令,获取全局限流服务配置
kubectl get asmglobalratelimiter global-test -n istio-system -o yaml

预期输出

apiVersion: istio.alibabacloud.com/v1
kind: ASMGlobalRateLimiter
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: >
      {"apiVersion":"istio.alibabacloud.com/v1","kind":"ASMGlobalRateLimiter","metadata":{"annotations":{},"name":"global-test2","namespace":"istio-system"},"spec":{"configs":[{"limit":{"quota":100000,"unit":"SECOND"},"limit_overrides":[{"limit":{"quota":1,"unit":"MINUTE"},"request_match":{"remote_address":{"distinct":true}}}],"match":{"vhost":{"name":"bf2.example.com","port":80,"route":{"name_match":"httpbin-route"}}},"name":"httpbin"}],"isGateway":true,"rateLimitService":{"host":"ratelimit.default.svc.cluster.local","port":8081,"timeout":{"seconds":5}},"workloadSelector":{"labels":{"app":"istio-ingressgateway"}}}}
  creationTimestamp: '2025-07-24T02:02:20Z'
  generation: 3
  name: global-test2
  namespace: istio-system
  resourceVersion: '35117'
  uid: 81f60d14-ae73-411f-b6b4-57f071e36539
spec:
  configs:
    - limit:
        quota: 100000
        unit: SECOND
      limit_overrides:
        - limit:
            quota: 1
            unit: MINUTE
          request_match:
            remote_address:
              distinct: true
      match:
        vhost:
          name: bf2.example.com
          port: 80
          route:
            name_match: httpbin-route
      name: httpbin
  isGateway: true
  rateLimitService:
    host: ratelimit.default.svc.cluster.local
    port: 8081
    timeout:
      seconds: 5
  workloadSelector:
    labels:
      app: istio-ingressgateway
status:
  config.yaml: |
    descriptors:
    - descriptors:
      - key: remote_address
        rate_limit:
          requests_per_unit: 1
          unit: MINUTE
      key: generic_key
      rate_limit:
        requests_per_unit: 100000
        unit: SECOND
      value: RateLimit[global-test2.istio-system]-Id[3387964427]
    domain: ratelimit.default.svc.cluster.local
  message: ok
  status: successful
  1. 将asmglobalratelimiter的status中的全局限流服务配置粘贴至限流服务configmap中
kubectl apply -f- <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
  name: ratelimit-config
data:
  config.yaml: |
    descriptors:
    - descriptors:
      - key: remote_address
        rate_limit:
          requests_per_unit: 1
          unit: MINUTE
      key: generic_key
      rate_limit:
        requests_per_unit: 100000
        unit: SECOND
      value: RateLimit[global-test2.istio-system]-Id[3387964427]
    domain: ratelimit.default.svc.cluster.local
EOF
  1. 执行以下命令用相同客户端连续访问ASM网关两次
export GATEWAY_URL=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
curl http://$GATEWAY_URL:80/get -H "host:bf2.example.com"
curl http://$GATEWAY_URL:80/get -H "host:bf2.example.com"

第二次访问时预期输出如下

< HTTP/1.1 429 Too Many Requests
< x-envoy-ratelimited: true
< x-ratelimit-limit: 1, 1;w=60, 100000;w=1
< x-ratelimit-remaining: 0
< x-ratelimit-reset: 33
< date: Thu, 24 Jul 2025 02:48:27 GMT
< server: istio-envoy
< content-length: 0
<

说明限流已经生效。使用不同客户端时,可发现请求仍然可以正常访问

相关文章
|
12月前
|
API
使用ACK推理网关基于域名路由到不同模型服务
本文介绍如何在ACK推理网关中通过Gateway API配置基于不同域名的路由规则,实现将请求按域名分发至qwen和deepseek等不同模型服务,并提供完整的操作步骤与测试示例。
|
编解码 Shell 文件存储
Rockchip saveBaseParameter程序来设置显示器参数
Rockchip saveBaseParameter程序来设置显示器参数
1581 50
【npm】解决:bat脚本中无法连续执行npm的问题
【npm】解决:bat脚本中无法连续执行npm的问题
1118 0
|
人工智能 缓存 Kubernetes
ACK GIE配置建议
Gateway with Inference Extension是基于Kubernetes社区Gateway API及其扩展规范实现的增强型组件,支持四层/七层路由服务,并面向生成式AI推理场景提供负载均衡优化、服务管理简化等能力,适用于AI推理服务的高可用部署与性能优化。在不同的场景使用ACK Gateway with Inference Extension时,可能需要根据业务需求和高可用需要对网关和推理扩展进行不同的配置调整。本文主要介绍在实际业务场景中针对ACK GIE的配置建议,以获得更好的使用效果。
1036 23
|
5月前
|
监控 NoSQL API
使用ASMGlobalRateLimiter实现基于调用来源和请求路径的精细化全局限流
本文介绍在阿里云ASM服务网格中,结合Lua Filter与ASMGlobalRateLimiter,基于调用方Service Account身份和API路径实现多维度精细化全局限流,满足不同客户端访问同一服务不同接口需差异化配额的业务需求。(239字)
|
Cloud Native 算法 中间件
如何使用服务网格实现全方位的流量调度场景
阿里云服务网格(ASM)通过流量调度套件扩展了Istio的限流、熔断能力,实现分用户限流、请求排队等复杂流量管理功能,提升分布式系统高可用性与可观测性。
|
前端开发 Java API
酒店管理系统基于 JavaFX Spring Boot 和 React 经典项目重构实操
本文介绍了基于现代技术栈的酒店管理系统开发方案,整合了JavaFX、Spring Boot和React三大技术框架。系统采用前后端分离架构,JavaFX构建桌面客户端,React开发Web管理界面,Spring Boot提供RESTful API后端服务。核心功能模块包括客房管理和客户预订流程,文中提供了JavaFX实现的客房管理界面代码示例和React开发的预订组件代码,展示了如何实现客房信息展示、添加修改操作以及在线预订功能。
851 0
|
调度 C语言 芯片
RT-Thread记录(二、RT-Thread内核启动流程 — 启动文件和源码分析)
今天就在前面我们RT-Thread Studio工程基础之上讲一讲RT-Thread内核启动流程
1136 0
RT-Thread记录(二、RT-Thread内核启动流程 — 启动文件和源码分析)