I have a GKE cluster which uses Nginx Ingress Controller as its ingress engine. Currently, when I setup the Nginx Ingress Controller I define a service kind: LoadBalancer
and point it to an external static IP previously reserved on GCP. The problem with that is it only binds to a regional static IP address (L4 Load Balancer if I’m not mistaken). I want to have a Global Load Balancer instead.
I know that I can achieve that by using GKE ingress controller instead of Nginx Ingress Controller. But I still want to use Nginx Ingress due to its powerful annotations like rewriting headers based on conditions etc; things not available for GKE Ingress annotations.
Finally, is there any way to combine a Global Load Balancer with nginx ingress controller or put an Global Load Balancer in front of a L4 Load Balancer created By Nginx?
We need to have Global Load Balancer in order to be protected by Cloud Armor.
2
Answers
I finally managed to make Nginx Ingress Controller and L7 HTTP(S) Load Balancer work together.
Based on the @rrob repply with his own question I managed to make it work. The only difference is that his solution will install a classic HTTP(S) LoadBalancer, instead of the new version and also I cover the creation of the IP Address, the self-signed Certificate, and the HTTP Proxy redirect from HTTP to HTTPS. I will plcae here the detailed steps that worked for me.
This steps assume we already have a Cluster created with
VPC-native traffic routing
enabled.Before the need of the HTTP(S) LoadBalancer, I would just apply the manifests provided by the NGINX DOCS page for the installation of the Nginx Ingress Controller and It would create a service of type
LoadBalancer
which would, then, create a regional L4 LoadBalancer automatically.But now that I need need to have Cloud Armor and WAF, the L4 Loadbalancer doesn't support it. A HTTPS(S) Load Balancer is needed in order for Cloud Armor to work.
In order to have Nginx Ingress controller working with the new HTTPS(S) LoadBalancer we need to change the
type: LoadBalancer
on the Nginx Ingress Controller service toClusterIP
instead, and add the NEG annotation to itcloud.google.com/neg: '{"exposed_ports": {"80":{"name": "ingress-nginx-80-neg"}}}'
. We do that because we don't want it to generate a L4 LoadBalancer for us. Instead, we will manually create an HTTP(S) LoadBalancer and bind it to theingress-nginx-controller
through its NEG annotation. This binding will happen later when we set our Nginx Ingress Controller deployment as the Backend Service of our HTTPS LoadBalancer. So back to the Nginx Ingress Controller Service, it will end up like this:To install it, add the ingress-nginx to the helm repository:
Then install it:
The next steps will be:
Finally, I will setup the Loadbalancer frontend through the Console interface which is way easier.
To create the LoadBalancer front end, enter the Loadbalancer on Console and click on "Edit".
The Frontend configuration tab will be incomplete. Go there
Click on "ADD FRONTEND IP AND PORT"
Give it a name and select HTTPS on the field Protocol.
On IP Address change from Ephemeral to your previously allocated static IP
Select your certificate and mark Enable HTTP to HTTPS redirect if you want. (I did)
Save the LoadBalancer. The entering the LoadBalancer page we should see our nginx instance(s) healthy and green. In my case I've setup the Nginx Ingress Controller to have 4 replicas:
Finally, we just need to point our domains to the LoadBalancer IP and create our Ingress file.
You can create the Nginx as a service of type LoadBalancer and give it a NEG annotation as per this google documentation.
https://cloud.google.com/kubernetes-engine/docs/how-to/container-native-load-balancing
Then you can use this NEG as a backend service (target) for HTTP(S) load balancing
You can use the gcloud commands from this article
https://hodo.dev/posts/post-27-gcp-using-neg/