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]# 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM