Setup Ingress-Nginx rate limit rps for a specific path

5/26/2019

I am using Kubernetes Kops. I want to set rate limit rps at Ingress-Nginx level for a specific path only.

I know about

nginx.ingress.kubernetes.io/limit-rps 

If I set this in Ingress rules then it will be applicable for all the routes. But, I want to apply it for a specific route. Let's say, when I am trying to access

/login

I want to set rps limit to 100 for the path /login

nginx.ingress.kubernetes.io/limit-rps: 100

This is my Ingress rules config,

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: staging-ingress-rules
  namespace: staging
  annotations:
    kubernetes.io/ingress.class: 'nginx'
    nginx.ingress.kubernetes.io/proxy-body-size: '0'
spec:
  rules:
  - host: staging.mysite.com
    http:
      paths:
      - path: /login
        backend:
          serviceName: login_site
          servicePort: 80
      - path: /registration
        backend:
          serviceName: registration_site
          servicePort: 80
-- cyberoy
amazon-web-services
docker
kubernetes
kubernetes-ingress
nginx-ingress

1 Answer

5/27/2019

It's possible to slightly abuse the config for ingress-nginx by adding multiple Ingress definitions for the same hostname. ingress-nginx will merge the rules/routes together. The config will become harder to manage though and you are getting towards the limits of what nginx proxying can do for you.

Other options

Traefik has a rate limit middleware that can be applied to routes.

Also look at something like kong or istio if you want to start managing individual services with more detail.

Nginx Ingress config

Creating a structure to your naming conventions will be important here so you know which Ingress houses which routes. Using the route path in the Ingress name is the where I would start but your use case may vary:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: staging-ingress-rules-registration
  annotations:
    kubernetes.io/ingress.class: 'nginx'
    nginx.ingress.kubernetes.io/proxy-body-size: '0'
    nginx.ingress.kubernetes.io/limit-rps: '10'
spec:
  rules:
  - host: staging.mysite.com
    http:
      paths:
      - path: /registration
        backend:
          serviceName: registration-site
          servicePort: 80
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: staging-ingress-rules-login
  annotations:
    kubernetes.io/ingress.class: 'nginx'
    nginx.ingress.kubernetes.io/proxy-body-size: '0'
    nginx.ingress.kubernetes.io/limit-rps: '100'
spec:
  rules:
  - host: staging.mysite.com
    http:
      paths:
      - path: /login
        backend:
          serviceName: login-site
          servicePort: 80

I'm not sure how host wide or server wide annotations (like nginx.ingress.kubernetes.io/ssl-ciphers) would need to be managed. If they all merge nicely then maybe create a special Ingress just to house those. If not you might end up managing host settings across all Ingress configs which will be a pain.

-- Matt
Source: StackOverflow