我目前正在开发一个设计为微服务 API 的 Node.js 项目。它由在我的计算机上本地运行的多个 Docker 容器组成。该项目的主要目的是使用物联网控制水培塔,采用各种传感器和 ESP32 微控制器。微服务使用 Skaffold 部署并通过 Kubernetes 进行管理。目前,我有四个运行中的微服务:身份验证服务、设备服务(处理每个设备的详细信息,例如单个水培塔)、邮件服务和使用 Next.js 和 React 构建的客户端界面。所有微服务都使用 Express,我使用 Ingress NGINX 进行服务间通信。
当我将所有 IoT 设备连接到同一网络并向本地 PC 发出 API 请求时,测试设置时出现了问题。我已将 /etc/hosts 文件配置为将“greenhive.io”(我创建的域)重定向到 127.0.0.1。我知道从另一台设备访问我的 PC 的 IP 允许通过端口 80 与我的本地设置进行通信。但是,当使用来自其他设备的 IP 地址时,我遇到“找不到 NGINX”错误。这表明问题出在我的 Ingress NGINX 部署中。这是我的 Ingress NGINX 的 YAML 文件:
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
我尝试将 hosts 文件上的 IP 更改为本地网络为我的 PC 提供的本地 IP。此外,我还尝试将我的 PC 的端口 80 转发到入口 pod 的端口 80。
Ingress
host:
控件和其他代理设置中的类似控件根据 HTTPHost:
标头进行路由。您的 Kubernetes 集群(或任何其他 HTTP 服务)可能托管多个域。因此,如果两者greenhive.io
都example.com
解析为同一个 IP 地址,则Host:
标头会通过 HTTP 协议传递用户实际在浏览器中输入的主机名。由于您专门匹配此标头,因此只有当浏览器或其他客户端在其 URL 中明确包含 DNS 名称时,此设置才会起作用。如果您尝试通过 IP 地址调用服务,则此设置将不起作用。
如果您的集群仅托管这一个域,最简单的解决方案就是删除
host:
设置。现在,Ingress 将接受任何连接,无论在浏览器 URL 中输入了什么主机名。在本地系统上,您可以删除系统级 DNS 覆盖/etc/hosts
并使用127.0.0.1
或localhost
。如果您托管多个域并且确实需要基于主机的路由,则需要正确设置域的 DNS。您可能需要系统管理员的帮助才能完成此操作。同样,您应该删除本地
/etc/hosts
设置,以便从 DNS 获取正确的 IP 地址,即使它解析为本地系统。(原则上,您也可以通过在每个可能调用该服务的上下文中手动修改 hosts 文件来解决这个问题,但维护起来很麻烦,而且如果 IP 地址发生变化,它就会变得脆弱。我通常了解到编辑 hosts 文件通常不是首选路径。)