{"id":1216,"date":"2023-04-06T16:28:07","date_gmt":"2023-04-06T08:28:07","guid":{"rendered":"https:\/\/www.linuxdevops.cn\/?p=1216"},"modified":"2023-04-07T09:52:04","modified_gmt":"2023-04-07T01:52:04","slug":"how-to-implement-global-speed-limiting-with-k8-nginx-ingress","status":"publish","type":"post","link":"https:\/\/www.linuxdevops.cn\/2023\/04\/how-to-implement-global-speed-limiting-with-k8-nginx-ingress\/","title":{"rendered":"\u4f7f\u7528 Kubernetes NGINX Ingress\u8fdb\u884c\u5168\u5c40\u901f\u7387\u9650\u5236"},"content":{"rendered":"
\u6700\u8fd1\u6211\u9700\u8981\u5728\u751f\u4ea7\u7cfb\u7edf\u4e0a\u4e3a Kubernetes \u90e8\u7f72\u5b9e\u65bd\u5168\u5c40\u901f\u7387\u9650\u5236\u3002\u6709\u8bb8\u591a\u89e3\u51b3\u65b9\u6848\uff0c\u4f8b\u5982 Azure WAF\uff0c\u5b83\u63d0\u4f9b\u901f\u7387\u9650\u5236\uff0c\u4f46\u5b83\u4eec\u90fd\u662f\u9488\u5bf9\u6bcf\u4e2a\u5ba2\u6237\u7aef\u7684\u901f\u7387\u9650\u5236\uff0c\u8fd9\u610f\u5473\u7740\u6211\u4eec\u5e94\u7528\u7684\u4efb\u4f55\u89c4\u5219\u90fd\u5c06\u5e94\u7528\u4e8e\u5355\u4e2a\u5ba2\u6237\u7aef\uff0c\u8fd9\u662f\u8fdb\u884c\u901f\u7387\u9650\u5236\u7684\u4e00\u79cd\u65b9\u5f0f\uff0c\u4f46\u6211\u4eec\u9700\u8981\u5168\u5c40\u901f\u7387-\u4e5f\u6709\u9650\u5236\u3002<\/p>\n
<\/p>\n
Image from https:\/\/articles.bplans.com<\/a><\/p>\n \u4e8b\u5b9e\u8bc1\u660e\uff0c\u6700\u8457\u540d\u7684\u901f\u7387\u9650\u5236\u65b9\u6cd5\u662fPer Client Rate Limiting<\/strong>\u3002\u6839\u636e Azure \u652f\u6301\uff0c\u7531\u4e8e DDoS \u4fdd\u62a4\uff0c\u6211\u4eec\u4e0d\u9700\u8981\u5168\u5c40\u901f\u7387\u9650\u5236\u3002\u53ea\u6709\u5f53\u6211\u4eec\u770b\u5230\u5927\u91cf\u975e\u6cd5\u6d41\u91cf\u8bd5\u56fe\u5230\u8fbe\u670d\u52a1\u5668\u65f6\uff0cDDoS \u624d\u4f1a\u751f\u6548\u3002\u4f46\u662f\uff0c\u5982\u679c\u6211\u4eec\u7684\u5e94\u7528\u7a0b\u5e8f\u65e0\u6cd5\u63d0\u4f9b\u5927\u91cf\u5408\u6cd5\u6d41\u91cf\u600e\u4e48\u529e\uff1f\u8fd9\u5c31\u662f\u5168\u5c40\u901f\u7387\u9650\u5236\u53d1\u6325\u4f5c\u7528\u7684\u5730\u65b9\u3002\u5b83\u4fdd\u62a4\u6211\u4eec\u514d\u53d7\u4e24\u4ef6\u4e8b\u7684\u4f24\u5bb3\u3002<\/p>\n \u6211\u7684\u8981\u6c42\u662f\u5728\u4e0d\u5411\u7cfb\u7edf\u6dfb\u52a0\u65b0\u8dc3\u70b9\u7684\u60c5\u51b5\u4e0b\u5bf9\u73b0\u6709\u57fa\u7840\u8bbe\u65bd\u5b9e\u65bd\u5168\u5c40\u901f\u7387\u9650\u5236\uff0c\u8fd9\u610f\u5473\u7740\u6211\u5fc5\u987b\u5bf9\u7cfb\u7edf\u4e0a\u5df2\u6709\u7684\u67d0\u4e9b\u7ec4\u4ef6\u5b9e\u65bd\u5168\u5c40\u901f\u7387\u9650\u5236\u3002\u5728\u4e92\u8054\u7f51\u4e0a\u641c\u7d22\u4e86\u51e0\u4e2a\u5c0f\u65f6\u5e76\u6ca1\u6709\u7ed9\u6211\u4e00\u4e2a\u5f88\u597d\u7684\u89e3\u51b3\u65b9\u6848\uff0c\u5e76\u4e14\u9274\u4e8e Azure WAF \u4e0d\u652f\u6301\u5168\u5c40\u901f\u7387\u9650\u5236\uff0c\u552f\u4e00\u7684\u9009\u62e9\u662f\u5728 NGINX Ingress \u63a7\u5236\u5668\u4e0a\u5b9e\u65bd\u5168\u5c40\u901f\u7387\u9650\u5236\u3002<\/p>\n Annotations - NGINX Ingress Controller<\/a><\/p>\n<\/blockquote>\n \u7136\u800c\uff0c\u4f7f\u7528 NGINX Ingress\u63a7\u5236\u5668\u5b9e\u73b0\u5168\u5c40\u901f\u7387\u9650\u5236\u9700\u8981\u4e00\u4e2a\u989d\u5916\u7684 \u7ecf\u8fc7\u8fdb\u4e00\u6b65\u641c\u7d22\uff0c\u6211\u53d1\u73b0\u4e86\u4ee5\u4e0b\u6587\u7ae0\uff0c\u8fd9\u4e9b\u6587\u7ae0\u89e3\u91ca\u4e86\u5982\u4f55\u5c06 NGINX http_limit_req \u6a21\u5757\u4e0e Kubernetes Ingress Controller \u4e00\u8d77\u4f7f\u7528\uff08\u8fd9\u4f3c\u4e4e\u662f\u552f\u4e00\u4e00\u7bc7\u5173\u4e8e\u5982\u4f55\u4f7f\u7528 K8s \u6267\u884c\u6b64\u64cd\u4f5c\u7684\u535a\u5ba2\u6587\u7ae0\uff09<\/p>\n \u4f7f\u7528 NGINX Ingress\u5bf9 Kubernetes \u5e94\u7528\u7a0b\u5e8f\u8fdb\u884c\u901f\u7387\u9650\u5236<\/a><\/p>\n<\/blockquote>\n \u4e0a\u8ff0\u5e16\u5b50\u4e2d\u63d0\u5230\u7684\u65b9\u6cd5\u6709\u4e24\u4e2a\u4e3b\u8981\u95ee\u9898\u3002<\/p>\n \u95ee\u9898 1 \u662f\u6211\u4e0d\u5f97\u4e0d\u5fcd\u53d7\u7684\uff0c\u56e0\u4e3a\u5f88\u660e\u663e\uff0c\u771f\u6b63\u7684\u5168\u5c40\u901f\u7387\u9650\u5236\u4e0d\u518d\u53ef\u884c\u3002\u4f46\u662f\uff0c\u5bf9\u4e8e\u95ee\u9898 2\uff0c\u6211\u5df2\u7ecf\u5bf9 Azure WAF \u8fdb\u884c\u4e86\u6bcf\u5ba2\u6237\u7aef\u901f\u7387\u9650\u5236\uff0c\u56e0\u6b64\u8fd9\u79cd\u65b9\u6cd5\u6ca1\u6709\u4ea7\u751f\u4efb\u4f55\u7ed3\u679c\u3002<\/p>\n \u4f3c\u4e4e\u7f3a\u5c11\u6709\u5173 ngx_http_limit_req_module \u7684\u6587\u6863\uff0c\u4f46\u662f\uff0cNGINX \u5bf9\u6b64\u6709\u4e00\u4e2a\u975e\u5e38\u597d\u7684\u6587\u6863\uff08\u4e0d\u662f NGINX K8 \u63a7\u5236\u5668\uff0c\u800c\u662f\u666e\u901a NGINX\uff09<\/p>\n \u4e0a\u9762\u7684\u793a\u4f8b\u5728\u6bcf\u4e2a\u7528\u6237\u7684 \/login\/ \u7aef\u70b9\u4e0a\u5b9e\u73b0\u4e86\u6bcf\u79d2 10 \u4e2a\u8bf7\u6c42\u7684\u901f\u7387\u9650\u5236\u3002<\/p>\n \u7531\u4e8e\u8fd9\u662f\u6bcf\u4e2a\u5ba2\u6237\u7aef\u7684\u901f\u7387\u9650\u5236\uff0c\u6211\u60f3\u5bf9\u5176\u8fdb\u884c\u4fee\u8865\u4ee5\u5b9e\u73b0\u6bcf\u4e2apod \u7684\u5168\u5c40\u901f\u7387\u9650\u5236\u3002<\/strong>\u9605\u8bfb\u6587\u6863\u5bf9\u4e0a\u8ff0\u547d\u4ee4\u53c2\u6570\u89e3\u91ca\u5982\u4e0b<\/p>\n \u90a3\u662f\u4e92\u8054\u7f51\u4e0a\u6ca1\u6709\u592a\u591a\u4fe1\u606f\u7684\u53e6\u4e00\u90e8\u5206\u3002K8s NGINX Ingress \u63a7\u5236\u5668\u5305\u542b\u4e00\u7ec4\u7528\u4e8e\u901f\u7387\u9650\u5236\u7684\u6ce8\u91ca\uff0c\u4f8b\u5982 \u56e0\u6b64\uff0c\u8981\u5b9e\u73b0\u8fd9\u4e00\u70b9\uff0c\u60a8\u5fc5\u987b\u4f7f\u7528\u53e6\u4e00\u79cd\u89e3\u51b3\u65b9\u6cd5\u3002\u90a3\u5c31\u662f\u4f7f\u7528\u81ea\u5b9a\u4e49\u4ee3\u7801\u5c06\u5916\u90e8 configmap \u6302\u8f7d\u5230\u4f60\u7684 K8s \u90e8\u7f72\u4e2d\u3002<\/p>\n \u4e0a\u9762\u7684 ConfigMap \u5c06\u5728\u60a8\u7684 K8 NGINX Ingress Controller \u4e0a\u521b\u5efa\u4e00\u4e2aPer Pod Global Rate Limit\uff08\u4f5c\u7528\u4e8e\u6bcf\u4e2aPod\u7684\u9650\u901f\uff09<\/strong>\u3002<\/p>\n \u6216\u8005\uff0c\u5982\u679c\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4e2d\u9700\u8981\u591a\u4e2a\u4e0d\u540cIngress\u9650\u901f\u8d44\u6e90\uff0c\u60a8\u53ef\u4ee5\u5220\u9664\u4e0a\u8ff0 location-snippet \u5e76\u5c06\u5176\u4f5c\u4e3aconfiguration-snippet \u6dfb\u52a0\u5230Ingress\u8d44\u6e90\u4e2d\u3002\u5b83\u5c06\u5141\u8bb8\u60a8\u4e3a\u6bcf\u4e2aIngress\u8d44\u6e90\u6dfb\u52a0\u5168\u5c40\u901f\u7387\u9650\u5236\u3002\u4f46\u662f\u8bf7\u6ce8\u610f\uff0c\u60a8\u5e94\u7528\u7684\u9650\u5236\u5c06\u5355\u72ec\u5e94\u7528\u4e8e\u60a8\u62e5\u6709\u7684\u6240\u6709Ingress\u526f\u672c\u3002<\/p>\n \u4f8b\u5982\uff1a<\/p>\n\u4e3a\u4ec0\u4e48\u8981\u8fdb\u884c\u5168\u5c40\u901f\u7387\u9650\u5236\uff1f<\/h1>\n
\n
\u53ef\u7528\u4e8e\u5168\u5c40\u901f\u7387\u9650\u5236\u7684\u89e3\u51b3\u65b9\u6848<\/h1>\n
\n
memcached<\/code>pod \u6765\u540c\u6b65 NGINX pod \u4e4b\u95f4\u7684\u8ba1\u6570\u5668\u3002\u5728\u4e0e Kubernetes Slack \u793e\u533a\u4ea4\u8c08\u540e\uff0c\u6211\u53d1\u73b0\u4efb\u4f55\u5168\u5c40\u901f\u7387\u9650\u5236\u7684\u65b9\u6cd5\u90fd\u4f1a\u5728\u6027\u80fd\u4e0a\u9020\u6210\u4e25\u91cd\u7684\u74f6\u9888\uff0c\u8fd9\u6392\u9664\u4e86\u8fd9\u79cd\u65b9\u5f0f\u4f5c\u4e3a\u8fdb\u884c\u5168\u5c40\u901f\u7387\u9650\u5236\u7684\u9009\u9879\u3002<\/p>\n
ngx_http_limit_req_module<\/h1>\n
\n
\n
Time to get Creative<\/h1>\n
\n
\n
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r\/s;\n\nserver {\n location \/login\/ {\n limit_req zone=mylimit;\n\n proxy_pass http:\/\/my_upstream;\n }\n}<\/code><\/pre>\n
limit_req_zone <key> zone=<zone_name>:<allocated_memory> rate=<rate_limit><\/code><\/pre>\n
\u5982\u4f55\u7528 K8s \u5b9e\u73b0<\/h1>\n
nginx.ingress.kubernetes.io\/limit-connections , nginx.ingress.kubernetes.io\/limit-rps (<\/code>https:\/\/kubernetes.github.io\/ingress-nginx\/user-guide\/nginx-configuration\/annotations\/#rate-limiting\uff09\u3002\u4f46\u662f\u8fd9\u4e9b\u518d\u6b21\u521b\u5efa\u4e86\u6bcf\u4e2a\u5ba2\u6237\u7aef\u901f\u7387\u9650\u5236\uff0c\u800c\u4e0d\u662f\u5168\u5c40\u9650\u5236<\/a>\u3002<\/p>\n
kind: ConfigMap\napiVersion: v1\nmetadata:\n name: nginx-ingress-ingress-nginx-controller\n namespace: ingress-basic\ndata:\n http-snippet : |\n limit_req_zone $binary_remote_addr zone=rd_ingress-hello_rps:5m rate=100r\/m ;\n location-snippet: |\n limit_req zone=rd_ingress-hello_rps burst=20 nodelay;\n limit_req_status 429;<\/code><\/pre>\n
apiVersion: extensions\/v1beta1\nkind: Ingress\nmetadata:\nname: test-ingress\nannotations:\n nginx.ingress.kubernetes.io\/configuration-snippet: |\n limit_req zone=mgt burst=20 nodelay;\n limit_req_status 503;\nspec:\n tls:\n - hosts:\n - test.com\n rules:\n - host: test.com\n http:\n paths:\n - path: \/\n backend:\n serviceName: test-service\n servicePort: 9443<\/code><\/pre>\n
\n