Search code examples
kubernetesurl-rewritingnginx-ingress

How to rewrite URLs for some specific paths?


I have read in ingress-nginx documentation that the rewrite is being performed thanks to an annotation like this:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
  name: rewrite
  namespace: default
spec:
  rules:
  - host: rewrite.bar.com
    http:
      paths:
      - backend:
          serviceName: http-svc
          servicePort: 80
        path: /something(/|$)(.*)

I have a case where I have multiple hosts and I want URL rewriting for some particular paths only:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
  name: ingress
spec:
  rules:
    - host: somehost.westeurope.cloudapp.azure.com
      http:
        paths:
        - path: /rest-smtp-sink # I want to rewrite this path
          pathType: Prefix
          backend:
            service:
              name: rest-smtp-sink-svc
              port:
                number: 80
        - path: /backend # This one too
          pathType: Prefix
          backend:
            service:
              name: server-svc
              port:
                number: 80
        - path: / # But not this one
          pathType: Prefix
          backend:
            service:
              name: client-svc
              port:
                number: 80

However, the annotation seems to be global. How do I enable URL rewriting for some paths only?


Solution

  • I managed to get the desired result with this configuration:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      annotations:
        kubernetes.io/ingress.class: nginx
        cert-manager.io/cluster-issuer: letsencrypt
        nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
        nginx.ingress.kubernetes.io/rewrite-target: /$2
      name: ingress
    spec:
      rules:
        - host: somehost.westeurope.cloudapp.azure.com
          http:
            paths:
            - path: /rest-smtp-sink(/|$)(.*)
              pathType: Prefix
              backend:
                service:
                  name: rest-smtp-sink-svc
                  port:
                    number: 80
            - path: /backend(/|$)(.*)
              pathType: Prefix
              backend:
                service:
                  name: server-svc
                  port:
                    number: 80
            - path: /()(.*)
              pathType: Prefix
              backend:
                service:
                  name: client-svc
                  port:
                    number: 80
    

    As the nginx.ingress.kubernetes.io/rewrite-target annotation is global, I've used /$2 as the rewrite target and /()(.*) as a noop for the root path.