MongoDB——centos7 docker容器访问宿主机的 ip-无法初始mongo副本集

问题描述:

在三台centos7上配置mongo副本集,

三节点启动

docker run -d --name mongoconfig \
              -p 26001:27019 \
              -v /root/data/soft/mongo/configdb:/data/configdb \
              \mongo:4.0.24 \
              --configsvr \
              --replSet "replconfig" \
              --bind_ip_all
初始化config副本集
rs.status()
config = {
    _id : "replconfig",
     members : [
         {_id : 0, host : "192.168.1.20:26001" },
         {_id : 1, host : "192.168.1.21:26001" },
         {_id : 2, host : "192.168.1.22:26001" }
     ]
 }
rs.initiate(config)

在初始化副本集时,用的是宿主ip,报错不识别本节点,即无法从容器内访问宿主ip。

报错如下:

[root@bogon mongo]# docker exec -it mongoconfig  mongo 192.168.1.20:26001 -eval "rs.status()"
MongoDB shell version v4.0.24
connecting to: mongodb://192.168.1.20:26001/test?gssapiServiceName=mongodb
2021-05-17T10:02:06.601+0000 E QUERY    [js] Error: couldn't connect to server 192.168.1.20:26001, connection attempt failed: SocketException: Error connecting to 192.168.1.20:26001 :: caused by :: No route to host :
connect@src/mongo/shell/mongo.js:356:17
@(connect):2:6
exception: connect failed
[root@bogon mongo]#

> config

{

"_id" : "replconfig",

"members" : [

{

"_id" : 0,

"host" : "192.168.1.20:26001"

},

{

"_id" : 1,

"host" : "192.168.1.21:26001"

},

{

"_id" : 2,

"host" : "192.168.1.22:26001"

}

]

}

> 

> 

> rs.initiate(config)

{

"ok" : 0,

"errmsg" : "No host described in new configuration 1 for replica set replconfig maps to this node",

"code" : 93,

"codeName" : "InvalidReplicaSetConfig",

"$gleStats" : {

"lastOpTime" : Timestamp(0, 0),

"electionId" : ObjectId("000000000000000000000000")

},

"lastCommittedOpTime" : Timestamp(0, 0)

}

> 

 

 

 

问题分析

在 centos7 上部署 docker 容器,其网络模式采用的是 bridge 模式。
启动 docker 时,docker 进程会创建一个名为 docker0 的虚拟网桥,用于宿主机与容器之间的通信。当启动一个 docker 容器时,docker 容器将会附加到虚拟网桥上,容器内的报文通过 docker0 向外转发。

如果 docker 容器访问宿主机,那么 docker0 网桥将报文直接转发到本机,报文的源地址是 docker0 网段的地址。而如果 docker 容器访问宿主机以外的机器,docker 的 SNAT 网桥会将报文的源地址转换为宿主机的地址,通过宿主机的网卡向外发送。

因此,当 docker 容器访问宿主机时,如果宿主机服务端口会被防火墙拦截,那么就无法连通宿主机,出现 No route to host 的错误。

而访问宿主机所在局域网内的其他机器,由于报文的源地址是宿主机 ip,因此,不会被目的机器防火墙拦截,所以可以访问。

 

解决问题 方法一

粗暴关闭 

systemctl stop firewalld

 

解决问题 方法二

容器访问宿主机的地址使用 eth0 的地址,即宿主机内网 ip 地址。
运行 ipconfig 命令,查看网络的虚拟网桥相关信息。

注意:宿主机会把容器 ip 地址段当成外网 ip。(当前说明是 centos7 环境)

编辑防火墙文件 /etc/firewalld/zones/public.xml,添加下面 docker0 地址段到配置:

<rule family="ipv4">
<source address="172.17.0.0/16"/>
<accept/>
</rule>

如下

vim /etc/firewalld/zones/public.xml

<?xml version="1.0" encoding="utf-8"?>
<zone>
  <short>Public</short>
  <description>For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description>
  <service name="ssh"/>
  <service name="dhcpv6-client"/>


<rule family="ipv4">
  <source address="172.17.0.0/16"/>
  <accept/>
</rule>

</zone>

 


重启防火墙,docker 容器即可正常访问宿主机端口

firewall-cmd --reload

或者重启防火墙服务

service firewalld restart

 

之后再从容中访问宿主ip映射的26001,通过

[root@bogon mongo]# docker exec -it mongoconfig  mongo 192.168.1.20:26001 -eval "rs.status()"
MongoDB shell version v4.0.24
connecting to: mongodb://192.168.1.20:26001/test?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("78e18609-4abb-453e-9de8-0b0f0617864e") }
MongoDB server version: 4.0.24
{
    "ok" : 0,
    "errmsg" : "no replset config has been received",
    "code" : 94,
    "codeName" : "NotYetInitialized",
    "$gleStats" : {
        "lastOpTime" : Timestamp(0, 0),
        "electionId" : ObjectId("000000000000000000000000")
    },
    "lastCommittedOpTime" : Timestamp(0, 0)
}
[root@bogon mongo]# 

 

posted @ 2021-05-17 18:19  会飞的斧头  阅读(1129)  评论(0编辑  收藏  举报