Windows宿主與docker容器網絡連接——Windows10環境下“遠程”訪問docker中centos系統裏的MySQL數據庫之續集

 

時隔二十天,喵哥又開始設置docker裏centos容器的網絡。目標是實現在宿主——Windows10下面可以訪問docker中centos容器裏的MySQL數據庫。

之前一篇博客記錄的是喵哥妥協解決這個問題的方案——在172.17.0.0這個網段裏面設置兩個centos容器,這樣就可以保證兩者互相訪問數據庫,但這沒有達到喵哥對數據庫服務器的要求——在宿主(Windows10)下編程使用數據庫。

這一次,喵哥從docker的網絡模式開始學習、理解、然後去解決問題。

1.docker的網絡模式

Docker常見的網絡模式有:

  1. Bridge模式 --net=bridge(默認)
  2. Host模式 --net=host
  3. Container模式 --net=container:指定容器名
  4. None模式 --net=none
  5. 用戶自定義模式

1.1bridge模式

Docker網絡的默認模式,在docker run啓動容器的時候,如果不加--net參數,就默認採用這種網絡模式。其特點如下:

  • 使用一個 linux bridge,默認爲 docker0

  • 使用 veth 對,一頭在容器的網絡 namespace 中,一頭在 docker0 上

  • 該模式下Docker Container不具有一個公有IP,因爲宿主機的IP地址與veth pair的 IP地址不在同一個網段內

  • Docker採用 NAT 方式,將容器內部的服務監聽的端口與宿主機的某一個端口port 進行“綁定”,使得宿主機以外的世界可以主動將網絡報文發送至容器內部

  • 外界訪問容器內的服務時,需要訪問宿主機的 IP 以及宿主機的端口 port

  • NAT 模式由於是在三層網絡上的實現手段,故肯定會影響網絡的傳輸效率。

  • 容器擁有獨立、隔離的網絡棧;讓容器和宿主機以外的世界通過NAT建立通信

 

Docker完成以上網絡配置的過程大致是這樣的:

1. 在主機上創建一對虛擬網卡veth pair設備。veth設備總是成對出現的,它們組成了一個數據的通道,數據從一個設備進入,就會從另一個設備出來。因此,veth設備常用來連接兩個網絡設備。 

2. Docker將veth pair設備的一端放在新創建的容器中,並命名爲eth0。另一端放在主機中,以veth65f9這樣類似的名字命名,並將這個網絡設備加入到docker0網橋中。

 

容器要跟外埠網絡通信,還需要一個NAT路由器,在Windows下它的名稱爲dockerNAT。

外界的機器要訪問docker容器,可以用端口映射的辦法把docker容器的端口跟宿主的端口做一個映射即可。

iptables -t nat -A  DOCKER -p tcp --dport 8001 -j DNAT --to-destination 172.17.0.19:8000

在Windows下是:

netsh interface portproxy add v4tov4 listenaddress=主機的IP listenport=50001 connectaddress=172.17.0.2 connectport=3306

然而,對於我來說,這些還是不夠。雖然,彷彿打通了外界機器與容器的通信,但是消息往往就到宿主就找不到路了。因爲沒有路由表。在宿主添加10.0.75.1到172.17.0.0網段的路由表,這樣就可以了。

 

1.2host模式

定義:

Host 模式並沒有爲容器創建一個隔離的網絡環境。而之所以稱之爲host模式,是因爲該模式下的 Docker 容器會和 host 宿主機共享同一個網絡 namespace,故 Docker Container可以和宿主機一樣,使用宿主機的eth0,實現和外界的通信。換言之,Docker Container的 IP 地址即爲宿主機 eth0 的 IP 地址。其特點包括:

  • 這種模式下的容器沒有隔離的 network namespace

  • 容器的 IP 地址同 Docker host 的 IP 地址

  • 需要注意容器中服務的端口號不能與 Docker host 上已經使用的端口號相沖突

  • host 模式能夠和其它模式共存

 

1.3container模式

 Container 網絡模式是 Docker 中一種較爲特別的網絡的模式。處於這個模式下的 Docker 容器會共享其他容器的網絡環境,因此,至少這兩個容器之間不存在網絡隔離,而這兩個容器又與宿主機以及除此之外其他的容器存在網絡隔離。  

 

1.4none模式

 

 網絡模式爲 none,即不爲 Docker 容器構造任何網絡環境。一旦Docker 容器採用了none 網絡模式,那麼容器內部就只能使用loopback網絡設備,不會再有其他的網絡資源。Docker Container的none網絡模式意味着不給該容器創建任何網絡環境,容器只能使用127.0.0.1的本機網絡。

 

2.解決

其實在1.1中已經把解決的方案大致說明了。

只要添加一個10.0.75.1網關到172.17.0.0網段的路由表即可。由於是在宿主訪問,不需要添加端口映射表。

 

route add -p 172.17.0.0 mask 255.255.255.0 10.0.75.2

然後只要在容器中的MySQL設置好訪問權限即可:

mysql> grant all PRIVILEGES on db_name.* to 'username'@'xxx.xxx.xx.x' identified by 'password' WITH GRANT OPTION;
 
#說明#
 
/*
  數據庫的授權用grant:
              grant 權限 on 數據庫.表 to 用戶 【identified by '密碼'】 with grant option;
  其中,
              權限有:select、insert、update、delete和all privileges。
              數據庫爲本地存在的數據庫名,表爲數據庫中的表,如果要全選某個項目,可用*代替,如
                    *.*表示所有數據庫的表,exp_country.*表示exp_country中的所有表,max_sal.k1表示max_sal中的k1表。
              用戶,可以在本地自建。也可以是遠程的,用'username'@'IP地址'表示。
              密碼爲可選項。
              附帶的with grant option可以使得被授權用戶也有賦予其他用戶權限的權力
  數據庫收回權限用revoke:
              revoke 權限 【on 數據庫.表】 option from 用戶; 
*/

例如,喵哥的centos容器需要通過10.0.75.1來轉發數據包,所以在MySQL中賦予權限的對象是10.0.75.1.

grant all PRIVILEGES on db_name.* to 'username'@'10.0.75.1' identified by 'password' WITH GRANT OPTION;

然後就可以在Windows端的MySQL登錄centos的MySQL數據庫了。

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章