一、Ingress-nginx 速率限制

1.1 为什么要限速?

1、限速的本质是保证公平。

2、在带宽资源有限的情况下,尽可能地保障每个用户能被合理的分配足够的带宽值,服务更多的用户。

3、限速还可以大大缓解分布式拒绝服务攻击(DDOS)带来的影响。 这里的 速率 可以是:

  • 单个用户在单位时间内访问资源的频率;
  • 也可以是单个ip在单位时间内访问资源的频率;
  • 还可以是单位时间内指定连接的传输速率;

策略标准:(线上环境不要轻易去测试!一定要在非正式环境做验证)

nginx.ingress.kubernetes.io/limit-connections:单个IP地址允许的并发连接数。 超出此限制时,将返回503错误。

nginx.ingress.kubernetes.io/limit-rps:每秒从给定IP接受的请求数。突发限制设置为此限制乘以突发乘数,默认乘数为5。 当客户端超过此限制时,将返回limit-req-status-code默认值: 503。

nginx.ingress.kubernetes.io/limit-rpm:每分钟从给定IP接受的请求数。突发限制设置为此限制乘以突发乘数,默认乘数为5。 当客户端超过此限制时,将返回limit-req-status-code默认值: 503。

nginx.ingress.kubernetes.io/limit-burst-multiplier:突发大小限制速率的倍数。默认的脉冲串乘数为5,此注释将覆盖默认的乘数。当客户端超过此限制时,将返回limit-req-status-code默认值: 503。

nginx.ingress.kubernetes.io/limit-rate-after:最初的千字节数,在此之后,对给定连接的响应的进一步传输将受到速率的限制。必须在启用代理缓冲的情况下使用此功能。

nginx.ingress.kubernetes.io/limit-rate:每秒允许发送到给定连接的千字节数。零值禁用速率限制。必须在启用代理缓冲的情况下使用此功能。

nginx.ingress.kubernetes.io/limit-whitelist:客户端IP源范围要从速率限制中排除。该值是逗号分隔的CIDR列表。

1.2 ingress-nginx配置

# 编写yaml
[root@master01 6]# vim ingress-nginx-limit.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: java-ingress-nginx
  namespace: default
  annotations:
    nginx.ingress.kubernetes.io/limit-rate: 100K
    nginx.ingress.kubernetes.io/limit-whitelist: 10.0.0.60
    nginx.ingress.kubernetes.io/limit-rps: "1"
    nginx.ingress.kubernetes.io/limit-rpm: "30"
    nginx.ingress.kubernetes.io/limit-connections: "10"
spec:
  ingressClassName: nginx
  rules:
    - host: java.zhang-qing.com
      http:
        paths:
          - pathType: Prefix
            path: /
            backend:
              service:
                name: springboot
                port:
                  number: 8080

# 应用
[root@master01 6]# kaf ingress-nginx-limit.yaml

备注:

nginx.ingress.kubernetes.io/limit-rate:限制客户端每秒传输的字节数
nginx.ingress.kubernetes.io/limit-whitelist:白名单中的IP不限速
nginx.ingress.kubernetes.io/limit-rps:单个IP每秒的连接数
nginx.ingress.kubernetes.io/limit-rpm:单个IP每分钟的连接数
nginx.ingress.kubernetes.io/limit-connections:连接数被限制为10

测试验证:(偶发 503 异常)

[root@master01 6]#for i in `seq 1 50`; do curl http://java.zhang-qing.com/appone -I;done

环境清理

[root@master01 6]# k delete -f ingress-nginx-limit.yaml

二、Ingress-nginx 基本认证

有些访问是需要认证访问的,比如运管平台:skywalking,默认平台不需要输入任何用户名或密码。

需求:利用ingress-nginx实现,访问的时候输入用户名和密码。

2.1 工具生成秘钥

#用http的命令工具来生成
[root@master01 6]#yum -y install httpd-tools
[root@master01 6]#htpasswd -c auth admin
#查看密文
[root@master01 6]#cat auth

2.2 创建secret

需要将secret认证文件和pod放在同一个名称空间

# 创建secret
[root@master01 6]#kubectl create secret generic basic-auth --from-file=auth -n default

2.3 配置Ingress

需要在annotations下添加三条配置

#编写yaml
[root@master01 6]# vim ingress-nginx-auth.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: java-ingress-nginx
  namespace: default
  annotations:
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    nginx.ingress.kubernetes.io/auth-realm: "Authentication Required - admin"
spec:
  ingressClassName: nginx
  rules:
    - host: java.zhang-qing.com
      http:
        paths:
          - pathType: Prefix
            path: /
            backend:
              service:
                name: springboot
                port:
                  number: 8080

#应用
[root@master01 6]# kaf ingress-nginx-auth.yaml

备注:

# 认证类型
nginx.ingress.kubernetes.io/auth-type: basic
# 包含账号密码的secret
nginx.ingress.kubernetes.io/auth-secret: basic-auth
# 认证提示信息
nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - admin'

测试验证:

# curl -i -k http://java.zhang-qing.com/appone
HTTP/1.1 401 Unauthorized

web访问测试,账号为admin,密码为123456

image-20250410154606124

环境清理

[root@master01 6]# k delete -f  ingress-nginx-auth.yaml

三、其余annotations参数

3.1 禁用https强制跳转

annotations:
  nginx.ingress.kubernetes.io/ssl-redirect: "false"

3.2 Ingress-nginx的匹配请求头

需求:针对手机用户,匹配header头信息,将请求转发至手机端app。

#编写yaml
[root@master01 6]# vim ingress-nginx-header.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: java-ingress-nginx
  namespace: default
  annotations:
    nginx.ingress.kubernetes.io/server-snippet: |-
      set $agentflag 0;
      if ($http_user_agent ~* "(iPhone|iPod|android)" ) {
        set $agentflag 1;
      }
      if ($agentflag = 1) {
        return 301 https://m.baidu.com;
      }
spec:
  ingressClassName: nginx
  rules:
    - host: java.zhang-qing.com
      http:
        paths:
          - pathType: Prefix
            path: /
            backend:
              service:
                name: springboot
                port:
                  number: 8080

#应用
[root@master01 6]# kaf ingress-nginx-header.yaml

测试验证:

[root@master01 6]# curl --user-agent "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/6531.22.7" http://java.zhang-qing.com/appone -i

HTTP/1.1 301 Moved Permanently
Date: Thu, 10 Apr 2025 07:58:02 GMT
Content-Type: text/html
Content-Length: 162
Connection: keep-alive
Location: https://m.baidu.com

环境复原

[root@master01 6]# k delete -f ingress-nginx-header.yaml -f java.yaml

四、总结