Nginx Ingress - how to set redirect to external site if there is no marching route?

11/13/2019

beginner here. I am currently trying to configure Ingress to do two things - if the fibonacci route exists, redirect to the function and pass the parameter, if the route doesnt exist, redirect to another website and attach the input there.

So, for example, there are two basic scenarios.

  1. https://xxx.amazonaws.com/fibonacci/10 -> calls fibonacci function with parameter 10 (that works)
  2. https://xxx.amazonaws.com/users/jozef -> calls redirect function which redirects to https://api.github.com/users/jozef

I think the service doing the redirect is written correctly, it looks like this.

kind: Service
apiVersion: v1
metadata:
  name: api-gateway-redirect-service
spec:
  type: ExternalName
  externalName: api.github.com
  ports:
    - protocol: TCP
      targetPort: 443
      port: 80 # Default port for image

This is how my Ingress looks like. Experimented with default-backend annotation as well as various placement of the default backend, nothing worked. When I try to curl https://xxx.amazonaws.com/users/jozef, I keep getting 301 message but the location is unchanged. The final output looks like this

HTTP/1.1 301 Moved Permanently
Server: openresty/1.15.8.2
Date: Wed, 13 Nov 2019 15:52:14 GMT
Content-Length: 0
Connection: keep-alive
Location: https://xxx.amazonaws.com/users/jozef

* Connection #0 to host xxx.amazonaws.com left intact
* Maximum (50) redirects followed
curl: (47) Maximum (50) redirects followed

Does someone have an idea what am I doing wrong? This is my Ingress. Also, if it helps, we use Kubernetes version 1.14.6. Thanks a million

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-nginx
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
  - http:
      paths:
        - path: /fibonacci/(.*)
          backend:
            serviceName: fibonacci-k8s-service
            servicePort: 80
        - path: /(.*)
          backend:
            serviceName: api-gateway-redirect-service
            servicePort: 80
-- Jozef
kubernetes
kubernetes-ingress
nginx
nginx-ingress

2 Answers

11/14/2019

So I ve kept reading about this subject and it turns out that ingress controllers generally don't go through services but connect to pods directly (it looks up pods selected by the service and configures them into nginx), wich makes the use case here (connecting to the serice that isn't backed up by anypod) destined to fail.

HOWEVER, it looks like that in recent version this has been supported by nginx ingress controller with nginx+ ONLY so far.

references:

Support for Type ExternalName Services

Ingress uses Endpoints to configure PODs Ips in nginx config to load balance

-- Ezwig
Source: StackOverflow

11/22/2019

The resolution to the problem was the addition of the 'Host: hostname' header in the curl command.

The service that was handling the request needed Host: hostname header to properly reply to this request. After the hostname header was provided the respond was correct.

Links:

Curl docs

Ingress docs

-- Dawid Kruk
Source: StackOverflow