Is it possible to rate limit requests based on HTTP header value on nginx-ingress?
Yes, you can do it by creating ConfigMap file with the customized template containing 'limit_req_zone' directive, as shown on official NGINX Ingress examples of custom-annotations usage here.
You should specify the key/variable to the limit_req_zone directive e.g.:
limit_req_zone $http_authorization_key ...
where $http_authorization_key variable corresponds to 'Authorization-Key' request header field*
*the last part of a variable name is the field name converted to lower case with dashes replaced by underscores (from official NGINX doc)
As I didn't have kubernetes nginx ingress from nginxinc suggested solution here didn't work.
Manage to do it through configmap and annotation tweak.
Configmap:
kind: ConfigMap
apiVersion: v1
metadata:
name: nginx-configuration
namespace: ingress-nginx
labels:
app: nginx-ingress
chart: nginx-ingress-1.33.0-dev
release: nginx-ingress
data:
http-snippet: |
limit_req_zone $http_authorization zone=my-zone:20m rate=5r/s;
limit_req_zone $binary_remote_addr zone=my-zone:20m rate=10r/s;
limit_req_zone $http_someheader zone=my-zone:20m rate=20r/s;
Annotation in ingress resource:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/configuration-snippet: |
limit_req zone=my-zone-1 burst=10 nodelay;
limit_req_log_level notice;
limit_req_status 429;
Note: http-snippet is not allowed as annotation!
Example with different throtling for different locations defined by one ingress:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/server-snippet: |
location /content/images/ {
limit_req zone=my-zone-2 burst=50 nodelay;
}
location /content/texts/ {
limit_req zone=my-zone-3 burst=50 nodelay;
}
nginx.ingress.kubernetes.io/configuration-snippet: |
limit_req zone=my-zone-1 burst=10 nodelay;
limit_req_log_level notice;
limit_req_status 429;
Note that defining location here in server-snippet annotation doesn't allow you to define it further down in ingress