Docker 網絡模型之 macvlan 詳解,圖解,實驗完整

本文首發於個人公衆號 Linux雲計算網絡(id: cloud_dev),專一於乾貨分享,號內有 10T 書籍和視頻資源,後臺回覆 「1024」便可領取,歡迎你們關注,二維碼文末能夠掃。

上一篇文章咱們詳細介紹了 macvlan 這種技術,macvlan 詳解,因爲它高效易配置的特性,被用在了 Docker 的網絡方案設計中,這篇文章就來講說這個。html

01 macvlan 用於 Docker 網絡

在 Docker 中,macvlan 是衆多 Docker 網絡模型中的一種,而且是一種跨主機的網絡模型,做爲一種驅動(driver)啓用(-d 參數指定),Docker macvlan 只支持 bridge 模式。linux

下面咱們作兩個實驗,分別驗證相同 macvlan 網絡和不一樣 macvlan 網絡的連通性。docker

1.1 相同 macvlan 網絡之間的通訊

首先準備兩個主機節點的 Docker 環境,搭建以下拓撲圖示:編程

1 首先使用 docker network create 分別在兩臺主機上建立兩個 macvlan 網絡:ubuntu

root@ubuntu:~# docker network create -d macvlan --subnet=172.16.10.0/24 --gateway=172.16.10.1 -o parent=enp0s8 mac1

這條命令中,安全

  • -d 指定 Docker 網絡 driver
  • --subnet 指定 macvlan 網絡所在的網絡
  • --gateway 指定網關
  • -o parent 指定用來分配 macvlan 網絡的物理網卡

以後能夠看到當前主機的網絡環境,其中出現了 macvlan 網絡:網絡

root@ubuntu:~# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
128956db798a        bridge              bridge              local
19fb1af129e6        host                host                local
2509b3717813        mac1                macvlan             local
d5b0798e725e        none                null                local

2 在 host1 運行容器 c1,並指定使用 macvlan 網絡:工具

root@ubuntu:~# docker run -itd --name c1 --ip=172.16.10.2 --network mac1 busybox

這條命令中,post

  • --ip 指定容器 c1 使用的 IP,這樣作的目的是防止自動分配,形成 IP 衝突
  • --network 指定 macvlan 網絡

一樣在 host2 中運行容器 c2:雲計算

root@ubuntu:~# docker run -itd --name c2 --ip=172.16.10.3 --network mac1 busybox

3 在 host1 c1 中 ping host2 c2:

root@ubuntu:~# docker exec c1 ping -c 2 172.16.10.3
PING 172.16.10.3 (172.16.10.3): 56 data bytes
64 bytes from 172.16.10.3: seq=0 ttl=64 time=0.641 ms
64 bytes from 172.16.10.3: seq=1 ttl=64 time=0.393 ms

--- 172.16.10.3 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss

round-trip min/avg/max = 0.393/0.517/0.641 ms
注意:以上的實驗都須要物理網卡 enp0s8 開啓混雜模式,否則會 ping 不通。

1.2 不一樣 macvlan 網絡之間的通訊

接下來,咱們來看看不一樣 macvlan 網絡之間的連通性,搭建如下的拓撲環境:

因爲 macvlan 網絡會獨佔物理網卡,也就是說一張物理網卡只能建立一個 macvlan 網絡,若是咱們想建立多個 macvlan 網絡就得用多張網卡,但主機的物理網卡是有限的,怎麼辦呢?

好在 macvlan 網絡也是支持 VLAN 子接口的,因此,咱們能夠經過 VLAN 技術將一個網口劃分出多個子網口,這樣就能夠基於子網口來建立 macvlan 網絡了,下面是具體的建立過程。

1 首先分別在兩臺主機上將物理網口 enp0s8 建立出兩個 VLAN 子接口。

# 使用 vconfig 命令在 eth0 配置兩個 VLAN
root@ubuntu:~# vconfig add enp0s8 100
root@ubuntu:~# vconfig add enp0s8 200

# 設置 VLAN 的 REORDER_HDR 參數,默認就好了
root@ubuntu:~# vconfig set_flag enp0s8.100 1 1
root@ubuntu:~# vconfig set_flag enp0s8.200 1 1

# 啓用接口
root@ubuntu:~# ifconfig enp0s8.100 up
root@ubuntu:~# ifconfig enp0s8.200 up

2 分別在 host1 和 host2 上基於兩個 VLAN 子接口建立 2 個 macvlan 網絡,mac10 和 mac20。

root@ubuntu:~# docker network create -d macvlan --subnet=172.16.10.0/24 --gateway=172.16.10.1 -o parent=enp0s8.100 mac10
root@ubuntu:~# docker network create -d macvlan --subnet=172.16.20.0/24 --gateway=172.16.20.1 -o parent=enp0s8.200 mac20

3 分別在 host1 和 host2 上運行容器,並指定不一樣的 macvlan 網絡。

# host1
root@ubuntu:~# docker run -itd --name d1 --ip=172.16.10.10 --network mac10 busybox
root@ubuntu:~# docker run -itd --name d2 --ip=172.16.20.10 --network mac20 busybox

# host2 
root@ubuntu:~# docker run -itd --name d3 --ip=172.16.10.11 --network mac10 busybox
root@ubuntu:~# docker run -itd --name d4 --ip=172.16.20.11 --network mac20 busybox

經過驗證,d1 和 d3,d2 和 d4 在同一 macvlan 網絡下,互相能夠 ping 通,d1 和 d2,d1 和 d4 在不一樣的 macvlan 網絡下,互相 ping 不通。

這個緣由也很明確,不一樣 macvlan 網絡處於不一樣的網絡,並且經過 VLAN 隔離,天然 ping 不了。

但這也只是在二層上通不了,經過三層的路由是能夠通的,咱們這就來驗證下。

從新找一臺主機 host3,經過打開 ip_forward 把它改形成一臺路由器(至於爲何能夠這樣,能夠參考我以前的一篇文章),用來打通兩個 macvlan 網絡,大概的圖示以下所示:

1 首先對 host3 執行 sysctl -w net.ipv4.ip_forward=1 打開路由開關。

2 而後建立兩個 VLAN 子接口,一個做爲 macvlan 網絡 mac10 的網關,一個做爲 mac20 的網關。

[root@localhost ~]# vconfig add enp0s8 100
[root@localhost ~]# vconfig add enp0s8 200
[root@localhost ~]# vconfig set_flag enp0s8.100 1 1
[root@localhost ~]# vconfig set_flag enp0s8.200 1 1

# 對 vlan 子接口配置網關 IP 並啓用
[root@localhost ~]# ifconfig enp0s8.100 172.16.10.1 netmask 255.255.255.0 up
[root@localhost ~]# ifconfig enp0s8.200 172.16.20.1 netmask 255.255.255.0 up

3 這樣以後再從 d1 ping d2 和 d4,就能夠 ping 通了。

root@ubuntu:~# docker exec d1 ping -c 2 172.16.20.10
PING 172.16.20.10 (172.16.20.10): 56 data bytes
64 bytes from 172.16.20.10: seq=0 ttl=63 time=0.661 ms
64 bytes from 172.16.20.10: seq=1 ttl=63 time=0.717 ms

--- 172.16.20.10 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.661/0.689/0.717 ms
root@ubuntu:~# docker exec d1 ping -c 2 172.16.20.11
PING 172.16.20.11 (172.16.20.11): 56 data bytes
64 bytes from 172.16.20.11: seq=0 ttl=63 time=0.548 ms
64 bytes from 172.16.20.11: seq=1 ttl=63 time=0.529 ms

--- 172.16.20.11 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.529/0.538/0.548 ms

PS:可能有些系統作了安全限制,可能 ping 不通,這時候能夠添加如下 iptables 規則,目的是讓系統可以轉發不通 VLAN 的數據包。

iptables -t nat -A POSTROUTING -o enp0s8.100 -j MASQUERADE

iptables -t nat -A POSTROUTING -oenp0s8.200 -j MASQUERADE

iptables -A FORWARD -i enp0s8.100 -o enp0s8.200 -m state --state RELATED,ESTABLISHED -j ACCEPT

iptables -A FORWARD -i enp0s8.200 -o enp0s8.100 -m state --state RELATED,ESTABLISHED -j ACCEPT


iptables -A FORWARD -i enp0s8.100 -o enp0s8.200 -j ACCEPT

iptables -A FORWARD -i enp0s8.200 -o enp0s8.100 -j ACCEPT

爲何配置 VLAN 子接口,配上 IP 就能夠通了,咱們能夠看下路由表就知道了。

首先看容器 d1 的路由:

root@ubuntu:~# docker exec d1 ip route
default via 172.16.10.1 dev eth0 
172.16.10.0/24 dev eth0 scope link  src 172.16.10.10

咱們在建立容器的時候指定了網關 172.16.10.1,因此數據包天然會被路由到 host3 的接口。再來看下 host3 的路由:

[root@localhost ~]# ip route
default via 192.168.108.1 dev enp0s3 proto dhcp metric 100 
172.16.10.0/24 dev enp0s8.100 proto kernel scope link src 172.16.10.1 
172.16.20.0/24 dev enp0s8.200 proto kernel scope link src 172.16.20.1 
192.168.56.0/24 dev enp0s8 proto kernel scope link src 192.168.56.122 metric 101 
192.168.108.0/24 dev enp0s3 proto kernel scope link src 192.168.108.2 metric 100

能夠看到,去往 172.16.10.0/24 網段的數據包會從 enp0s8.100 出去,同理 172.16.20.0/24 網段也是,再加上 host3 的 ip_forward 打開,這就打通了兩個 macvlan 網絡之間的通路。

02 總結

macvlan 是一種網卡虛擬化技術,可以將一張網卡虛擬出多張網卡。

macvlan 的四種通訊模式,經常使用模式是 bridge。

在 Docker 中,macvlan 只支持 bridge 模式。

相同 macvlan 能夠通訊,不一樣 macvlan 二層沒法通訊,能夠藉助三層路由完成通訊。

思考一下:

  1. macvlan bridge 和 bridge 的異同點
  2. 還有一種相似的技術,多張虛擬網卡共享相同 MAC 地址,但有獨立的 IP 地址,這是什麼技術?

後臺回覆「加羣」,帶你進入高手如雲交流羣

個人公衆號 「Linux雲計算網絡」(id: cloud_dev) ,號內有 10T 書籍和視頻資源,後臺回覆 「1024」 便可領取,分享的內容包括但不限於 Linux、網絡、雲計算虛擬化、容器Docker、OpenStack、Kubernetes、工具、SDN、OVS、DPDK、Go、Python、C/C++編程技術等內容,歡迎你們關注。


參考:

https://www.cnblogs.com/Cloud...

https://blog.csdn.net/dog250/...

https://www.hi-linux.com/post...

相關文章
相關標籤/搜索