一段时间以来,我们一直在使用单容器 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 套接字连接不能。