Docker Swarm中容器之间的通信

4
我希望能够在Docker Swarm模式下通过WebSocket连接实现主节点和工作节点之间的通信。
需要确保从工作节点可以访问到主节点,但目前连接失败。
此外,我还希望能够通过http从我的主机连接到主节点,但同样连接失败。
这是我的 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:

我用以下命令创建了swarm:

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

我试图通过以下方式连接到主节点:

curl http://localhost:8080/result

并获取

curl: (7) Failed to connect to localhost port 8080: Connection refused
主节点

环境:

MASTER_PORT=3000
MASTER_HOST=localhost
MASTER_HTTP_PORT=8080

启动 WebSocket 服务器的代码:

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}`)
});

启动HTTP服务器的代码:

server.listen(config.masterHttpPort, config.masterHost, (err) => {
    if (err != null) {
      throw err
    }
    console.log(`Http server started on address http://${config.masterHost}:${config.masterHttpPort}`);
  });
工人

环境

MASTER_SERVICE_HOST=master
MASTER_PORT=3000

连接Websocket客户端到主节点的代码:

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

我很困惑,因为在使用docker-compose运行应用程序时(不是在swarm模式下),一切都运行得非常完美。

但是在swarm模式下,我无法通过http从主机访问主节点,也无法通过websocket连接从工作节点访问主节点。

我怀疑自己对docker网络配置的配置有误。

主节点的日志:

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

此外,一些来自工作节点的日志记录:
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
你确定主节点没有启动和运行吗? - ozlevka
主节点正常运行,因为工作节点依赖于主节点。 - Ivan Prodaiko
上传两个服务的日志:docker service logs [service_name] - ozlevka
1个回答

0

这是你的问题:

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

不要绑定到本地主机。绑定到任何IP 0.0.0.0。 或者为了更安全,绑定到hostname -I IP 对于所有容器外的内容,它不是本地主机,而是另一个主机,尽管您在同一台机器上运行。

那么,我需要在0.0.0.0:3000和0.0.0.0:8080上运行我的服务器吗? - Ivan Prodaiko
在普通的容器编排中,我可以通过服务名称进行连接。在群集模式下也能做到吗? - Ivan Prodaiko
是的...你不能绑定到本地主机并从外部查询。尝试将新的绑定放入你的应用程序中。 - ozlevka
容器之间的通信方式是相同的吗? - Ivan Prodaiko
容器之间的通信等同于机器之间的通信。 - ozlevka

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接