#node.js #reactjs #docker #kubernetes #websocket
#node.js #reactjs #docker #kubernetes #websocket
Вопрос:
Я использую Kubernetes для развертывания моего приложения React. Из-за базы данных, которую я использую (RethinkDB). Я должен инициировать соединение WebSocket между моим приложением React и Node.js сервер, который подключается через прокси к экземпляру базы данных. Соединение работает так, как задумано, когда я развертываю экземпляр базы данных, сервер внутреннего узла и приложение react на своем локальном компьютере. Однако при развертывании приложения в Kubernetes я получаю сообщение об ошибке
WebSocket connection to 'ws://localhost:8015/' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED
в моем приложении react.
Для дальнейшей отладки я запустил терминал внутри контейнера и запустил команду curl для службы, которая подключается к базе данных, и не получил никаких ошибок. Я также запустил сервер внутреннего узла, чтобы проверить, подключается ли он к удаленной базе данных, и не увидел там никаких проблем. Наконец, я проверил, инициирует ли внутренний сервер WebSocket, как предполагалось, с помощью wscat, и работает ли соединение с WebSocket. И из-за того, что приложение хорошо работает на моем локальном компьютере, это наводит меня на мысль, что проблема в приложении React, подключающемся к WebSocket, может быть вызвана тем, как Kubernetes обрабатывает соединения с Websocket. Любые разъяснения по этому вопросу приветствуются.
P.S
Я добавил код внутреннего сервера, код в приложении React, который подключается к WebSocket, и файлы YAML моего развертывания React Backend. Если требуются дополнительные файлы, пожалуйста, не стесняйтесь комментировать
сервер внутреннего узла
const http = require('http');
var rethinkdbWebsocketServer = require('rethinkdb-websocket-server');
const httpServer = http.createServer();
rethinkdbWebsocketServer.listen({
httpServer: httpServer,
httpPath: '/',
dbHost: remoteDB_IP,
dbPort: 28015,
unsafelyAllowAnyQuery: true
});
httpServer.listen(8015);
Реагирующий код, который подключается к Websocket
ReactRethinkdb.DefaultSession.connect({
host: 'localhost', // the websocket server
port: process.env.REACT_APP_WEBSOCKET_PORT,
path: '/',
secure: false,
autoReconnectDelayMs: 2000, // when disconnected, millis to wait before reconnect
});
deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: dashboard
labels:
app: dashboard
spec:
replicas: 1
selector:
matchLabels:
app: dashboard
template:
metadata:
labels:
app: dashboard
spec:
containers:
- name: dashboard
image: myrepor/dashbaord
imagePullPolicy: Always
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
ports:
- containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
name: dashboard
spec:
selector:
app: dashboard
ports:
- port: 3000
targetPort: 3000
type: LoadBalancer
Комментарии:
1. где в kubernetes развернута база данных? не в том же модуле?
2. Он развертывается как другой модуль kubernetes и предоставляется с помощью балансировщика нагрузки
3.но тогда адрес базы данных не
localhost
Ответ №1:
итак, идеи kubernetes сводятся к запуску каждого приложения в отдельном модуле.
И подключение их через службы.
Таким образом, вы можете развертывать каждый уровень отдельно без простоев — маршруты обслуживания к старым pod (ам), пока новые не будут запущены и запущены. (и что еще более важно, масштабируйте отдельно) Kubernetes выполняет какое-то разрешение имен внутри каждого кластера k8s. Не совсем уверен, является ли это полным dns или нет
поэтому я бы рекомендовал
- разделите ваш сервер узла на один модуль. и разверните для него службу с помощью вашего ws-порта (8015).
- ваше приложение react выделяет отдельный модуль со своей собственной службой и определяет имя службы сервера узла в качестве конечной точки для WS.
Причина проста — даже не уверен, что localhost будет правильно разрешен с помощью модуля in.
Комментарии:
1. Я реализовал ваше решение, развернув приложения и серверную часть на своих собственных модулях, но безрезультатно. Однако в моей первой попытке я сделал это, представив WebSocket как ClusterIP. Со второй попытки я использовал тот же подход, но предоставил свой WebSocket внешнему трафику с использованием балансировщика нагрузки, и этот подход сработал. Я не совсем понимаю, почему это сработало, поэтому я пока оставлю вопрос без ответа, чтобы кто-то с лучшим пониманием мог ответить на вопрос