kubernetes gke multiple ingresses single global ip - kubernetes

I have multiple MSA on k8s on GKE. Each is on separate subdomain like:
msa1.example.com
msa2.example.com
I have it in single ingress:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: main-ingress
annotations:
kubernetes.io/ingress.global-static-ip-name: lalala-ip-1
kubernetes.io/ingress.allow-http: "false"
spec:
tls:
- hosts:
- msa1.example.com
secretName: msa1-tls
backend:
serviceName: sink
servicePort: 80
rules:
- host: msa1.example.com
http:
paths:
- path: /.well-known/*
backend:
serviceName: letsencrypt
servicePort: 80
- path: /*
backend:
serviceName: lalala
servicePort: 80
- host: msa2.example.com
http:
paths:
- path: /*
backend:
serviceName: lalala2
servicePort: 80
... and all is nice.
The thing is, that I want to have each MSA in separate file.
Problem is this kubernetes.io/ingress.global-static-ip-name: lalala-ip-1 line. If I have it in two ingresses only first started is bounded to IP, but other ones no.
Is there a way, to share IP on GKE ingress controller between two ingresses?

A way around it could be to run your own nginx-ingress controller in your cluster and expose it via LoadBalancer service type. Then you would have 1 IP for your ingress and be able to serve all ingresses via nginx controller by adding annotation kubernetes.io/ingress.class: "nginx"
Reference: https://kubernetes.github.io/ingress-nginx/user-guide/multiple-ingress/

Confirmed my comment:
Only one resource at a time can use a static external IP address.
https://cloud.google.com/compute/docs/ip-addresses/reserve-static-external-ip-address

GKE has recently added support for the new Kubernetes Gateway API. Both the GKE Gateway implementation as well as the Kubernetes Gateway API specification are still in alpha at this point.
The Kubernetes Gateway-API, is intended to support use cases, where you have a central Gateway (with a single IP), but want different Routes (with different hostnames or paths), managed in separate objects or even namespaces.
References:
https://gateway-api.sigs.k8s.io/
https://cloud.google.com/kubernetes-engine/docs/concepts/gateway-api

Related

Use existing AWS NLB with kubernetes ingress

I'm trying deploy an app that uses a nodeport ingress to register with an existing AWS NLB. I t's my understanding that I don't need an lb controller because the NLB is pre-existing and I'm not relying upon it to deploy the NLB. Is this much correct?
Ultimately, I think I just need an annotation in the ingress to tether it to the existing NLB . Am I on the right track?
uses a nodeport ingress to register with an existing AWS NLB
Node port and ingress are two different things, plus How the dynamic node will be managed and how the target will be set for the NLB? Plus node port is not recommended think-nodeport-kubernetes
So the best option is to use an ingress controller with NLB.
All you need to apply this, this will create NLB and ingress,
you can also release existing static IP from the NLB and assign it to the new created NLB
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-0.32.0/deploy/static/provider/aws/deploy.yaml
This is how it will look like
network-load-balancer-nginx-ingress-controller-eks
By doing this, you do not need any fancy annotation for the LB as well, so just create ingress and it should work
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: example-ingress
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
tls:
- hosts:
- anthonycornell.com
secretName: tls-secret
rules:
- host: anthonycornell.com
http:
paths:
- path: /apple
backend:
serviceName: apple-service
servicePort: 5678
- path: /banana
backend:
serviceName: banana-service
servicePort: 5678
Make sure to update DNS that pointing to NLB

How to deploy multiple frontend application on same kubernetes cluster with only one hostname

I've 3 angular applications that are deployed on Kubernetes. I'm trying to run all 3 with just one hostname and different paths. Here is my ingress.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /$1
name: test-ingress-deployment
namespace: my-namespace
spec:
tls:
- hosts:
- dns-name.eastus.cloudapp.azure.com
secretName: aks-ingress-tls
rules:
- host: dns-name.eastus.cloudapp.azure.com
http:
paths:
- backend:
serviceName: ui-svc
servicePort: 80
path: /(.*)
- backend:
serviceName: ui-svc-one
servicePort: 80
path: /one/?(.*)
- backend:
serviceName: ui-svc-two
servicePort: 80
path: /two/?(.*)
All these 3 services are in different namespaces. I'm getting 503 for every endpoint I'm trying to hit, after applying ingress.
Documentation around this is scarce, at least I wasn't able to find something except for Github issues shedding a little light into this issue. But as far as I know cross namespace access was intentionally avoided in K8s, it would be a prime source of privilege escalation attacks.
To my knowledge you do have two options:
You can run your ingress and ingress controller inside the kube-system namespace. But this is not recommended as kube-system is meant for K8s components only and it most likely creates security concerns.
You can have the ingress in the namespace your service resides in. But then you need an ingress controller which allows merging of rules which not all support afaik.
There are probably more solutions out there, maybe someone with more in-depth K8s knowledge can shed more light on it.

One Kubernetes Ingress to front multiple clusters? Scope issues

So I have two clusters at the moment (soon to be a few more, once I get this working), ClusterA and ClusterB.
Is it possible for one ingress to interface with services from both clusters?
ClusterA hosts the front end and the ingress, while ClusterB hosts the back end.
The excerpted ingress is below. Everything bar the back end works.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:{...}
selfLink: /apis/extensions/v1beta1/namespaces/default/ingresses/test-frontend-ingress
uid: //
spec:
backend:
serviceName: idu-frontend-XYZ
servicePort: 80
rules:
- http:
paths:
- backend:
serviceName: test-backend-app-service
servicePort: 8080
path: /api/v2/
- backend:
serviceName: idu-frontend-XYZ
servicePort: 80
path: /
tls:
- secretName: tls-cert-name
status:
loadBalancer:
ingress:
- ip: 123.456.789.012
Back end service URL:
https://console.cloud.google.com/kubernetes/service/asia-southeast1-b/test-backend/default/test-backend-app-service...
URL the ingress tries to point to:
https://console.cloud.google.com/kubernetes/service/asia-southeast1-b/standard-cluster-1/default/test-backend-app-service...
So what I've gathered is the ingress can only interface with things in the same cluster as them? test-backend and standard-cluster-1 are the cluster names, and they are both on the default namespace. Isn't that kind of pointless, as you can only deploy one thing to each cluster? Unless your images contain multiple apps, in which case it isn't really microservices anymore.
Connecting two clusters with Kubernetes is hard I guess.
Instead you can deploy both the services on the same cluster. You can create two deployments and expose them as services. And then ingress can redirect traffic between them.
Why do you need a cluster per service though ?
If there is no other alternative you will have to do something like this:
https://appscode.com/products/voyager/7.1.1/guides/ingress/http/external-svc/

Ingress-controller redirect to serviceName according to ip addresses

I have an ingress controller and two nginx in one Kubernetes namespace. One service has the name nginx-1 and the second name nginx-2.
I need to create a situation where nginx-1 will be default backend, and nginx-2 will be a target for a few IP addresses.
I have tried to do this using a ConfigMap but without results.
Maybe someone had a problem like this?
Never saw on Kubernetes docs something like this, but I would like to purpose another approach. You can configure your ingress to use named based virtual hosting, so that few IP addresses would connect using a different domain.
Here and example:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: name-virtual-host-ingress
spec:
rules:
- host: foo.bar.com
http:
paths:
- backend:
serviceName: service1
servicePort: 80
- host: bar.foo.com
http:
paths:
- backend:
serviceName: service2
servicePort: 80
Reference: https://kubernetes.io/docs/concepts/services-networking/ingress/#name-based-virtual-hosting

How to map unmatched routes with ingress on GKE

I'm trying to automatically provision a loadbalancer on GCP by using the ingress object with our GKE cluster.
I have three GKE deployments and each is available with a service on port 8080 with a unique nodePort.
When using ingress-fanout.yaml, it creates 4 backend services instead of the 3 specified in the yaml. The 4th service defaults to all unmatched routes. I assume the 4th service is because we don't match unmapped routes in the yaml.
How can one map unmatched routes to one of the services? Is that possible?
Here's ingress-fanout.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: fanout-ingress
annotations:
kubernetes.io/ingress.global-static-ip-name: "our-static-ip"
ingress.gcp.kubernetes.io/pre-shared-cert: "our-ssl-cert"
kubernetes.io/ingress.allow-http: "false"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
rules:
- host: our-website.com
http:
paths:
- path: /*
backend:
serviceName: li-frontend
servicePort: 8080
- path: /backend/*
backend:
serviceName: li-django
servicePort: 8080
- path: /notifications/*
backend:
serviceName: li-notifications
servicePort: 8080
Update: I removed many of the original questions and narrowed the scope of the question. When health checks started succeeding, that cleared the old issues.
First of all, "backends" have nothing to do with the "paths" you specified. "backends" on GCP Console are pointing to your GKE node pools.
Ingress supports adding a default backend. You could have tried just searching for "ingress default backend". You can find documentation about this here: https://kubernetes.io/docs/concepts/services-networking/ingress/#single-service-ingress
Basically doing this will set a default backend when nothing else is matched:
spec:
backend:
serviceName: testsvc
servicePort: 80
rules:
[...your stuff here...]