Вопрос или проблема
В настоящее время я работаю над проектом на Node.js, который разработан как микроуслуга API. Он состоит из нескольких контейнеров Docker, работающих локально на моем компьютере. Основная цель проекта — контролировать гидропонные башни с использованием IoT, применяя различные датчики и микроконтроллеры ESP32. Микроуслуги развернуты с помощью Skaffold и управляются с помощью Kubernetes. В настоящее время у меня есть четыре работающие микроуслуги: служба аутентификации, служба устройств (которая обрабатывает данные для каждого устройства, например, отдельной гидропонной башни), служба рассылки и клиентский интерфейс, созданный с использованием Next.js и React. Все микроуслуги используют Express, и я использую Ingress NGINX для межсервисной связи.
Моя проблема возникает, когда я тестирую настройку со всеми моими IoT-устройствами, подключенными к одной сети, и делаю запросы к API на своем локальном ПК. Я настроил свой файл /etc/hosts таким образом, чтобы перенаправлять “greenhive.io” (домен, который я создал) на 127.0.0.1. Я понимаю, что доступ к IP-адресу моего ПК с другого устройства позволяет взаимодействовать с моей локальной настройкой через порт 80. Однако при использовании IP-адреса с другого устройства я получаю ошибку “NGINX не найден”. Это указывает на то, что проблема заключается в развертывании моего Ingress NGINX. Вот файл YAML для моего 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
Я пробовал изменить IP в файле hosts на локальный IP, который выделяет моя локальная сеть для моего ПК. Также я пробовал сделать проброс порта с порта 80 моего ПК на порт 80 инграса.
Контроль host:
в Ingress и аналогичные параметры в других прокси-настройках выполняют маршрутизацию на основе HTTP Host:
заголовка. Возможно, что ваш кластер Kubernetes (или любой другой HTTP-сервис) обслуживает несколько доменов. Поэтому, если как greenhive.io
, так и example.com
разрешаются в один и тот же IP-адрес, заголовок Host:
передается через HTTP-протокол, указывая, какое имя хоста пользователь фактически ввел в своем браузере.
Поскольку вы конкретно сопоставляете этот заголовок, эта настройка будет работать только в том случае, если браузер или другое клиентское приложение конкретно включает DNS-имя в своем URL. Это не будет работать, если вы пытаетесь вызвать сервис по IP-адресу.
Если ваш кластер обслуживает только этот один домен, то самым простым решением будет просто удалить настройку host:
. Теперь Ingress будет принимать любое соединение, независимо от того, какое имя хоста было указано в URL-адресе браузера. В вашей локальной системе вы можете удалить переопределение уровня системы DNS в /etc/hosts
и использовать 127.0.0.1
или localhost
.
Если вы обслуживаете несколько доменов и вам действительно нужно маршрутизировать на основе имени хоста, то вам нужно правильно настроить DNS для вашего домена. Вероятно, вам понадобится помощь системного администратора для этого. Снова следует удалить местную настройку /etc/hosts
, чтобы вы получали правильный IP-адрес из DNS, даже если он разрешается в локальную систему.
(В принципе, вы также можете обойти это, вручную изменяя файл hosts в каждом контексте, который может вызывать сервис, но это хлопотно для поддержки, и это может быть ненадежно, если IP-адрес когда-либо изменится. Я в целом научился, что редактирование файла hosts обычно не является предпочтительным путем.)
Ответ или решение
Открытие API микросервисов для локальной сети
Ваша задача по тестированию микросервисного API в локальной сети представляет собой важный шаг на пути к успешной интеграции IoT-устройств с вашим проектом. Вы уже смогли настроить несколько микросервисов с использованием Node.js, Docker и Kubernetes, однако возникшие проблемы с доступом к вашему API с других устройств требуют более глубокой проработки.
Проблема: Доступность API через NGINX Ingress
Основная проблема, с которой вы столкнулись, связана с маршрутизацией запросов через Ingress NGINX, использующим директиву host
. В вашем случае, определенные модули и маршруты в NGINX настроены на принятие только тех запросов, которые содержат хост greenhive.io
. Это означает, что если вы пытаетесь обратиться к вашему API с другого устройства, используя IP-адрес, Ingress не сможет правильно обработать запрос, так как не совпадает хост.
Рекомендации по решению проблемы
-
Удаление директивы
host
: Наиболее простым и эффективным решением будет удаление конфигурацииhost
из вашего манифеста Ingress. Это позволит Ingress принимать запросы независимо от используемого хоста. Изменения могли бы выглядеть следующим образом: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: - http: paths: - path: /api/users/?(.*) pathType: ImplementationSpecific backend: service: name: auth-srv port: number: 3000 ...
-
Использование IP-адреса вашего ПК: Для тестирования используйте локальный IP-адрес вашего компьютера, вместо
127.0.0.1
илиlocalhost
. Это позволит IoT-устройствам в локальной сети обращаться к вашему API. -
Настройка маршрутизации через DNS: Если вы планируете использовать
greenhive.io
как хост для доступа к вашему API, вам необходимо настроить DNS, чтобы он правильно указывал на IP-адрес вашего компьютера в локальной сети. Вы можете использовать сторонние DNS-сервисы или локальные решения, чтобы это реализовать. -
Тестирование с разных устройств: Убедитесь, что с других устройств, подключенных к вашей локальной сети, вы можете успешно отправлять запросы к API. Используйте инструменты для тестирования API, такие как Postman или curl, чтобы проверить работоспособность вашего приложения.
Дополнительные рекомендации
-
Мониторинг и логирование: Включите логирование и мониторинг запросов через Ingress NGINX. Это поможет вам быстро выявлять и устранять проблемы с маршрутизацией и доступностью сервисов.
-
Отладка с помощью Minikube или Kind: Если вы еще не используете, рассмотрите возможность работы с Minikube или Kind, что поможет вам удобно развернуть Kubernetes-кластер и управлять локальными сервисами.
Таким образом, устранение директивы host
из вашей конфигурации Ingress, настройка локальной сети и правильное использование IP-адреса вашего компьютера обеспечит доступ к вашему API микросервисов с IoT-устройств и улучшит общее взаимодействие в вашем проекте. В случае дальнейших вопросов или необходимости в более детальном анализе, не стесняйтесь обращаться за помощью к специалистам или сообществу.