Communication between containers in docker swarm

霸气de小男生 提交于 2019-12-10 20:46:46

问题


I would like to communicate between master and worker nodes via WebSocket connection in docker swarm mode.

A master node should have been reached from the worker node. The connection fails.

Also, I would like to connect via http to the master node from my host machine. The connection fails as well.

Here is my docker-compose.yml

version: '3'
services:
  master:
    image: master
    build:
      context: .
      dockerfile: ./docker/master/Dockerfile
    env_file:
      - ./config.env
    command: ['node', './src/master/']
    ports:
      - 8080:8080
    networks:
      - webnet
    deploy:
      replicas: 1
      resources:
        limits:
          cpus: "0.2"
          memory: 200M
      restart_policy:
        condition: none

  worker:
    image: worker
    build:
      context: .
      dockerfile: ./docker/worker/Dockerfile
    env_file:
      - ./config.env
    command: ['node', './src/worker/']
    deploy:
      replicas: 10
      resources:
        limits:
          cpus: "0.1"
          memory: 100M
      restart_policy:
        condition: none
    networks:
      - webnet
    depends_on:
      - master

networks:
  webnet:

I create the swarm with:

docker swarm init
docker-compose build --no-cache
docker stack deploy -c docker-compose.yml ${stack_name}

I try to reach the master node with:

curl http://localhost:8080/result

and get

curl: (7) Failed to connect to localhost port 8080: Connection refused
Some more details about master node:

Env:

MASTER_PORT=3000
MASTER_HOST=localhost
MASTER_HTTP_PORT=8080

Code starting websocket server:

const wss = new WebSocket.Server({ host: config.masterHost, port: config.masterPort }, (err) => {
  if (err != null) {
    throw err
  }
  console.log(`Web Socket server started on address ws://${config.masterHost}:${config.masterPort}`)
});

Code starting http server:

server.listen(config.masterHttpPort, config.masterHost, (err) => {
    if (err != null) {
      throw err
    }
    console.log(`Http server started on address http://${config.masterHost}:${config.masterHttpPort}`);
  });
Some more details about worker node:

Env

MASTER_SERVICE_HOST=master
MASTER_PORT=3000

Code connecting websocket client to master node:

const masterUri = `ws://${config.masterServiceHost}:${config.masterPort}`;
console.log(`Connecting to ${masterUri}`);
const ws = new WebSocket(masterUri, {perMessageDeflate: false});

I'm really confused because when I'm running the app with docker-compose (not in swarm mode) everything works perfectly.

But in swarm mode, I neither could reach

the master node from host machine via http

nor could I reach

the master node from worker node via websocket connection

I suspect me configuring the docker networking incorrectly.

Logs from master node:

Process started with config: {
  "grouperFile": "./src/operations/group.js",
  "initialDelay": 10,
  "mapperFile": "./src/operations/map.js",
  "masterHost": "localhost",
  "masterHttpPort": 8080,
  "masterPort": 3000,
  "masterServiceHost": "master",
  "slaveReplicationFactor": 1
}
Web Socket server started on address ws://localhost:3000
Http server started on address http://localhost:8080

Also, some logs from worker node:

Process started with config: {
  "grouperFile": "./src/operations/group.js",
  "initialDelay": 10,
  "mapperFile": "./src/operations/map.js",
  "masterHost": "master",
  "masterHttpPort": 8080,
  "masterPort": 3000,
  "slaveReplicationFactor": 1
}
Connecting to ws://master:3000
events.js:174
      throw er; // Unhandled 'error' event
      ^

Error: getaddrinfo EAI_AGAIN master master:3000
    at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:57:26)
Emitted 'error' event at:
    at ClientRequest.req.on (/app/node_modules/ws/lib/websocket.js:554:10)
    at ClientRequest.emit (events.js:189:13)
    at Socket.socketErrorListener (_http_client.js:392:9)
    at Socket.emit (events.js:189:13)
    at emitErrorNT (internal/streams/destroy.js:82:8)
    at emitErrorAndCloseNT (internal/streams/destroy.js:50:3)
    at process._tickCallback (internal/process/next_tick.js:63:19)

回答1:


This is your problem:

Web Socket server started on address ws://localhost:3000
Http server started on address http://localhost:8080

Don't bind to localhost. Bind to any IP 0.0.0.0. Or for more security bind to hostname -I IP For all outside your container is not localhost it's another host despite you run on the same machine.



来源:https://stackoverflow.com/questions/54851497/communication-between-containers-in-docker-swarm

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!