Ingress rules not works

10/22/2018

I use GCE and try to expose an application via ingress. But path rules don't work.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
    name: front-ingress
    namespace: {{ .Release.Namespace }}
    annotations:
        {{ if eq .Values.env "dev" }}
        kubernetes.io/ingress.global-static-ip-name: "test-ip"
        {{ else }}
        cloud.google.com/load-balancer-type: "Internal"
        {{ end }}
spec:
    rules:
    -   host: {{ .Values.domain }}
        http:
            paths:
            -   path: /
                backend:
                    serviceName: front-service
                    servicePort: 80
            -   path: /api/
                backend:
                    serviceName: backend-service
                    servicePort: 80

When site opened in browser - all files return 404. When I open file by url, I receive: default backend - 404. If I set default backend via annotations - all files loaded, but /api requests failed - 404 error.

What it can be?

The main idea: test branch on site subdomain. k8s namespace = branch name. Ingress deployed to every namespace with a different host in rules. Global static IP set by annotation and set in GCE Cloud DNS.

Thanks.

UPDATE:

If I use annotation kubernetes.io/ingress.class: "gce" and path: /* and /api/* - site works perfectly. But because I use global static IP, I can't create more than one ingress per IP. If I use kubernetes.io/ingress.class: "nginx" - site returns error: default backend - 404

-- Serhii Koberniuk
google-compute-engine
ingres
kubernetes

1 Answer

10/23/2018

You can actually create multiple ingresses using the same external IP address. You just have to make sure that they are under different host (or hostname rules), so the paths don't interfere with each other. Every host represents a server {} block in the nginx configs with a unique server_name.

Ingress1:

spec:
    rules:
    -   host: host1.domain1
        http:
            paths:
            -   path: /
                backend:
                    serviceName: front-service1
                    servicePort: 80
            -   path: /api/
                backend:
                    serviceName: backend-service1
                    servicePort: 80

Ingress2:

-   host: host2.domain2
        http:
            paths:
            -   path: /
                backend:
                    serviceName: front-service2
                    servicePort: 80
            -   path: /api/
                backend:
                    serviceName: backend-service2
                    servicePort: 80

If you want to use an externalIP it's still doable, but you just have to use a separate ingress controller with a different ingress class name. For example, with the nginx ingress controller you can use the --ingress-class option:

ingress class

Also if you don't specify an --ingress-class in your first ingress controller you will have to configure it too, otherwise like the option says, the first ingress will satisfy all the classes.

-- Rico
Source: StackOverflow