Как подключить TCP-клиент Node.js в контейнере A к TCP-серверу в контейнере B с помощью Docker Compose?

Я пытаюсь подключить TCP-клиент в контейнере A к TCP-серверу в контейнере B. Запуск docker-compose up приводит к ошибке ECONNREFUSED на стороне клиента. 为什么呢?

TCP-клиент выглядит так:

   var net = require('net');

var client = new net.Socket();
client.connect(1337, function() {
    console.log('Connected');
    client.write('Hello, server! Love, Client.');
});

client.on('data', function(data) {
    console.log('Received: ' + data);
    // client.destroy(); // kill client after server's response
});

client.on('close', function() {
    console.log('Connection closed');
});

Dockerfile TCP-клиента выглядит так:

FROM node:latest

RUN mkdir /app
WORKDIR /app

ADD . /app

ADD package.json /app
RUN npm install

EXPOSE 1337

ENV PATH /app/node_modules/.bin:$PATH

CMD npm start

TCP-сервер выглядит так:

var net = require('net');

var server = net.createServer(function(socket) {
    socket.write('Echo server\r\n');
    socket.pipe(socket);
});

server.listen(1337);

Dockerfile TCP-сервера выглядит так:

FROM node:latest

RUN mkdir /app
WORKDIR /app

ADD . /app

ADD package.json /app
RUN npm install

EXPOSE 1337

ENV PATH /app/node_modules/.bin:$PATH

CMD npm start

Docker-compose.yml выглядит так:

version: "3"
services:
  tcpclient:
    build: ./tcpclient
    ports:
      - "8000:8000"
    depends_on:
      - tcpserver
  tcpserver:
    build: ./tcpserver
    ports:
      - "8001:1337"

Ошибка подключения выглядит так:

tcpclient_1  | > [email protected] start /app
tcpclient_1  | > node tcpclient.js
tcpclient_1  |
tcpclient_1  | events.js:137
tcpclient_1  |       throw er; // Unhandled 'error' event
tcpclient_1  |       ^
tcpclient_1  |
tcpclient_1  | Error: connect ECONNREFUSED 127.0.0.1:1337
tcpclient_1  |     at Object._errnoException (util.js:1003:13)
tcpclient_1  |     at _exceptionWithHostPort (util.js:1024:20)
tcpclient_1  |     at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1194:14)
tcpclient_1  | npm ERR! code ELIFECYCLE

Помощь будет принята с благодарностью


person Wasbeer    schedule 01.02.2018    source источник
comment
127.0.0.1 будет указывать на локальный хост вашего контейнера, а не на локальный хост вашего хоста. Попробуйте подключиться, используя tcpserver:1337 вместо 127.0.0.1. Docker compose будет развертывать эти контейнеры по умолчанию в одной сети, что означает, что они могут разрешать друг друга, используя имя службы.   -  person lvthillo    schedule 01.02.2018
comment
Хорошо, добавление «tcpserver» в качестве хоста сработало как по волшебству. Благодарю вас!   -  person Wasbeer    schedule 01.02.2018
comment
Прямо сейчас клиент подключается к серверу: tcpclient_1 | tcpclient_1 | > [email protected] start /app tcpclient_1 | > node tcpclient.js tcpclient_1 | tcpclient_1 | Connected Однако после подключения клиент не получает данные. Код можно увидеть здесь: github.com/wassbeer/docker/tree/networking. -в разработке   -  person Wasbeer    schedule 01.02.2018
comment
Я не разработчик узлов, но когда я раскомментирую client.destroy();, он кажется уничтоженным и печатает соединение закрытым после получения данных, но, возможно, я ошибаюсь.   -  person lvthillo    schedule 01.02.2018
comment
Проблема оказалась в том, что docker-compose up не регистрирует весь вывод в Docker Toolbox. При запуске docker-compose logs --follow tcpclient я вижу всю связь между сервером и клиентом.   -  person Wasbeer    schedule 02.02.2018


Ответы (1)


Здесь несколько проблем. Я не уверен, что localhost из контейнера будет в том же интерфейсе, что и ваш хост. Более того, порт привязан к 8001. Но я бы рекомендовал другой подход:

Используя link, вы можете ссылаться на другие хосты контейнеров по их имени. Я бы попытался:

1) Добавьте определение контейнера tcpclient: links: - tcpserver 2) Сохраните 1337:1337 на tcp-сервере (кстати, почему клиент выставляет TCP-порт?) 3) используйте client.connect(1337, 'tcpserver', function(...){...}

person Jean-Adrien    schedule 01.02.2018
comment
1) Спасибо, добавление «tcpserver» в качестве HOST для client.connect(1337, ....) заставляет клиента подключаться! 2) Добавление ссылки не меняет поведение. Без него тоже работает. 3) После подключения клиент не получает данные, либо не логирует это. Любая подсказка, почему он подключается, но не получает данные? Спасибо. - person Wasbeer; 01.02.2018