我成功地使用三个容器创建了docker副本集:

CONTAINER ID        IMAGE               PORTS              NAMES
b530275d1958        mongo       0.0.0.0:30003->27017/tcp   mongo3
dca4fa2d6f93        mongo       0.0.0.0:30002->27017/tcp   mongo2
0b4823661cf1        mongo       0.0.0.0:27017->27017/tcp   mongo1

此外,副本集已成功配置:
rs0:PRIMARY> rs.status()
{
    "set" : "rs0",
    "date" : ISODate("2018-01-08T20:57:30.395Z"),
    "myState" : 1,
    "term" : NumberLong(16),
    "heartbeatIntervalMillis" : NumberLong(2000),
    "optimes" : {
        "lastCommittedOpTime" : {
            "ts" : Timestamp(1515445046, 1),
            "t" : NumberLong(16)
        },
        "readConcernMajorityOpTime" : {
            "ts" : Timestamp(1515445046, 1),
            "t" : NumberLong(16)
        },
        "appliedOpTime" : {
            "ts" : Timestamp(1515445046, 1),
            "t" : NumberLong(16)
        },
        "durableOpTime" : {
            "ts" : Timestamp(1515445046, 1),
            "t" : NumberLong(16)
        }
    },
    "members" : [
        {
            "_id" : 0,
            "name" : "mongo1:27017",
            "health" : 1,
            "state" : 1,
            "stateStr" : "PRIMARY",
            "uptime" : 898,
            "optime" : {
                "ts" : Timestamp(1515445046, 1),
                "t" : NumberLong(16)
            },
            "optimeDate" : ISODate("2018-01-08T20:57:26Z"),
            "electionTime" : Timestamp(1515444174, 1),
            "electionDate" : ISODate("2018-01-08T20:42:54Z"),
            "configVersion" : 1,
            "self" : true
        },
        {
            "_id" : 1,
            "name" : "mongo2:27017",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 877,
            "optime" : {
                "ts" : Timestamp(1515445046, 1),
                "t" : NumberLong(16)
            },
            "optimeDurable" : {
                "ts" : Timestamp(1515445046, 1),
                "t" : NumberLong(16)
            },
            "optimeDate" : ISODate("2018-01-08T20:57:26Z"),
            "optimeDurableDate" : ISODate("2018-01-08T20:57:26Z"),
            "lastHeartbeat" : ISODate("2018-01-08T20:57:29.056Z"),
            "lastHeartbeatRecv" : ISODate("2018-01-08T20:57:30.324Z"),
            "pingMs" : NumberLong(0),
            "syncingTo" : "mongo1:27017",
            "configVersion" : 1
        },
        {
            "_id" : 2,
            "name" : "mongo3:27017",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 871,
            "optime" : {
                "ts" : Timestamp(1515445046, 1),
                "t" : NumberLong(16)
            },
            "optimeDurable" : {
                "ts" : Timestamp(1515445046, 1),
                "t" : NumberLong(16)
            },
            "optimeDate" : ISODate("2018-01-08T20:57:26Z"),
            "optimeDurableDate" : ISODate("2018-01-08T20:57:26Z"),
            "lastHeartbeat" : ISODate("2018-01-08T20:57:29.055Z"),
            "lastHeartbeatRecv" : ISODate("2018-01-08T20:57:29.506Z"),
            "pingMs" : NumberLong(0),
            "syncingTo" : "mongo1:27017",
            "configVersion" : 1
        }
    ],
    "ok" : 1,
    "operationTime" : Timestamp(1515445046, 1),
    "$clusterTime" : {
        "clusterTime" : Timestamp(1515445046, 1),
        "signature" : {
            "hash" : BinData(0,"c3aBSVWElstPhnBx3c5NysBfdmk="),
            "keyId" : NumberLong("6504664228182360065")
        }
    }
}

重要的是要注意,它是端口270173000230003上的仅一个VM连接

但是,当我的PHP应用程序使用我附加到它的mongo DSN字符串连接到它时,似乎出现了问题
mongodb://<username>:<pass>@172.31.6.177:27017,172.31.6.177:30002,172.31.6.177:30003/opsserver-main?replicaSet=rs0&amp;authSource=admin"

我的PHP应用程序中出现错误:
[Doctrine\MongoDB\Exception\ResultException]
  No suitable servers found: `serverSelectionTimeoutMS` expired: [connection timeout calling i
  smaster on '172.31.6.177:27017'] [connection timeout calling ismaster on 'mongo1:27017'] [co
  nnection timeout calling ismaster on 'mongo2:27017'] [connection timeout calling ismaster on
   'mongo3:27017']

我很奇怪它知道容器名称,或者至少尝试连接到它。我究竟做错了什么?

最佳答案

这是因为在docker网络内部,容器mongo1mongo2mongo3可以相互找到。但是,主机系统不知道这些名称,因此您的应用程序无法连接到整个集合。

您可以尝试从主机系统ping mongo1,其中应该显示Unknown host

解决此问题的最简单方法是更改​​副本集配置中的主机名(使用rs.initiate(...)启动副本集时使用的主机名),例如:

  • mongo1:27017-> <your local hostname>:27017
  • mongo2:27017-> <your local hostname>:30002
  • mongo3:27017-> <your local hostname>:30003

  • <your local hostname>替换为hostname -f命令的输出。

    这样,您的本地主机可以找到所有副本集节点,而所有副本集节点仍可以通过本地主机的端口映射找到彼此。

    关于mongodb - MongoDB Docker副本集-应用程序连接超时,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48158054/

    10-09 20:14