Kubernetes resolving backend IP - kubernetes

My backend and frontend is deployed on Google Kubernetes Engine (GKE). And lets consider these steps -
User opens up browser and points to yyy.yyy.yyy:8080.
Browser loads the login page.
User enters username/password and presses "login" button.
Browser (ReactJS App) sends request to REST backend xxx.xxx.xxx:7070 to do the validation.
Now my question is, how can we inject the backend (in this case xxx.xxx.xxx) ip frontend pod? Because this ip is not static (i dont want to make it static), and will be provided by GKE. I don't want to proxy my backend call through frontend either. Neither I want to use nginx, the reason is, one more POD, and config to maintain. Just don't want to have nginx for only this reason.
Should I create ingress? I mean something like-
`/` <-- serves ReactJS app
`/api` <--- serves REST api
Or there is a way to inject the ip of backend POD?
What is the best approach?
Thanks in advance.

You can't access the pods directly from the outside. The only way in is through a service of type LoadBalancer. External IP you get for such a service is static for GKE (AWS gives a DNS name instead)
For every service of type LoadBalancer the cloud provider will spin up a load balancer that you have to pay for. You can funnel all http traffic through a single ingress service that would fan out your requests based on host DNS or URI path and other options. Which is what pretty much everyone does. If you want to setup something like that google for ingress

Related

How can i not expose my backend microservice using api gateway?

I have an app that is deployed in k8s cluster and the frontend and the backend of the app are exposed, is there a way to not expose the backend ? i thought about the api gateway is it going to fulfills my requests if yes how ? and if not what's the alternatives ??
Thank you in advance
I tried the gateway kong and it did not work out very well
Your question requires more detail for me to be certain, however I will take a stab at pointing you in the right direction.
Typically, most apps have a frontend which serves the HTML, and any static assets such as images, css and javascript (like a single page app such as ReactJS)
If you have some SPA, then you will likely have a backend API written in something like Node / Python / PHP / Java to serve your frontend app with dynamic data.
If your frontend and backend are exposed to the internet, this is OK and expected.
If your backend was not exposed to the internet, then it would be impossible for your frontend to load dynamic data.
That said, you mentioned that you are using or at least tried to use an API Gateway. Typically, you would not expose your backend directly to the internet. Rather, you would expose your API Gateway to the internet, with the API Gateway acting as a reverse proxy to your backend.
In order to achieve this (in Kubernetes), you would typically create a Service type Load Balancer for your API Gateway. And configure a Service type Cluster IP for your backend.
ClusterIP: Exposes the Service on a cluster-internal IP. Choosing this value makes the Service only reachable from within the cluster. This is the default that is used if you don't explicitly specify a type for a Service. You can expose the service to the public with an Ingress or the Gateway API.

Using CloudFlare's CustomHostname with k8s ingress to enable CustomDomain

We have a custom domain feature, which allows our clients to use our services with their custom DNS records.
For example, our client ACME has a CNAME to ssl.company.com like so login.acme.com -> ssl.company.com. right now we are using a k8s cluster to provide such traffic. On each custom domain, we create an ingress, external service, and a certificate using LetsEncrypt cert-manager.
We started using Cloudflare WAF and they are providing CustomHostname feature which allows us to do the same as our CD cluster but without changing the host header. So
for the example above we get
host: login.acme.com -> login.acme.com
SNI: login.acme.com -> ssl.company.com
The issue is of course how to map a generic k8s ingress to allow such traffic.
when we did the POC we used this method and it worked, but now it stopped. We have also tried default backend and unhosted ingress path.
We are using nginx-ingress controller but migrating to another API gateway like kong.
Any help will be grateful.

Route to external site via Istio Virtual Service

I'm working on a side project to learn Istio in my spare time, part of which is getting my hands dirty with Istio routing.
I'm trying to setup a Virtual Service such that any traffic on "/" gets routed to google.com. I can get Virtual Services to work with any in-cluster pods/services, but I can't seem to configure Istio to route to anything outside the cluster.
Any guidance would be much appreciated, cheers
You have to create a Service Entry for google.com and then create a Virtual Service, referencing google.com in the same way as in-mesh services. Note the issue of the protocols - do you want to access google.com by HTTP or HTTPS? You may want to let Istio perform TLS origination for you.
Configure a service entry for google.com. Refer this documentation overall, and precisely this.

Kubernetes - route static IP to multiple services (Google Cloud Platform)

I have a small application comprising three services:
A single page application (SPA) served from nginx
A simple nodejs HTTP API used by the SPA
An MQtt broker exposing ports 1883 and 9001
Ideally I'd like the all to be served from the same subdomain and static IP address and have been trying to configure this in Kubernetes on the Google Cloud Platform.
I've created deployments for each of the services, with the SPA exposing port 80, the API 3000 and the MQTT broker 1883/9001. I've then followed the instructions here to set up a static IP and a Service to route to the SPA, then created similar services for the API and the MQTT app. (I've initally adapted these from deployments and services generated from a docker-compose file and Kompose).
The SPA and API seem to work fine but the MQTT service does not. When I run kubetl get events I see:
Error creating load balancer (will retry): failed to ensure load balancer for service default/mqtt-broker: failed to create forwarding rule for load balancer (a5529f2a9bdaf11e8b35d42010a84005(default/mqtt-broker)): googleapi: Error 400: Invalid value for field 'resource.IPAddress': '35.190.221.113'. Specified IP address is in-use and would result in a conflict., invalid
So I'm wondering if I should be creating a single service to route to the three deployments but can't find any documentation or examples that explain how to do this for a non http service.
I guess I could put the mqtt service on a separate IP address but this seems to be hacking around the problem rather than solving it.
Thanks in advance for any advice.
I eventually found an almost identical use case to my own on this github repository.
In essence, they are creating the MQTT broker on a separate static IP and using Kubernetes API calls to expose the details to the front end, which they explain in the following comment at the top of the web.yaml file:
This needs a bit of trickery
as it needs to expose the LB ip address for the MQTT server. That
requires kubernetes API calls to look it up, and the ability to
store it somewhere (we put it in a secret). To be secure this is
done with a dedicated service account and an init container.
https://github.com/IBM/ny-power

How to remove host header

I want to remove Host header at ingress controller before sending the request to backend service. Will appreciate your insight.
My backend service is NOT expecting any Host header.
Thank you !
Google Cloud Platform is working on richer routing and transforms with HTTP(s) Load Balancer, used by Kubernetes Engine Ingress. No ETA is available.
In the meantime, you can use a proxy service in front of the application. See this answer on how to remove a header with nginx.