How to configure ingress to deploy services to subdomains without creating a new loadbalancer

3/11/2020

I am new to Kubernetes and have an application deployed via GKE on mydomain.com and now want to add another service which should be available on api.mydomain.com without adding a new expensive load balancer. What should the new ingress file for api.mydomain look like? I read the documentation, but cannot figure out how to do this.

This is my first service running on mydomain.com:

kind: Service
apiVersion: v1
metadata:
  name: app-service
spec:
  selector:
    app: app
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: NodePort
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: app-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: "ip"
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
    acme.cert-manager.io/http01-edit-in-place: "true"
    kubernetes.io/tls-acme: "true"
spec:
  rules:
  - host: mydomain.com
    http:
      paths:
      - backend:
          serviceName: app-service
          servicePort: 80
  tls:
  - hosts:
    - mydomain.com
    secretName: my-certs

I tried to use the same configuration for the subdomain api.mydomain.com, but this does not work.

kind: Service
apiVersion: v1
metadata:
  name: api-service
spec:
  selector:
    app: api
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: NodePort
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: api-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: "ip"
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
    acme.cert-manager.io/http01-edit-in-place: "true"
    kubernetes.io/tls-acme: "true"
spec:
  rules:
  - host: api.mydomain.com
    http:
      paths:
      - backend:
          serviceName: api-service
          servicePort: 80
  tls:
  - hosts:
    - api.mydomain.com
    secretName: my-certs-api

Maybe I'm approaching the problem in the wrong way, I'm new in GKE, any suggestions?

-- needRhelp
google-kubernetes-engine
kubernetes
kubernetes-ingress

3 Answers

3/18/2020

As per my understanding you are trying to create one HTTP load balancer with one public IP address for two different domains.

It's doable using standard GKE ingress controller GCE L7 at least for HTTP protocol (see example below).

Please also find documentation page about using multiple SSL certificates with GCE L7 ingress.

Example:
( mydomain.com is replaced with example.com, because... an answer body cannot contain it.)

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: app-ingress
spec:
  rules:
  - host: example.com
    http:
      paths:
      - backend:
          serviceName: app-service
          servicePort: 80
  - host: api.example.com
    http:
      paths:
      - backend:
          serviceName: api-service
          servicePort: 80

Applying this yaml to GKE cluster results creating one HTTP load-balancer with the following Host and path rules:

http://example.com:80/* -> app-service:80 (if app-service health-check passed)
http://example.com:80/* -> default-backend:80 (return 404) (if app-service heath-check fails and default-backend health-check passed)
http://api.example.com:80/* -> api-service:80 (if app-service health-check passed)
http://api.example.com:80/* -> default-backend:80 (return 404) (if api-service heath-check fails and default-backend health-check passed)
http://lb.ip.address:80 -> default-backend:80 (return 404) (if  default-backend health-check passed)

HTTP LB returns 502 if all backends' health-checks are failed.
-- VAS
Source: StackOverflow

3/11/2020

You would generally use a different Ingress Controller than the default ingress-gce. ingress-nginx is very common and easy to get started with, but there are many options so I recommend you research them and pick which one matches your use case best.

-- coderanger
Source: StackOverflow

3/12/2020

Try "nginx" ingress.class . The config shall be like the following (I have removed tls part out it).

Nginx Ingress controller is quite easy and functional.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: double-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
#    nginx.ingress.kubernetes.io/rewrite-target: /$2  ### you can use it to route different paths to different services under the same host
spec:
  rules:
  - host: mydomain.com
    http:
      paths:
      - path: /
#      - path: /doc/common(/|$)(.*)    ### if you are using rewrite
        backend:
          serviceName: app-service
          servicePort: 80

  - host: api.mydomain.com
    http:
      paths:
      - path: /
        backend:
          serviceName: api-service
          servicePort: 80
  tls:
  - hosts:
    - api.mydomain.com
    secretName: my-certs-api

Hope that helps!

-- Nick
Source: StackOverflow