Docker學習筆記(五)Docker跨主機網絡--macvlan方案

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

一、實驗環境

IP 主機名 內核版本
10.1.1.17 master kernel-5.2.11
10.1.1.13 host1 kernel-5.2.11
10.1.1.14 host2 kernel-5.2.11

二、創建macvlan網絡

在master、node1和node2上同時執行以下命令:

[root@master ~]# docker network create -d macvlan --subnet=172.16.10.0/24 --gateway=172.16.10.1 -o parent=ens33 mac1
476cfc5eb16c51647c02f87ff682452d4a76568b47d770a612996d0e09420e21
[root@master ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
7fd1d76008e3        bridge              bridge              local
af93f80d0ba6        host                host                local
476cfc5eb16c        mac1                macvlan             local
23d2bfb36bf0        none                null                local

node1:

[root@node1 ~]# docker network create -d macvlan --subnet=172.16.10.0/24 --gateway=172.16.10.1 -o parent=ens33 mac1
33e73b4f6637ce7064b4f6198a43125f07557e7bf824ad1ea39a276e910e11eb
[root@node1 ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
9986d9dda86f        bridge              bridge              local
8611ebf969a6        host                host                local
33e73b4f6637        mac1                macvlan             local
556e2a599b82        none                null                local

node2:

[root@node2 ~]# docker network create -d macvlan --subnet=172.16.10.0/24 --gateway=172.16.10.1 -o parent=ens33 mac1
14b860ca6be2458d3f210286be2f6a867177403f41d96985a5fcac60ec93fa78
[root@node2 ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
3891241149c3        bridge              bridge              local
a63bf958be9e        host                host                local
14b860ca6be2        mac1                macvlan             local
fb8797af5710        none                null                local

三、用macvlan網絡創建容器:

master:

[root@master ~]# docker run -itd --name c1 --ip=172.16.10.2 --network mac1 busybox
50f2d1b18bcf4301a13afa08c5eb780f1d37351e3e30617076c5a557e4eda512

node1:

[root@node1 ~]# docker run -itd --name c2 --ip=172.16.10.3 --network mac1 busybox
91ce7ad4a9f628417067a93df8c547199af438a8d0b1b20d616cbdc3742b655a

node2:

[root@node2 ~]# docker run -itd --name c3 --ip=172.16.10.4 --network mac1 busybox
02fa6f6be82c6c680f0e798662e3555bae204dddfa5b722d00b5f71ca80a7163

(4)三個容器的IP分別爲172.16.10.2\3\4,進入容器互相ping對方:
master:

[root@master ~]# docker attach c1
/ # ping -c 1 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=2.546 ms

--- 172.16.10.3 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 2.546/2.546/2.546 ms
/ # ping -c 1 172.16.10.4
PING 172.16.10.4 (172.16.10.4): 56 data bytes
64 bytes from 172.16.10.4: seq=0 ttl=64 time=1.240 ms

--- 172.16.10.4 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 1.240/1.240/1.240 ms

node1:

[root@node1 ~]# docker attach c2
/ # ping -c 1 172.16.10.2
PING 172.16.10.2 (172.16.10.2): 56 data bytes
64 bytes from 172.16.10.2: seq=0 ttl=64 time=0.510 ms

--- 172.16.10.2 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.510/0.510/0.510 ms
/ # ping -c 1 172.16.10.4
PING 172.16.10.4 (172.16.10.4): 56 data bytes
64 bytes from 172.16.10.4: seq=0 ttl=64 time=1.460 ms

--- 172.16.10.4 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 1.460/1.460/1.460 ms

node2:

[root@node2 ~]# docker attach c3
/ # ping -c 1 172.16.10.2
PING 172.16.10.2 (172.16.10.2): 56 data bytes
64 bytes from 172.16.10.2: seq=0 ttl=64 time=1.994 ms

--- 172.16.10.2 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 1.994/1.994/1.994 ms
/ # ping -c 1 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=1.213 ms

--- 172.16.10.3 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 1.213/1.213/1.213 ms

互相之間都是能夠ping通的。

四、網絡結構分析:

macvlan是不依賴Linux bridge的,創建好macvlan網絡之後,通過brctl show可以確認沒有創建新的網橋:

[root@master ~]# brctl show
bridge name	bridge id		STP enabled	interfaces
docker0		8000.024276b03dbc	no		

查看c1容器的網絡:

[root@master ~]# docker exec c1 ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
4: eth0@if2: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:10:0a:02 brd ff:ff:ff:ff:ff:ff

除了lo,容器只有一個eth0,eth0後面有個if2,這說明該接口有個對應的interface,全局編號爲2,而在主機上執行 ip link可以看到,ens33的編號也是2:

[root@master ~]# ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 00:0c:29:c9:32:dd brd ff:ff:ff:ff:ff:ff
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default 
    link/ether 02:42:76:b0:3d:bc brd ff:ff:ff:ff:ff:ff

所以,可以確定的是,容器抄底eth0就是ens33通過macvlan虛擬出來的interface。容器的interface直接與主機的網卡進行連接,這種方案使得容器無需通過NAT和端口映射就能與外網相通,在網絡上與其他獨立主機沒有區別。

五、不同 macvlan 網絡之間的通信

macvlan會獨佔主機的網卡,也就是說每個網卡只能創建一個macvlan網絡,否則會報錯。但主機的網卡是有限的,如何支持更多的macvlan網絡呢?好在macvlan不僅可以連接到interface,如ens33,還可以連接到sub-interface,如ens33.100,ens33.200。
Linux網卡支持VLAN技術,VLAN是現代常用的網絡虛擬化技術,同一個網卡(interface)可以支持多個VLAN的數據包,不過前提是要創建sub-interface。
比如希望ens33網卡支持VLAN10和VLAN20,則需要創建sub-interface ens33.10和ens33.20。在交換機上,如果某個口智能手法單個VLAN的數據,則port爲access模式;若要接受多個VLAN的數據,則爲trunk模式。所以ens33網卡對端要接在交換機的trunk口上。因爲我們是虛擬機,就不需要這樣操作了。下面開始創建基於VLAN的macvlan網絡。

首先兩臺主機上安裝vconfig工具:

[root@master ~]# wget https://mirrors.aliyun.com/centos/6.10/os/x86_64/Packages/vconfig-1.9-8.1.el6.x86_64.rpm
rpm -ivh vconfig-1.9-8.1.el6.x86_64.rpm

加載8021q模塊:

[root@master ~]# modprobe 8021q

開啓ens33網卡的混雜模式:

[root@master ~]# ifconfig ens33 promisc

確認混雜模式已經開啓:

ens33: flags=4419<UP,BROADCAST,RUNNING,PROMISC,MULTICAST>  mtu 1500
        inet 10.1.1.13  netmask 255.255.255.0  broadcast 10.1.1.255
        inet6 fe80::55d8:65e5:d67d:8eaf  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:5c:02:a3  txqueuelen 1000  (Ethernet)
        RX packets 138  bytes 14859 (14.5 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 210  bytes 21630 (21.1 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

啓用IPV4. forwarding:

[root@master ~]# vim /etc/sysctl.conf
net.ipv4.ip_forward=1

然後重啓network。

[root@master ~]# systemctl restart network

現在三臺主機上分別基於ens33網卡創建兩個VLAN:

[root@master ~]# vconfig add ens33 100
[root@master ~]# vconfig add ens33 200

啓用VLAN:

[root@master ~]# ifconfig ens33.100 up
[root@master ~]# ifconfig ens33.200 up

基於兩個子接口分別創建mac10和mac20的macvlan網絡:

[root@master ~]# docker network create -d macvlan --subnet=172.16.10.0/24 --gateway=172.16.10.1 -o parent=ens33.100 mac10
[root@master ~]# docker network create -d macvlan --subnet=172.16.20.0/24 --gateway=172.16.20.1 -o parent=ens33.200 mac20

在node1上創建d1和d2兩個容器,分別基於mac10和mac20:

[root@master ~]# docker run -itd --name d1 --ip=172.16.10.10 --network mac10 busybox
[root@master ~]# docker run -itd --name d2 --ip=172.16.20.10 --network mac20 busybox

在node2上創建d3和d4兩個容器,分別基於mac10和mac20:

[root@master ~]# docker run -itd --name d3 --ip=172.16.10.11 --network mac10 busybox
[root@master ~]# docker run -itd --name d4 --ip=172.16.20.11 --network mac20 busybox

正常來講d1和d3屬於同一個網段,d2和d4屬於同一個網段,應該是能ping通的,目前我的實驗沒通,不知道是不是虛擬機本身不支持這個網絡。正在研究中。

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