re-route of traffic is not working with ingress controller. I feel i mis-understood the re-write annotation?

10/12/2019

Issue with re-write annotation.

Tried using re-write annotation. Not able to get that work.

apiVersion: networking.k8s.io/v1beta1 # for versions before 1.14 use extensions/v1beta1
kind: Ingress
metadata:
  name: hello-whale-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
  - host: hello.whale.info
    http:
      paths:
      - path: /blue|/(.+)
        backend:
          serviceName: hello-blue-whale-svc
          servicePort: 80
      - path: /green|/(.+)
        backend:
          serviceName: hello-green-whale-svc
          servicePort: 80

/Green is showing perfect result , but why not /blue.

-- Vamsi Jakkula
kubernetes
kubernetes-ingress
minikube

2 Answers

10/12/2019

You should see in your logs that the ingress always hits the same backend. Maybe this doc may help you.

I tested myself with two nginx servers as backends, one returning blue and the other green:

apiVersion: networking.k8s.io/v1beta1 # for versions before 1.14 use extensions/v1beta1
kind: Ingress
metadata:
  name: hello-whale-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
    nginx.org/rewrites: "serviceName=green rewrite=/;serviceName=blue rewrite=/"
spec:
  rules:
  - host: stardust
    http:
      paths:
      - path: /green
        backend:
          serviceName: green
          servicePort: 80
      - path: /blue
        backend:
          serviceName: blue
          servicePort: 80

Then, using curl I can reach the right target:

$ curl stardust/green
green
$ curl stardust/blue
blue

And here are the logs of the ingress controller:

10.32.0.1 - - [12/Oct/2019:14:56:12 +0000] "GET /green HTTP/1.1" 200 6 "-" "curl/7.64.1" 132 0.008 [default-green-80] [] 10.32.0.28:80 6 0.008 200 b5ac38db9dd6a7e53d316dc48e9401aa
10.32.0.1 - - [12/Oct/2019:14:56:16 +0000] "GET /blue HTTP/1.1" 200 5 "-" "curl/7.64.1" 131 0.011 [default-blue-80] [] 10.32.0.12:80 5 0.012 200 c438d22db0e80a5206ca8885a48d72f9

I hope it can help you.

-- Stéphane Beuret
Source: StackOverflow

10/15/2019

can you try like this: path: /blue/(.*) – Vasily Angapov 2 days ago

I'd like to add some words of explanation to Vasily Angapov's correct answer posted in question comments so everyone can understand why /blue/(.*) actually works and why /blue|/(.+) will not work and shouldn't be used in this context.

Let's use regexp online interpreter which contains detailed explanation of every character used in our expression and let us experiment with matching different strings to the given regular expression:

/blue|/(.+) basically means we want to match string /blue or any other non-zero string. . means any character except of line termination and + sign is a quantifier which tells us how many times previous character may occur in our string. + denotes one or more occurrences of preceding character so the expression .+ matches a string consisting of one or more different characters (excluding line break).

If you construct an ingress path to be matched with specific string you typically don't want to use |. In this particular context it would mean that you want to match /blue or anything else like /green, /yellow, /red... which doesn't make much sense in this context. You are rather interested to match paths only starting from /blue like /blue/index.html, /blue/second.html or blue/third.php or just /blue itself. Your path may look like this:

/blue/(.+)

and it will match /blue/index.html, /blue/1 but not /blue alone as .+ matches one or more arbitrary characters.

.* on the other hand matches zero or more arbitrary characters so expression /blue/(.*) will match:

/blue, /blue/index.html, /blue/, /blue/1 etc.

-- mario
Source: StackOverflow