Angular, NGINX cannot connect to backend on Kubernetes cluster

3/22/2021

I'm trying to learn K8. I have a frontend app that is made using angular. I'm serving it behind an NGINX proxy. I also have a backend that has functionalities. There are my files,

nginx.conf

http {
    upstream gateway {
        server sb-gateway:8081;
    }
    include /etc/nginx/mime.types;
    server {
        listen       80;
        sendfile on;
        default_type application/octet-stream;

        location / {
            root   /usr/share/nginx/html;
            try_files $uri $uri/ /index.html;
            index  index.html index.htm;
        }

        location /api/ {
            proxy_set_header X-Forwarded-Host $host;
            proxy_set_header X-Forwarded-Server $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

            proxy_pass http://gateway;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
    }
}

user.service.ts

...
return this.http.post('/api/login', {data})
...

ui-service.yaml

apiVersion: v1
kind: Service
metadata:
  labels:
    app: sb-ui
  name: sb-ui
spec:
  type: LoadBalancer
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30000
  selector:
    app: sb-ui

The backend service is called sb-gateway and I'm trying to route all requests that have /api/ in them to the backend (as specified in NGINX). But I get this error when i try to hit a route from the frontend/pressing a button.

POST http://192.168.64.2:30000/api/login 404 (NOT FOUND).

I'm trying to run this on minikube. I have SSH'd in the frontend pod and tried to curl the backend service. It works. I just need to figure out how am I supposed to communicated from the frontend service to the backend service on angular.

Any help would be greatly appreciated!

-- hrishikeshpaul
angular
kubernetes
nginx

1 Answer

4/9/2021

Posting this answer as a community wiki to give more of a baseline on how you can allow/route the traffic to/in the Kubernetes cluster.

Feel free to expand it.


Having in mind following statement:

I'm trying to learn K8.

Instead of using an nginx Pod that is acting as a proxy, you should be using Ingress.

In short Ingress can be described as:

An API object that manages external access to the services in a cluster, typically HTTP.

Ingress may provide load balancing, SSL termination and name-based virtual hosting.

-- Kubernetes.io: Docs: Concepts: Services networking: Ingress

Through an Ingress object you can tell your Ingress controller (which in this example will be nginx-ingress) to have a specific configuration that will allow you to route the traffic accordingly.


Having as an example following situation:

  • You have your application that should receive request on a /api path
  • You have other applications that should receive all other request (in this example simple nginx Pod)

Being specific to:

I'm trying to run this on minikube.

Minikube has already built-in Ingress addon that can be enabled with a single command (there are some exceptions, please refer to the documentation of specific --driver):

  • $ minikube addons enable ingress

With above command you will spawn nginx-ingress.

Creating a setup to show how it could be configured:

  • $ kubectl create deployment hello --image=gcr.io/google-samples/hello-app:2.0
  • $ kubectl expose deployment hello --port=8080 --type=ClusterIP
  • $ kubectl create deployment nginx --image=nginx
  • $ kubectl expose deployment nginx --port=80 --type=ClusterIP

The Ingress resource should look like:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: simple-fanout-example
spec:
  ingressClassName: "nginx"
  rules:
  - host:
    http:
      paths:
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: hello 
            port:
              number: 80
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx
            port:
              number: 80

What above example of Ingress will do:

  • Request with /api, /api/, /api/xyz, etc.:
    • route to hello Service with hello Pod
  • Request with /, /xyz, /abc/xyz, etc.:
    • route to nginx Service with nginx Pod

A side note!

If you need to add some specific configuration to your Ingress you can check this documentation:

You can see from the hello Pod logs:

2021/04/09 15:22:07 Server listening on port 8080
2021/04/09 15:50:14 Serving request: /api
2021/04/09 15:50:17 Serving request: /api
2021/04/09 15:50:19 Serving request: /api/asdasd

Additional resources:

-- Dawid Kruk
Source: StackOverflow