2

I have a k8s cluster running locally on an arm Mac. I have client and server pods. The client is a React frontend. The server is an express server connecting to a mongodb Atlas cluster.

So far the images build fine and all pods are running.

The problem is the internal port routing is not working. All I see is

GET http://localhost:5000/ net::ERR_CONNECTION_REFUSED

And the referrer policy in the networking tab suggests a CORS error:

Referrer Policy: strict-origin-when-cross-origin

I'm not sure what I need to do to get my client to fetch on a certain port? So far I have this, which works outside of k8s:

const getAllUsers = () => {
    fetch("http://localhost:5000/")
      .then((res) => res.text())
      .then((res) => {
        return setUsers(JSON.parse(res));
      });
  };

The server has this code to handle the request:

  app.get("/", (req, res) => {
  usersCollection
    .find()
    .toArray()
    .then((results) => {
      res.json(results);
    })
    .catch((error) => console.error(error));
});

My server cluster ip service is like this:

apiVersion: v1
kind: Service
metadata:
  name: server-cluster-ip-service
spec:
  type: ClusterIP
  selector:
    component: server
  ports:
    - port: 5000
      targetPort: 5000

And my server deployment is like this:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: server-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      component: server
  template:
    metadata:
      labels:
        component: server
    spec:
      containers:
        - name: server
          image: mydocker/k8s-server
          ports:
            - containerPort: 5000
          env:
            - name: REDIS_HOST
              value: redis-cluster-ip-service
            - name: REDIS_PORT
              value: "6379"

When I log out the server deployment logs I get:

> express_mongodb@1.0.0 dev /app
> nodemon server.js

[nodemon] 2.0.12
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node server.js`
Connected to Database
listening on 5000

Which is great - it's listening on the port I specified with

 app.listen(PORT, function () {
  console.log("listening on 5000");
});

There's something I'm not getting here. The first thing I want to do is make sure my server is connected to my client on port 5000 - what am I doing wrong?

EDIT: After a long time looking at CORS error fixes, maybe it isn't a CORS error? I curl the service ip with:

curl my.ip.##.##

Then try:

curl localhost:5000

But the requests time out.

I use kubectl describe service server-cluster-ip-service

and get back

Name:              server-cluster-ip-service
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          component=server
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.###.##.##
IPs:               10.###.##.##
Port:              <unset>  5000/TCP
TargetPort:        5000/TCP
Endpoints:         172.##.#.##:5000,172.##.#.##,172.##.#.##
Session Affinity:  None
Events:            <none>
Davtho1983
  • 3,827
  • 8
  • 54
  • 105

1 Answers1

1

Ideally, you should be using the service name to communicate with different services inside the cluster.

If you react server want to talk with the express server, you have to the express-service-name as host into the react service. Kubernetes will auto manage the resolution.

so for you, it will be server-cluster-ip-service

const getAllUsers = () => {
    fetch("http://server-cluster-ip-service:5000/")
      .then((res) => res.text())
      .then((res) => {
        return setUsers(JSON.parse(res));
      });
  };

As in a single machine or in a host all services can talk to each other on localhost the same way in Kubernetes cluster services uses the service name to solve each other.

Reference document DNS for services & POD: https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/

You express cluster POD or application will run on 0.0.0.0/0 and port 5000 and there will be one Kubernetes service as your created now with target port 5000.

Your client or other application internally will call this service by service name and request redirected to container (POD) of the express server.

Harsh Manvar
  • 27,020
  • 6
  • 48
  • 102