Multiple Rewrites with nginx ingress annotations on Kubernetes?

9/10/2019

I believe that I must create multiple Ingress resources to achieve the desired effect, but must ask, is it possible to have multiple rewrite annotations with nginx (community) controller for the same host?

I have the following, but it won't work, as I understand it, because there is no way to link the rewrite rule to the path explicitly. In this case, I suppose it could use the fact that there are different numbers of capture groups, but that wouldn't always be the case.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: api-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: https://staging.example.com/keyword-lnk/badnewsbears/$1/$2
    nginx.ingress.kubernetes.io/rewrite-target: https://staging.example.com/lnk/$2
    certmanager.k8s.io/cluster-issuer: staging-letsencrypt-prod

spec:
  rules:
    - host: staging.example.com
      http:
        paths:
         - path: /
           backend:
              serviceName: api-service
              servicePort: http
    - host: badnewsbears.example.com
      http:
        paths:
          - backend:
              serviceName: api-service
              servicePort: http
            path: ^(/a/)(.*)$
          - backend:
              serviceName: api-service
              servicePort: http
            path: ^/([tbc])/(.*)
  tls:
  - hosts:
    - staging.example.com
    - badnewsbears.example.com
    secretName: letsencrypt-prod-issuer-account-key
    # ^ must be set to the key matching the annotation
    # certmanager.k8s.io/cluster-issuer above

The goal is to have requests to staging.example.com not have rewrites, but requests to badnewsbears.example.com/t/soup rewrite to https://staging.example.com/keyword-lnk/badnewsbears/t/soup, while badnewsbears.example.com/a/soup yields https://staging.example.com/lnk/$2

Is there a way to specify a mapping of rewrite target->path in the Ingress (or elsewhere), or will I have to separate out the different rewrite rules for the same host into different

-- Ben
kubernetes
kubernetes-ingress
nginx-ingress

2 Answers

9/11/2019

TL;DR; you're not really meant to be able to configure multiple rewrites for the kubernetes/ingress-nginx controller type. Although it is possible to hack this together in a limited fashion using regex based rewrites with capture groups, as explained in this answer I posted to How to proxy_pass with nginx-ingress? .

Hope this helps.

-- cewood
Source: StackOverflow

9/11/2019
  1. You can create multiple ingresses with the same host and different path applying the annotation. So that would be the solution you suspected in the first place.

  2. You could consider trying Nginx Plus based Ingress.

To configure URI rewriting you need to add the nginx.org/rewrites annotation to your Ingress resource definition. The annotation syntax is as follows:

nginx.org/rewrites: "serviceName=service1 rewrite=rewrite1[;serviceName=service2 rewrite=rewrite2;...]"

Here is the official example.

Please let me know if that helped.

-- OhHiMark
Source: StackOverflow