Mongodb、Boot2Docker和副本集连接

Mongodb、Boot2Docker和副本集连接,mongodb,docker,boot2docker,replicaset,Mongodb,Docker,Boot2docker,Replicaset,我有一个docker容器,它充当复制集的单个成员。我能够成功地启动其中三个,并在其中运行一些shell脚本,以便将它们作为副本集连接在一起。我发现我可以从主机单独连接到每个成员,但是当我尝试连接到副本集(在我的情况下,通过spring data mongodb)时,通过在boot2docker IP和相应端口列出每个成员,我发现应用程序在某个地方为每个容器IP交换boot2docker IP,并尝试在该IP上直接连接 我假设发生这种情况是因为初始连接字符串只是一个种子列表,然后通过与成员本身的通

我有一个docker容器,它充当复制集的单个成员。我能够成功地启动其中三个,并在其中运行一些shell脚本,以便将它们作为副本集连接在一起。我发现我可以从主机单独连接到每个成员,但是当我尝试连接到副本集(在我的情况下,通过spring data mongodb)时,通过在boot2docker IP和相应端口列出每个成员,我发现应用程序在某个地方为每个容器IP交换boot2docker IP,并尝试在该IP上直接连接

我假设发生这种情况是因为初始连接字符串只是一个种子列表,然后通过与成员本身的通信来提供实际配置。当然,这是一个问题,因为这些IP不存在于主机上(应用程序运行的地方),只存在于boot2docker VM中。我如何让成员报告boot2docker IP而不是他们各自无法访问的IP

我在elasticsearch中遇到了类似的问题,并通过设置
network.publish\u host
变量来修复它。mongodb有类似的设置吗?我认为bind_ip可能是正确的东西,但一直无法实现这一点,我是否使用不当?我一直在将其设置为boot2docker IP,并在启动时收到一个绑定错误

此外,我可以确认这只是boot2docker加入混搭的一个问题,因为我运行ubuntu和native docker的朋友能够很好地连接

以下是我在尝试将绑定ip设置到boot2docker vm时看到的错误:

Starting mongod process using command: /usr/bin/mongod --storageEngine wiredTiger --auth --dbpath /data/db/ --replSet rs0 --bind_ip 127.0.0.1,192.168.59.103 --keyFile /mongodb-keyfile
2015-04-19T16:34:41.123+0000 E NETWORK  [initandlisten] listen(): bind() failed errno:99 Cannot assign requested address for socket: 192.168.59.103:27017
以下是我的spring xml中的连接字符串:

<mongo:mongo id="mongo" replica-set="192.168.59.103:27017,192.168.59.103:27018,192.168.59.103:27019"/>

这些IP是每个容器的IP,每个容器确实在端口27017上启动,但是我在boot2docker VM上将它们的端口发布为27017、27018和27019。

您必须在容器的IP地址中启动mongod

试试这个:/usr/bin/mongod--auth--dbpath/data/db/--replSet rs0--bind_ip 172.17.0.34


172.17.0.34是您的集装箱地址(mongod Primary)

我找到了解决方案。本质上,mongo客户机(在我的例子中是spring数据)关心的是副本集成员自己报告的地址。初始连接字符串只是一个种子列表,在其中一个指定成员向客户端响应副本集配置的完整详细信息之前,将遍历该列表

这意味着,为重试尝试而记录的实际IP以及将来与副本集的所有交互,都是由副本集在客户端请求其配置时向客户端报告的内容决定的,该配置由副本集配置文档的内容决定

由于复制集是使用docker容器IP启动的,这些IP记录在副本集配置文档中,然后在启动时报告给应用程序,因此一旦客户端切换到使用这些IP,它就无法再连接到容器,因为docker IP不会暴露在boot2docker VM之外


解决方案(在我的例子中)是更改副本集初始配置,以提供成员IP,就好像它是从主机启动的(因此实际上它们只是boot2docker机器上公开的不同端口)。这意味着配置文档中的地址可以被我主机上的任何客户机访问,而不仅仅是boot2docker中的客户机。

我在执行以下操作后遇到了类似的问题。为了能够打开到该群集的正确副本集连接,我对说明进行了以下两项修改:

  • 我没有使用专用的docker网桥,而是使用托管网络,通过以下方式启动每个节点(例如):
  • docker run-p 30001:30001--名称mongo1--网络主机MongoMongod --replSet rs1—端口30001

    (“--net host”使用主机网络,然后必须重新映射端口以使用主机上的可用端口。不确定在此设置中是否需要端口转发选项)

  • 我使用docker机器在windows上运行,因此我使用以下方法检索vm的ip:
  • docker机器环境

    然后将该IP插入副本集配置,因此(在本例中,VM的IP为192.168.99.100):


    显然,整个设置仅用于测试,而不是设计用于生产。

    mongod进程是在docker容器本身中启动的,所以IP不应该是本地主机吗?问题在于boot2docker将我路由到容器IP地址,但主机无法到达该IP上的容器-它只能直接访问boot2docker VM。mongod进程应在docker容器IP地址中启动。默认情况下,主机无法访问容器ip,因此您必须手动执行此操作:docker run-d-p host_ip:port:27017 mongo_image,您现在可以通过host_ip:port访问容器
    Client view of cluster state is {type=ReplicaSet, servers=[{address=172.17.0.34:27017, type=Unknown, state=Connecting}, {address=172.17.0.35:27017, type=Unknown, state=Connecting}, {address=172.17.0.36:27017, type=Unknown, state=Connecting}]
            at com.mongodb.BaseCluster.getServer(BaseCluster.java:82) ~[mongo-java-driver-2.13.0.jar:na]
    
    config = {
          "_id" : "rs1",
          "members" : [
            {
              "_id" : 0,
              "host" : "192.168.99.100:30001"
            },
            {
              "_id" : 1,
              "host" : "192.168.99.100:30002"
            },
            {
              "_id" : 2,
              "host" : "192.168.99.100:30003"
            }
          ]
        }