简体   繁体   中英

Connecting React Frontend to Node JS backend within Kubernetes

What is the recommended way to make API requests from a React Frontend Application to a Node JS backend application within Kubernetes? They are both hosted on the same container, with the dockerfile as such:

COPY frontend/package.json .
COPY frontend/yarn.lock .
RUN npm install
COPY frontend/tsconfig.json .
COPY frontend/src ./src
COPY frontend/public/ ./public

WORKDIR /app/backend
COPY backend/package.json .
RUN npm install
COPY backend/index.js .
COPY backend/controllers ./controllers
COPY backend/models ./models
COPY backend/routes ./routes
EXPOSE 3000
EXPOSE 3001

WORKDIR /app/frontend
RUN npm run build
RUN npm install -g serve

WORKDIR /app
RUN mkdir newImages
RUN mkdir exportedData
COPY image/* newImages/

COPY startup.sh /app
CMD /app/startup.sh

startup.sh navigates to both the frontend and backend folders and starts both servers. Running each of these locally on my machine works fine, and api requests go through correctly. However, when I deploy to Kubernetes, API requests made from my browser all time out. I attempt to use the friendly name of the pod - so these requests are being made to http://podname:PORT/api/XXX. If I exec into the pod and run the requests through curl, the api requests work fine. Similarly, if I expose the API port with a LoadBalancer and replace "podname" with a hardcoded external IP for the service, everything works fine. However, that is not a viable long term solution as External IP's can change easily if pods go down/are restarted.

Is there some easy way to route these requests properly through a proxy within the frontend, or will I need to set up an NGINX controller to handle everything here? I assume the issue is that React is running directly within the browser I access the frontend from - causing requests to come from my computer, meaning that IP's are not properly resolved (or even accessible, given that the friendly name resolves to the internal cluster IP)

Any help would be appreciated!

TL;DR Two Things

  1. You cannot use pod names to connect with services from outside the cluster. That is because pod names are DNS names that are resolved into IP addresses that are internal to your cluster and this subnet cannot be reached from the outside. And you SHOULDN'T use pod names to connect to your pods from the outside, that's what services are for. Because once your application grows to a larger size, 100s of pods, it will be impossible to maintain pod names on the client side.

  2. With a LoadBalancer service type, your design will work perfectly fine. You don't have to worry about IP addresses changing and not 'mapping to pods' anymore. That is because your pods are being interfaced by a service. The connectivity between this service and your pods is consistent even if your LoadBalancer IP address keeps changing. All that will change is the way you will connect to your Service object. The internal connectivity between a service and its pods is not your concern at all.

Also, please note that it is a very bad idea to design an application this way, where two separate logical components sit on the same container. It's a purely monolithic design and it is very hard to scale and maintain. You shouldn't even use different containers, but rather different pods for this, to begin with. There will be no issues since all pods can communicate with each other very transparently in Kubernetes and no extra configuration will be needed.

Ideally, you will have to setup two different services that will connect with each other.

Bottom line is, there is no need to setup a proxy to directly connect your pods to your clients. Instead, simply use a service of LoadBalancer type that exposes an endpoint your clients can use. And there is no need to worry about changing externalIPs. If you are using the application internally, you can fix a private IP address which can easily be used. If you are deploying this application to a larger scale, you really need to rethink your design and also invest into static public IP addresses.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM