I'm currently working on a Node.js project designed as a microservices API. It consists of multiple Docker containers running locally on my computer. The project's main purpose is to control hydroponic towers using IoT, employing various sensors and ESP32 microcontrollers. The microservices are deployed using Skaffold and managed with Kubernetes. At present, I have four functioning microservices: an authentication service, a devices service (which handles details for each device, such as an individual hydroponic tower), a mailing service, and a client interface built with Next.js and React. All microservices utilize Express, and I use Ingress NGINX for inter-service communication.
My issue arises when testing the setup with all my IoT devices connected to the same network, making API requests to my local PC. I’ve configured my /etc/hosts file to redirect "greenhive.io" (a domain I created) to 127.0.0.1. I understand that accessing my PC's IP from another device allows communication with my local setup via port 80. However, when using the IP address from a different device, I encounter an "NGINX not found" error. This suggests that the problem lies in my Ingress NGINX deployment. Here is the YAML file for my Ingress NGINX:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-srv
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/use-regex: 'true'
spec:
rules:
- host: 'greenhive.io'
http:
paths:
- path: /api/users/?(.*)
pathType: ImplementationSpecific
backend:
service:
name: auth-srv
port:
number: 3000
- path: /api/devices/?(.*)
pathType: ImplementationSpecific
backend:
service:
name: devices-srv
port:
number: 3000
- path: /api/logs/?(.*)
pathType: ImplementationSpecific
backend:
service:
name: logs-srv
port:
number: 3000
- path: /api/readings/?(.*)
pathType: ImplementationSpecific
backend:
service:
name: readings-srv
port:
number: 3000
- path: /?(.*)
pathType: ImplementationSpecific
backend:
service:
name: client-srv
port:
number: 3000
I've tried changing the IP on the hosts file to the the local IP the local network gives my PC. Also, I tried doing a port-forward from port 80 of my pc to the port 80 of the ingress pod.
The Ingress host:
control, and similar controls in other proxy setups, do routing based on the HTTP Host:
header. It's possible for your Kubernetes cluster (or any other HTTP service) to be hosting multiple domains. So if both greenhive.io
and example.com
both resolve to the same IP address, the Host:
header passes along through the HTTP protocol which host name the user had actually typed in to their browser.
Because you're specifically matching on this header, this setup will only work if the browser or other client specifically includes the DNS name in their URL. It will not work if you're trying to call the service by IP address.
If your cluster is only hosting this one domain, the easiest solution is just to delete the host:
setting. Now the Ingress will accept any connection, regardless of what host name was put into the browser URL. On your local system, you can delete the system-level DNS override in /etc/hosts
and use 127.0.0.1
or localhost
.
If you are hosting multiple domains and you really need host-based routing, then you need to properly set up DNS for your domain. That's probably something you'll need help from a system administrator to do. Again, you should delete the local /etc/hosts
setting so that you're getting the correct IP address from DNS, even if it resolves to the local system.
(In principle you can also hack around this by manually modifying the hosts file in every single context that might be calling the service, but that's a hassle to maintain, and it can be fragile if the IP address ever changes. I've generally learned that editing the hosts file isn't usually a preferred path.)