docker(7、容器網絡3) macvlan 網絡 不支持DNS服務

macvlan 本身是 linux kernel 模塊,其功能是允許在同一個物理網卡上配置多個 MAC 地址,即多個 interface,每個 interface 可以配置自己的 IP。

macvlan 本質上是一種網卡虛擬化技術,Docker 用 macvlan 實現容器網絡。

macvlan 的最大優點是性能極好,相比其他實現,macvlan 不需要創建 Linux bridge,而是直接通過以太 interface 連接到物理網絡。

1、準備實驗環境

創建一個 macvlan 網絡。

使用 host1 和 host2 上再添加單獨的網卡 ens37 創建 macvlan

爲保證多個 MAC 地址的網絡包都可以從 ens192 通過,需要打開網卡的混雜模式。

ip link set ens37 promisc on

ip link show ens37

確保 ens37 狀態 UP 並且 promisc 模式已經生效。

 如果 host1 和 host2 是 vwmare 虛擬機,還需要在網卡配置選項頁中設置混雜模式

2、創建 macvlan 網絡

在 host1 和 host2 中創建 macvlan 網絡 mac_net1:

docker network create -d macvlan --subnet=172.16.86.0/24 --gateway=172.16.86.1 -o parent=ens37 mac_net1

 

注意:在 host2 中也要執行相同的命令。

1) -d macvlan 指定 driver 爲 macvlan。

2) macvlan 網絡是 local 網絡,爲了保證跨主機能夠通信,用戶需要自己管理 IP subnet。

3) 與其他網絡不同,docker 不會爲 macvlan 創建網關,這裏的網關應該是真實存在的,否則容器無法路由。

4) -o parent 指定使用的網絡 interface。

在 host1 中運行容器 bbox1 並連接到 mac_net1。

由於 host1 中的 mac_net1 與 host2 中的 mac_net1 本質上是獨立的,爲了避免自動分配造成 IP 衝突,我們最好通過 --ip 指定 bbox1 地址爲 172.16.86.10。

docker run -itd --name bbox1 --ip=172.16.86.10 --network mac_net1 busybox 

在 host2 中運行容器 bbox2,指定 IP 172.16.86.11。

docker run -itd --name  bbox2 --ip=172.16.86.11 --network mac_net1 busybox

驗證 bbox1 和 bbox1 的連通性。

bbox2 能夠 ping 到 bbox1 的 IP 172.16.86.10,但無法解析 “bbox1” 主機名。

可見 docker 沒有爲 macvlan 提供 DNS 服務,這點與 overlay 網絡是不同的。

3、macvlan 網絡結構分析

macvlan 不依賴 Linux bridge,brctl show 可以確認沒有創建新的 bridge。 docker——gwbridge 是overlay網絡生成的,不是本環境的

查看一下容器 bbox1 的網絡設備:

除了 lo,容器只有一個 eth0,請注意 eth0 後面的 @if16,這表明該 interface 有一個對應的 interface,其全局的編號爲 16。

根據 macvlan 的原理,我們有理由猜測這個 interface 就是主機的 ens37,確認如下:

由此可見,容器的 eth0 就是 ens37 通過 macvlan 虛擬出來的 interface。

容器的 interface 直接與主機的網卡連接,這種方案使得容器無需通過 NAT 和端口映射就能與外網直接通信(只要有網關),在網絡上與其他獨立主機沒有區別。

當前網絡結構如圖所示

 

4、用 sub-interface 實現多 macvlan 網絡(另外的環境的測試網卡是ens192的Ubuntu系統)

macvlan 會獨佔主機的網卡,也就是說一個網卡只能創建一個 macvlan 網絡,否則會報錯:

但主機的網卡數量是有限的,如何支持更多的 macvlan 網絡呢?

好在 macvlan 不僅可以連接到 interface(如 ens192),也可以連接到 sub-interface(如 ens192.xxx)。

VLAN 是現代網絡常用的網絡虛擬化技術,它可以將物理的二層網絡劃分成多達 4094 個邏輯網絡,這些邏輯網絡在二層上是隔離的,每個邏輯網絡(即 VLAN)由 VLAN ID 區分,VLAN ID 的取值爲 1-4094。

Linux 的網卡也能支持 VLAN(apt-get install vlan),同一個 interface 可以收發多個 VLAN 的數據包,不過前提是要創建 VLAN 的 sub-interface。

比如希望 ens192 同時支持 VLAN10 和 VLAN20,則需創建 sub-interface ens192.10 和 ens192.20。

在交換機上,如果某個 port 只能收發單個 VLAN 的數據,該 port 爲 Access 模式,如果支持多 VLAN,則爲 Trunk 模式,所以接下來實驗的前提是:

ens192 要接在交換機的 trunk 口上。如果是虛擬機,則不需要額外配置了。

在 ens192.10 和 ens192.20 上創建 macvlan 網絡。

首先編輯 host1 和 host2 的 /etc/network/interfaces,配置 sub-interfaces:

 

然後啓用 sub-interface:

創建 macvlan 網絡:

host1上:

docker network create -d macvlan --subnet=172.16.10.0/24 --gateway=172.16.10.1 -o parent=ens192.10 mac_net10

docker network create -d macvlan --subnet=172.16.20.0/24 --gateway=172.16.20.1 -o parent=ens192.20 mac_net20

host2上用同樣方法創建macvlan網絡。

在 host1 中運行容器:

 

在 host2 中運行容器:

 

當前網絡結構如圖所示:

5、macvlan 網絡隔離和連通

驗證 macvlan 之間的連通性。

bbox1 能 ping 通 bbox3,bbox2 能 ping 通 bbox4。

即:同一 macvlan 網絡能通信。

bbox1 無法 ping 通 bbox2 和 bbox4。

即:不同 macvlan 網絡之間不能通信。

但更準確的說法應該是:不同 macvlan 網絡不能 在二層上 通信。

在三層上可以通過網關將 macvlan 連通,下面我們就啓用網關。

將 額外的doceker-machine配置成一個虛擬路由器,設置網關並轉發 VLAN10 和 VLAN20 的流量。

當然也可以使用物理路由器達到同樣的效果。首先確保操作系統 IP Forwarding 已經啓用。

輸出爲 1 則表示啓用,如果爲 0 可通過如下命令啓用:

sysctl -w net.ipv4.ip_forward=1

 

在 /etc/network/interfaces 中配置 vlan sub-interface:

啓用 sub-interface:

ifup ens192.10

ifup ens192.20

將網關 IP 配置到 sub-interface:

[root@ubuntu ~]$ifconfig ens192.10 172.16.10.1 netmask 255.255.255.0 up

[root@ubuntu ~]$ifconfig ens192.20 172.16.20.1 netmask 255.255.255.0 up

 

添加 iptables 規則,轉發不同 VLAN 的數據包。

iptables -t nat -A POSTROUTING -o ens192.10 -j MASQUERADE

iptables -t nat -A POSTROUTING -o ens192.20 -j MASQUERADE

iptables -A FORWARD -i ens192.10 -o ens192.20 -m state --state RELATED,ESTABLISHED -j ACCEPT

iptables -A FORWARD -i ens192.20 -o ens192.10 -m state --state RELATED,ESTABLISHED -j ACCEPT

iptables -A FORWARD -i ens192.10 -o ens192.20 -j ACCEPT

iptables -A FORWARD -i ens192.20 -o ens192.10 -j ACCEPT

 

當前網絡拓撲如下圖所示:

現在 host1 上位於 mac_net10 的 bbox1 已經可以與 host2 上位於 mac_net20 的 bbox4 通信了。

下面我們分析數據包是如何從 bbox1(172.16.10.10)到達 bbox4(172.16.20.11)的。整個過程如下圖所示:

1) 因爲 bbox1 與 bbox4 在不同的 IP 網段,跟據 bbox1 的路由表:

數據包將發送到網關 172.16.10.1。

2) 路由器從 ens192.10 收到數據包,發現目的地址是 172.16.20.11,查看自己的路由表:

於是將數據包從 ens192.20 轉發出去。

3) 通過 ARP 記錄的信息,路由器能夠得知 172.16.20.11 在 host2 上,於是將數據包發送給 host2。

4) host2 根據目的地址和 VLAN 信息將數據包發送給 bbox4。

macvlan 網絡的連通和隔離完全依賴 VLAN、IP subnet 和路由,docker 本身不做任何限制,用戶可以像管理傳統 VLAN 網絡那樣管理 macvlan。

 

 

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