1

一段时间以来,我们一直在使用单容器 Docker 映像,但在 RHEL8 上没有问题。我们需要使用 docker-compose 来集成多个服务,但即使是简单的尝试也没有成功。

我们正在使用 Mongo (mongo:4.2.3-bionic) 和 NodeJS (node:alpine)。

我们创建了一个简单的节点应用程序,它试图将单个文档添加到 MongoDB 集合中。dbwrite.js 的代码是:

var MongoClient = require('mongodb').MongoClient;

MongoClient.connect("mongodb://mongo:27017/", function(err, mongodb) {
  if (err) throw err;
  var mongodbo = mongodb.db("test");
  var doc = {"payload":"test doc"};
  mongodbo.collection("test2").insertOne(doc, function(err, res) {
    if (err) throw err;
  });
  mongodb.close();
});

dbwrite.js 的 Dockerfile 是:

FROM node:alpine
ADD . /
CMD ["node", "dbwrite.js"]

Mongo 容器和 Node 容器一样是从 DockerHub 中提取的。

docker-compose.yaml 文件:

version: '3.1'
services:
  mongo:
    image: mongo:4.2.3-bionic
    container_name: mongo
    restart: always
  ports:
    - 27017:27017
  volumes:
    - ./mongo_db:/data/db

app:
  image: dbwrite:v0.1
  container_name: dbwrite

如果我们执行“docker-compose up”,dbwrite 容器会抛出错误:

dbwrite  | /node_modules/mongodb/lib/topologies/server.js:233
dbwrite  |             throw err;
dbwrite  |             ^
dbwrite  | 
dbwrite  | MongoNetworkError: failed to connect to server [mongo:27017] on first connect [Error:    connect EHOSTUNREACH 172.22.0.2:27017
dbwrite  |     at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1137:16) {
dbwrite  |   name: 'MongoNetworkError',
dbwrite  |   [Symbol(mongoErrorContextSymbol)]: {}
dbwrite  | }]
dbwrite  |     at Pool.<anonymous> (/node_modules/mongodb/lib/core/topologies/server.js:438:11)
dbwrite  |     at Pool.emit (events.js:321:20)
dbwrite  |     at /node_modules/mongodb/lib/core/connection/pool.js:561:14
dbwrite  |     at /node_modules/mongodb/lib/core/connection/pool.js:994:11
dbwrite  |     at /node_modules/mongodb/lib/core/connection/connect.js:31:7
dbwrite  |     at callback (/node_modules/mongodb/lib/core/connection/connect.js:264:5)
dbwrite  |     at Socket.<anonymous> (/node_modules/mongodb/lib/core/connection/connect.js:294:7)
dbwrite  |     at Object.onceWrapper (events.js:428:26)
dbwrite  |     at Socket.emit (events.js:321:20)
dbwrite  |     at emitErrorNT (internal/streams/destroy.js:84:8) {
dbwrite  |   name: 'MongoNetworkError',
dbwrite  |   [Symbol(mongoErrorContextSymbol)]: {}
dbwrite  | }
dbwrite exited with code 1

重建容器(以艰难的方式进行——我知道——但希望保持一切尽可能相同),并替换 Dockerfile CMD 行

CMD ["node", "dbwrite.js"]

CMD ["ping", "-c", "20", "mongo"]

从“mongo”产生正常的 ping 响应,所以我相信默认网络是正确创建的,并且 DNS 正在按预期发生,但我的节点应用程序获得了 EHOSTUNREACH。

dbwrite  | 64 bytes from 172.22.0.2: seq=15 ttl=64 time=0.072 ms
dbwrite  | 64 bytes from 172.22.0.2: seq=16 ttl=64 time=0.080 ms
dbwrite  | 64 bytes from 172.22.0.2: seq=17 ttl=64 time=0.067 ms
dbwrite  | 64 bytes from 172.22.0.2: seq=18 ttl=64 time=0.121 ms
dbwrite  | 64 bytes from 172.22.0.2: seq=19 ttl=64 time=0.097 ms
dbwrite  | 
dbwrite  | --- mongo ping statistics ---
dbwrite  | 20 packets transmitted, 20 packets received, 0% packet loss
dbwrite  | round-trip min/avg/max = 0.065/0.086/0.121 ms
dbwrite exited with code 0

如果我们编辑 dbwrite.js 代码并将 connect() 方法中的“mongo”替换为“localhost”,并从 localhost(容器外部)执行“node dbwrite.js”,将 Document 发送到 Collection。Mongo 容器日志报告它正在侦听 0.0.0.0。

mongo    | 2020-02-10T19:35:26.337+0000 I  NETWORK  [listener] Listening on 0.0.0.0
mongo    | 2020-02-10T19:35:26.337+0000 I  NETWORK  [listener] waiting for connections on port 27017

虽然我没有捕获输出,但之前执行的“docker network inspect”在 172.22.0.x/16 上显示了容器及其分配的 IPv4 地址。IPAM 显示在子网 172.22.0.0/16 和网关 172.22.0.1 上使用默认驱动程序“网桥”。

任何关于可能出错的建议将不胜感激。我们正处于降级 RHEL8 的边缘,看看这是否与我们的问题有关,因为 Red Hat 如此明确地声称支持 Docker。似乎这是一些网络安全问题,因为 ICMP ping 可以遍历网桥但 TCP 套接字连接不能。

4

0 回答 0