<p>I'm trying to create a GKE Ingress that points to two different backend services based on path. I've seen a few posts explaining this is only possible with an nginx Ingress because gke ingress doesn't support rewrite-target. However, this Google documentation, <a href="https://cloud.google.com/kubernetes-engine/docs/concepts/ingress#multiple_backend_services" rel="nofollow noreferrer">GKE Ingresss - Multiple backend services</a>, seems to imply otherwise. I've followed the steps in the docs but haven't had any success. Only the service that is available on the path prefix of <code>/</code> is returned. Any other path prefix, like <code>/v2</code>, returns a 404 Not found.</p>
<p>Details of my setup are below. Is there an obvious error here -- is the Google documentation incorrect and this is only possible using nginx ingress?</p>
<pre><code>-- Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: app-static-ip
    networking.gke.io/managed-certificates: app-managed-cert
spec:
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80
      - path: /v2
        pathType: Prefix
        backend:
          service:
            name: api-2-service
            port:
              number: 8080

-- Service 1
apiVersion: v1
kind: Service
metadata:
  name: api-service
  labels:
    app: api
spec:
  type: NodePort
  selector:
    app: api
  ports:
  - port: 80
    targetPort: 5000

-- Service 2
apiVersion: v1
kind: Service
metadata:
  name: api-2-service
  labels:
    app: api-2
spec:
  type: NodePort
  selector:
    app: api-2
  ports:
  - port: 8080
    targetPort: 5000
</code></pre>

<p>GCP Ingress supports multiple paths. This is also well described in <a href="https://cloud.google.com/kubernetes-engine/docs/tutorials/http-balancer" rel="nofollow noreferrer">Setting up HTTP(S) Load Balancing with Ingress</a>. For my test I've used both Hello-world v1 and v2.</p>
<p>There are 3 possible issues.</p>
<ul>
<li>Issue is with container ports opened. You can check it using netstat:</li>
</ul>
<pre><code>$ kk exec -ti first-55bb869fb8-76nvq -c container -- bin/sh
/ # netstat -plnt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 :::8080                 :::*                    LISTEN      1/hello-app
</code></pre>
<ul>
<li><p>Issue might be also caused by the <code>Firewall</code> configuration. Make sure you have proper settings. (In general, in the new cluster I didn't need to add anything but if you have more stuff and have specific Firewall configurations it might block).</p>
</li>
<li><p>Misconfiguration between <code>port</code>, <code>containerPort</code> and <code>targetPort</code>.</p>
</li>
</ul>
<p>Below my example:</p>
<p><strong>1st deployment with</strong></p>
<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: first
  labels:
    app: api
spec:
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      containers:
        - name: container
          image: gcr.io/google-samples/hello-app:1.0
          ports:
          - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: api-service
  labels:
    app: api
spec:
  type: NodePort
  selector:
    app: api
  ports:
  - port: 5000
    targetPort: 8080
</code></pre>
<p><strong>2nd deployment</strong></p>
<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: second
  labels:
    app: api-2
spec:
  selector:
    matchLabels:
      app: api-2
  template:
    metadata:
      labels:
        app: api-2
    spec:
      containers:
        - name: container
          image: gcr.io/google-samples/hello-app:2.0
          ports:
          - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: api-2-service
  labels:
    app: api-2
spec:
  type: NodePort
  selector:
    app: api-2
  ports:
  - port: 6000
    targetPort: 8080
</code></pre>
<p><strong>Ingress</strong></p>
<pre><code>apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
spec:
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 5000
      - path: /v2
        pathType: Prefix
        backend:
          service:
            name: api-2-service
            port:
              number: 6000
</code></pre>
<p><strong>Outputs</strong>:</p>
<pre><code>$ curl 35.190.XX.249
Hello, world!
Version: 1.0.0
Hostname: first-55bb869fb8-76nvq
$ curl 35.190.XX.249/v2
Hello, world!
Version: 2.0.0
Hostname: second-d7d87c6d8-zv9jr
</code></pre>
<p>Please keep in mind that you can also use <code>Nginx Ingress</code> on GKE by adding specific annotation.</p>
<pre><code>kubernetes.io/ingress.class: &quot;nginx&quot; 
</code></pre>
<p>Main reason why people use <code>nginx ingress</code> on <code>GKE</code> is using <code>rewrite</code> annotation and possibility to use <code>ClusterIP</code> or <code>NodePort</code> as serviceType, where <code>GCP ingress</code> allows only <code>NodePort</code> serviceType.</p>
<p>Additional information you can find in <a href="https://cloud.google.com/kubernetes-engine/docs/concepts/ingress" rel="nofollow noreferrer">GKE Ingress for HTTP(S) Load Balancing</a></p>
