Kubernetes下nginx Ingress的限制

在 kubernetes 中,ingress 负责转发、融断和限流。

我们以 Nginx ingress 为例,讨论一下这方面的问题。

一、Nginx ingress黑白名单

这个很简单了,丢进黑名单或者白名单,在入口前拦一刀。

我们只要在 annotations 声明即可:

image-20211129102114725

 1apiVersion: networking.k8s.io/v1beta1 
 2kind: Ingress 
 3metadata: 
 4name: www-com-ingress 
 5annotations: 
 6   kubernetes.io/ingress.class: nginx 
 7   nginx.ingress.kubernetes.io/ssl-redirect: "true" 
 8   nginx.ingress.kubernetes.io/block-cidrs: a.b.c.d/32 
 9   #nginx.ingress.kubernetes.io/whitelist-source-range: a.b.c.d/32 
10spec: 
11tls: 
12- hosts: 
13   - www.huabbao.com 
14   secretName: www-huabbao-com-cert 
15rules: 
16- host: www.huabbao.com 
17   http: 
18     paths: 
19     - path: / 
20       backend: 
21         serviceName: nginx-svc 

注意,多个ip的话,之间用逗号隔开(该值是逗号分隔的CIDR列表) :

1nginx.ingress.kubernetes.io/whitelist-source-range: '58.246.36.130,180.167.74.98,114.85.176.38’ 

二、Nginx ingress限速

限速这个问题比较复杂,首先我们需要考虑到用户体验,如果很鲁棒性的强制限制客户端流量是10KB,那么如果一开始的加载页面如果较大,客户直接就离场了。所以首先要考虑要有初始字节量,这个量需要能让客户顺畅的打开首页。然后我们再设定请求速率,再考虑单个IP地址的并发连接量(并发量×速率=客户端实际速率),第四个再考虑每分钟或每秒的最大请求数。

以下注释定义按顺序排列,可以设置单个客户端IP地址打开的连接的限制,可用于缓解DDoS攻击。

  • 一、nginx.ingress.kubernetes.io/limit-rate-after:设置初始字节量,在此之后,进一步传输将受到limit-rate速率限制。
  • 二、nginx.ingress.kubernetes.io/limit-rate:每秒接受的请求速率(每秒字节数)。
  • 三、nginx.ingress.kubernetes.io/limit-connections:来自单个IP地址的并发连接数。(可以建立最大连接数)
  • 四、nginx.ingress.kubernetes.io/limit-rps:每秒可从给定IP接受的连接数。(每个源 IP 每个源 IP 每秒最大请求次数)
  • 五、nginx.ingress.kubernetes.io/limit-rpm:每分钟可从给定IP接受的连接数。(每个源 IP 每分钟最大请求次数)

可以指定 nginx.ingress.kubernetes.io/limit-whitelist 设置从速率限制中排除的客户端IP源范围,该值也是逗号分隔的CIDR列表。

如果在单个Ingress规则中设置了多个注释 limit-rpm,则 limit-rps 优先。

 1apiVersion: extensions/v1beta1 
 2kind: Ingress 
 3metadata: 
 4  name: my-ingress 
 5  annotations: 
 6    nginx.ingress.kubernetes.io/limit-rate-after: 500k
 7    nginx.ingress.kubernetes.io/limit-rate: 50k
 8    nginx.ingress.kubernetes.io/limit-connections: "3" 
 9    nginx.ingress.kubernetes.io/limit-rps: "1" 
10    nginx.ingress.kubernetes.io/limit-rpm: "3" 
11    nginx.ingress.kubernetes.io/limit-whitelist: "192.168.7.0/24" 
12spec: 
13  rules: 
14  - host: my.test.com 
15    http: 
16      paths:  
17      - path: / 
18        backend: 
19          serviceName: nginx 
20          servicePort: 80 

解释一下:

首先设置了初始字节量是500k

然后初始字节量用完之后,限制用户传输速率是50k/s

随后并发连接设置为3,那么客户端如果同时打开3个连接,总速率是 50k×3=150k/s

第四步进一步设置了每秒最大请求次数是1,下面又设置每分钟最大请求次数是3。

第五步设置了 192.168.7.0/24 这段不受限速的影响

设置好以后压测试一下:

超限返回的代码是503

 1wrk -c 3 -t 3 -d 10 http://m.test.com --latency 
 2
 3
 4curl -v -H "Host: m.test.com" http://m.test.com
 5< HTTP/1.1 503 Service Temporarily Unavailable 
 6< Date: Wed, 28 Jul 2021 04:32:03 GMT 
 7< Content-Type: text/html 
 8< Content-Length: 190 
 9< Connection: keep-alive 
10HTTP/1.1 503 Service Temporarily Unavailable 

Kubernetes搭建minio作为阿里OSS的Gateway
Kubernetes下定制服务器503以及其他的403消息
comments powered by Disqus