我有一个docker容器,它充当副本集的单个成员。我能够成功启动其中的三个并在其中运行一些shell脚本,以便将它们作为副本集连接在一起。我发现我可以从我的主机上单独连接到每个成员,但是当我尝试通过在boot2docker上列出每个成员来连接到副本集(在我的情况下,通过spring-data-mongodb) IP和相应的端口,我发现应用程序在某处交换每个容器IP的boot2docker IP并尝试直接连接到该IP。
我假设发生这种情况是因为初始连接字符串只是种子列表,然后通过与成员本身的通信提供实际配置。当然,这是一个问题,因为主机上(运行应用程序的地方)上的IP不存在,只在boot2docker VM内部存在。如何让成员报告boot2docker IP而不是他们各自无法访问的IP?
我发现了与elasticsearch类似的内容,并且可以通过设置network.publish_host
变量来修复它。 mongodb有类似的设置吗?我想也许bind_ip是正确的东西,但一直无法做到这一点,我使用的不正确吗?我一直把它设置为boot2docker IP并在启动时收到绑定错误。
另外,我可以确认这只是boot2docker投入混音的一个问题,因为运行ubuntu和本地docker的朋友能够很好地连接。
这是我在尝试将bind_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"/>
这是我的应用看到的错误(如果我只是在没有尝试更改bind_ip等情况下启动了事情)
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]
这些IP是每个容器的IP,每个容器确实在端口27017上启动,但随后我在boot2docker VM上将它们的端口发布为27017,27018和27019.
答案 0 :(得分:1)
我找到了解决方法。从本质上讲,对mongo客户端(在我的情况下,弹簧数据)重要的是副本集成员自己报告的地址。初始连接字符串只是遍历的种子列表,直到其中一个指定成员使用副本集配置的完整详细信息响应客户端。
这意味着为重试尝试而记录的实际IP以及将来与副本集的所有未来交互都是由客户端请求其配置时副本集报告回客户端的内容决定的,该配置由内容确定。副本集配置文件。
由于副本集是使用docker容器IP启动的,因此这些是在副本集配置文档中记录的IP,然后在启动时报告给应用程序,因此一旦客户端切换到使用这些IP,它就不再能够连接到容器,因为docker IP没有暴露在boot2docker VM之外。
解决方案(在我的情况下)是更改副本集初始配置,而不是提供成员IP,就像它是从主机启动一样(所以他们真的只是在boot2docker上暴露的不同端口)机)。这意味着配置文档中的地址可由主机上的任何客户端访问,而不仅仅是boot2docker中的客户端。
答案 1 :(得分:1)
在关注this tutorial to set up a mongodb cluster via docker之后,我遇到了类似的问题。为了能够打开与此群集的正确副本集连接,我对指令进行了以下两个修改:
docker run -p 30001:30001 --name mongo1 --net host mongo mongod --replSet rs1 --port 30001
(&#34; - net host&#34;使用主机网络,然后必须重新映射端口以使用主机上的可用端口。不确定在此设置中是否甚至需要端口转发选项)
docker-machine env
然后将该IP插入副本集配置中(因此VM的IP为192.168.99.100):
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"
}
]
}
显然,整个设置仅用于测试,而不是为生产而设计。
答案 2 :(得分:-1)
你必须在容器的IP地址
中启动你的mongod试试这个:/ usr / bin / mongod --auth --dbpath / data / db / --replSet rs0 --bind_ip 172.17.0.34
172.17.0.34是您的容器的地址(mongod primairy)