Hi~朋友,关注置顶防止错过消息
为什么需要限流
为了防止接口被恶意请求,我们可以在Ingress Nginx网关上增加一个限流。
Nginx的限流
Nginx中的限流模块主要使用limit_req指令实现。
Nginx限流配置
1. 首先我们需要在http模块中使用limitreqzone定义一个共享内存区域,该共享内存区域记录了限流key的访问频率:
代码语言:javascript复制http {
limit_req_zone $binary_remote_addr zone=ip_limit:10m rate=5r/s;
}
- zone=iplimit:10m,指定了共享内存区域的名称为iplimit,并为其分配10MB的内存空间
- rate:rate参数用来指定请求速率,上述示例中限速每秒钟5次
- binaryremoteaddr:这里指定限流的key是客户端的IP地址二进制表现形式,如果是IP uri的形式后面可以再跟上uri
2. 使用limit_req指令为location配置具体的请求限制:
代码语言:javascript复制location / {
limit_req zone=ip_limit burst=5 nodelay;
}
- zone:指定了使用的共享内存区域的名称
- burst:指定了在超过指定速率限制以后允许的1s内最大突发请求次数,该参数受nodelay参数的影响
- nodelay:该参数有两个值off和on,默认为off,表示启用延迟模式,该模式下burst参数会生效,如果修改为on表示禁用延迟模式,一旦超过速率限制,请求会被立即拒绝
Kubernetes Nginx中限流配置
1. 在Ingress Nginx的ingress-nginx-controller中定义共享内存区域:
代码语言:javascript复制kind: ConfigMap
apiVersion: v1
metadata:
name: ingress-nginx-controller
namespace: ingress-nginx
...
data:
...
http-snippet: |
limit_req_zone
b
i
n
a
r
y
r
e
m
o
t
e
a
d
d
r
uri zone=ip_uri_limit:10m rate=10r/s;
..
2. 在相应的ingress中配置使用 nginx.ingress.kubernetes.io/configuration-snippet注解指定limit_req
代码语言:javascript复制kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
name: xxxx
annotations:
.....
nginx.ingress.kubernetes.io/configuration-snippet: |
limit_req zone=ip_uri_limit burst=10 nodelay;
spec:
ingressClassName: nginx
tls:
...
rules:
- host: xxx
....
测试和监控
测试工具我使用的wrk压测工具,它可以同时并发的向我们的网关发送请求。
上线限流规则以后一定要注意监控,默认的触发限流nginx会返回503错误,一定要注意限流参数的设置,防止误触。
对于更高级别的防护大家可以考虑使用WAF产品,WAF本人也不熟悉,就暂时不过多叙述。