Непонимание сервисов Kubernetes

Вопрос или проблема

Я пытаюсь использовать Kubernetes уже некоторое время и столкнулся с проблемой, которую не могу решить. Я пытаюсь развернуть фронтенд на React и бэкенд на Rust (как случай коммуникации между двумя контейнерами/подами), и всё работает нормально, оба приложения, похоже, функционируют, и к фронтенду можно получить доступ с помощью minikube service <name-of-service>. Проблема в том, что фронтенд пытается получить данные от бэкенда, и это заканчивается несколькими ошибками:

  • Не удалось установить соединение Websocket с 'ws://<minikube-ip>/ws'
  • GET 'http://backend:8080/test' net::ERR_NAME_NOT_RESOLVED (возможно, в этом и проблема?)
  • Не удалось получить данные

Я пытался изменить файлы .yaml, которые использую для создания развертывания и сервиса, и смотрел на множество способов, которые другие люди пробовали делать то же самое, но ничего, похоже, не помогло, так как они только предоставили спецификации своих .yaml файлов.

Вот как выглядит мой файл .yaml для развертывания и сервиса фронтенда:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: client-deployment
  labels:
    app: client
spec:
  replicas: 1
  selector:
    matchLabels:
      app: client
  template:
    metadata:
      labels:
        app: client
        tier: frontend
    spec:
      containers:
      - name: client
        image: quan1um/react-test:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
  name: client-service
spec:
  selector:
    app: client
    tier: frontend
  ports:
    - protocol: "TCP"
      port: 3000
      targetPort: 3000
  type: LoadBalancer

Бэкенд:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
spec:
  selector:
    matchLabels:
      app: backend
  template:
    metadata:
      labels:
        app: backend
    spec:
      containers:
        - name: backend
          image: quan1um/rust-actix-test:latest
          ports:
            - name: http
              containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: backend
spec:
  selector:
    app: backend
  ports:
    - protocol: TCP
      port: 8080
      targetPort: http
  type: ClusterIP

Как вы могли заметить из моих сообщений об ошибках, мой фронтенд пытается получить данные с http://backend:8080, и я понимаю, что это не сработает, так как эти запросы на получение происходят в браузере, а браузер не знает о сервисах в Kubernetes и их именах.

Хотя я использую только React для фронтенда, я видел конфигурационные файлы nginx, которые использовали имена, указанные в файлах .yaml сервиса, для блока конфигурации сервера, и мне это тоже интересно.

Ответ или решение

Понимание служб в Kubernetes: Решение проблем с взаимодействием между фронтендом и бэкендом

Kubernetes предоставляет мощные возможности для управления контейнерами, однако западение в детали его архитектуры может вызывать недопонимание, особенно при настройке взаимодействия между разными компонентами приложения, такими как фронтенд и бэкенд. В вашем случае вы столкнулись с проблемой, когда ваше React-приложение не может корректно взаимодействовать с Rust-бэкендом. Давайте рассмотрим это более подробно.

Проблема с доступом к бэкенду

Согласно предоставленным вами ошибкам, ваше React-приложение пытается отправить запросы на адрес http://backend:8080, но браузер не может разрешить имя "backend". Это связано с тем, что браузер, работающий в контексте вашего клиентского приложения, не имеет доступа к внутренним DNS-настройкам Kubernetes. В Kubernetes имена служб, такие как "backend", доступны только внутри кластера.

Решения

  1. Используйте внешний адрес службы:

    Чтобы ваш фронтенд мог взаимодействовать с бэкендом, вы должны использовать публичный IP-адрес или доменное имя службы. В вашем случае служба backend имеет тип ClusterIP, что делает её доступной только внутри кластера. Измените тип службы на NodePort или LoadBalancer, чтобы обеспечить внешний доступ:

    apiVersion: v1
    kind: Service
    metadata:
     name: backend
    spec:
     selector:
       app: backend
     ports:
       - protocol: TCP
         port: 8080
         targetPort: http
     type: NodePort  # или LoadBalancer
  2. Настройка прокси на фронтенде:

    Если вы не хотите изменять тип службы, вы можете настроить ваш React-приложение так, чтобы оно использовало fetch с конечной точкой, доступной из под сети. В этом случае вам нужно будет использовать IP-адрес Minikube и порт, перенаправленный из NodePort для доступа к бэкенду. Например:

    fetch(`http://<minikube-ip>:<nodeport>/test`)
  3. Используйте Ingress для управления маршрутами:

    Вы также можете рассмотреть возможность настройки Ingress-контроллера для управления доступом к вашим службам. Это позволит создать более гибкий маршрут и использовать доменные имена для доступа к разным частям вашего приложения.

Конфигурации Nginx

Что касается конфигурации Nginx, да, вы можете использовать имена служб Kubernetes для внутреннего маршрутизирования, но только в контексте контейнеров, работающих внутри кластера. Если ваш React-фронтенд работает на клиенте (в браузере), вы должны использовать внешние URL-адреса для всех запросов.

Если вы используете Nginx как реверс-прокси, то вам нужно будет настроить его для маршрутизации запросов к внутренним сервисам:

server {
    listen 80;

    location /api/ {
        proxy_pass http://backend:8080;
    }

    location / {
        proxy_pass http://client-service:3000;
    }
}

Заключение

Понимание механизмов работы Kubernetes – ключ к успешной настройке и запуску контейнеризованных приложений. К сожалению, прямое взаимодействие между клиентскими приложениями и внутренними именами служб Kubernetes невозможно, но с помощью корректного конфигурирования служб и, возможно, использования методов проксирования, таких как Nginx или Ingress, вы сможете добиться необходимого результата.

Не стесняйтесь задавать вопросы по процессу конфигурации, и мы вместе сможем разобраться в тонкостях!

Оцените материал
Добавить комментарий

Капча загружается...