I have a NGINX ingress on my Azure Kubernetes Cluster which I deployed some time ago using the Kubernetes helm chart (https://github.com/kubernetes/ingress-nginx)
I am trying to add rate limiting based on a custom header (X-Machine-Id).I cannot used the pre-made annotations made available by kubernetes nginx as they are IP-based and we have clusters of clients under the same IP.
Helm chart version: ingress-nginx-4.1.4
App version (NGINX) 1.2.1
I have read many blog posts and SO questions, but still no luck:
- https://www.nginx.com/blog/rate-limiting-nginx/#limit_req_zone
- https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations
- Rate limit in nginx based on http header
- https://faun.pub/global-rate-limiting-with-kubernetes-nginx-ingress-controller-fb0453447d65
- Set limit_req for specific location in Nginx Ingress
- Rate limit requests based on HTTP header value on nginx-ingress
Based on the reads above, I have added a http-snippet entry in the configmap of the ingress resource (in the same namespace):
data:
http-snippet: |-
limit_req_zone $http_x_machine_id zone=one:10m rate=1r/s;
I also tried the following:
data:
http-snippet: |-
map $http_x_machine_id $limit {
default "";
"~.+" $http_x_machine_id;
}
limit_req_zone $limit zone=one:10m rate=1r/s;
Then I add this to the configuration-snippet annotation in my Ingress resource (adding all snippets for completeness):
nginx.ingress.kubernetes.io/configuration-snippet: |
rewrite ^(.*/uiconfig)$ $1/ permanent;
rewrite ^(.*/auth-ui)$ $1/ permanent;
more_set_headers "X-XSS-Protection: 1; mode=block";
more_set_headers "X-Content-Type-Options: nosniff";
server_tokens off;
more_clear_headers "Server";
gzip_vary off;
limit_req zone=one burst=10 nodelay;
limit_req_log_level notice;
limit_req_status 429;
When I try to apply the changes on the configuration-snippet of the ingress resouce, I get the following error:
Failed to save resource: {"error":{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"admission webhook \"validate.nginx.ingress.kubernetes.io\" denied the request: (...) (...) [emerg] zero size shared memory zone \"one\"\nnginx: configuration file /tmp/nginx/nginx-cfg2052066727 test failed\n\n
The error is telling me that it's unable to find a memory zone called 'one'. However when I download the config file for my ingress the variable appears there:
# Custom code snippet configured in the configuration configmap
limit_req_zone $http_x_dcsconnect_machine_id zone=one:20m rate=1r/s;
Any hint would be appreciated. I am not very familiar with lua and nginx, as I always use helm charts to deploy ingress resources.