nginx - 为 Nginx Ingress 中的特定位置设置 limit_req
问题描述
我正在尝试为limit_req
Kubernetes ingress-nginx 中的特定路径设置速率限制选项,以防止强制身份验证。
我已经limit_req_zone
使用 ConfigMap 定义:
http-snippet: |
limit_req_zone $the_real_ip zone=authentication_ratelimit:10m rate=1r/s;
接下来,我使用注释来添加自定义位置块:
nginx.ingress.kubernetes.io/configuration-snippet: |
location ~* "^/authenticate$" {
limit_req zone=authentication_ratelimit nodelay;
more_set_headers "x-test: matched";
}
这会产生 nginx.conf:
server {
# - - 8< - -
location / {
# - - 8< - -
location ~* "^/authenticate$" {
limit_req zone=authentication_ratelimit nodelay;
more_set_headers "x-test: matched";
}
proxy_pass http://upstream_balancer;
proxy_redirect off;
}
结果是/authenticate
始终返回 HTTP 503(带有 x-test 标头)。来自入口访问日志的消息:
<ip> - [<ip>] - - [04/Jan/2019:15:22:07 +0000] "POST /authenticate HTTP/2.0" 503 197 "-" "curl/7.54.0" 172 0.000 [-] - - - - 1a63c9825c9795be1378b2547e29992d
proxy_pass
我怀疑这可能是因为嵌套位置块和(但这只是一个疯狂的猜测)之间的冲突。
我尝试了哪些其他选择?
- 使用
server-snippet
注释而不是configuration-snippet
-/authenticate
返回 404 因为proxy_pass
未配置 - 使用
nginx.ingress.kubernetes.io/limit-rpm
注释 - 对整个应用程序强制速率限制,这不是我想要的。
问题是为什么自定义位置块以 503 响应?我该如何调试呢?增加 nginx 日志记录级别会提供有关 503 的更多详细信息吗?或更一般的问题:我可以在 ingress-nginx 中注入自定义位置块吗?
解决方案
这可以通过使用 map 来完成,并且不考虑具有空键值的请求这一事实。
http-snippets: |
map $uri $with_limit_req {
default 0;
"~*^/authenticate$" 1;
}
map $with_limit_req $auth_limit_req_key {
default '';
'1' $binary_remote_addr; # the limit key
}
limit_req_zone $auth_limit_req_key zone=authentication_ratelimit:10m rate=1r/s;
并使用注释添加自定义位置块:
nginx.ingress.kubernetes.io/configuration-snippet: |
limit_req zone=authentication_ratelimit nodelay;
或者,如果您使用来自 nginxinc 的入口
nginx.org/location-snippets:
limit_req zone=authentication_ratelimit nodelay;
在这种情况下,检查请求是否需要在地图级别进行速率限制处理。
我的意见是:最好限制应用程序级别的请求,就像您对入口级别进行速率限制一样,这取决于入口 pod 的数量。
推荐阅读
- kubernetes - Kubernetes 滚动更新仅通过更改 env 变量
- ios - 使用已弃用的 kSecAttrAccessibleAlwaysThisDeviceOnly 会发生什么?
- javascript - 如何制作实用程序类或功能组件以公开少数常用实用程序方法
- css - 鼠标离开时悬停效果跳跃
- php - MYSQL 查询以排除结果中具有空值的列
- python - 如何根据文件夹结构自动化和调整 Python 代码
- c# - void 数组扩展方法什么都不做
- powershell - ForEach 和 $_ 空结果
- html - 覆盖而不使用相对父级和填充子级
- c# - 如何使用 C# 读取 MiCOM 继电器的保持寄存器(ModBus RTU over RS-485 通信)