天天看點

macvlan和pipework基礎概念macvlan簡單macvlan環境配置pipework

基礎概念

首先來回顧一下網絡的基礎概念, 網橋和網關

網橋

網橋(Bridge)是一個區域網路與另一個區域網路之間建立連接配接的橋梁. 是一種二層網絡裝置,

網關

網關實質上是一個網絡通向其他網絡的IP位址。

比如有網絡A和網絡B,網絡A的IP位址範圍為“192.168.1.1~192. 168.1.254”,子網路遮罩為255.255.255.0;網絡B的IP位址範圍為“192.168.2.1~192.168.2.254”,子網路遮罩為255.255.255.0。

在沒有路由器的情況下,兩個網絡之間是不能進行TCP/IP通信的,即使是兩個網絡連接配接在同一台交換機(或集線器)上,TCP/IP協定也會根據子網路遮罩(255.255.255.0)判定兩個網絡中的主機處在不同的網絡裡。

而要實作這兩個網絡之間的通信,則必須通過網關。如果網絡A中的主機發現資料包的目的主機不在本地網絡中,就把資料包轉發給它自己的網關,再由網關轉發給網絡B的網關,網絡B的網關再轉發給網絡B的某個主機

macvlan

macvlan 是linux核心在3.9版本以上提供較新的一種特性,

允許在同一個實體網卡上配置多個 MAC 位址,即多個 interface,每個 interface 可以配置自己的 IP。

macvlan 本質上是一種網卡虛拟化技術,Docker 用 macvlan 實作容器網絡就不奇怪了。

macvlan 的最大優點是性能極好,相比其他實作,macvlan 不需要建立 Linux bridge,而是直接通過以太 interface 連接配接到實體網絡

簡單macvlan環境配置

環境是兩台VM, 172.16.104.145/172.16.104.146

需要在兩台VM上都打開網卡混雜模式和建立docker的macvlan網絡

這種模式下的容器, 和主控端不能互通, 和其他主機以及上面的容器都可以通信

網卡混雜模式設定

[root@centos1 ~]# ip link set ens33 promisc on
[root@centos1 ~]# ifconfig
ens33: flags=4419<UP,BROADCAST,RUNNING,PROMISC,MULTICAST>  mtu 1500
        inet 172.16.104.145  netmask 255.255.255.0  broadcast 172.16.104.255
        inet6 fe80::9abe:3a2e:cbd9:3192  prefixlen 64  scopeid 0x20<link>           

ifconfig

可以看到有

PROMISC

字樣表示混雜模式打開

建立macvlan網絡

docker network create -d macvlan --subnet=172.16.104.0/24 --gateway=172.16.104.1 -o parent=ens33 mynet           
參數說明:

-d macvlan

: 建立macvlan網絡,使用macvlan網絡驅動

--subnet

: 指定主控端所在網段

--gateway

: 指定主控端所在網段網關, 必須是真實存在的網關,否則容器無法路由

-o parent

: 繼承指定網段的網卡

注意:

  • 1、macvlan是一種本地網絡, docker不會為它建立網關,
  • 2、使用者也需要自己管理 IP subnet, 而且不提供DNS服務
  • 3、macvlan是一種獨占網絡, 即一個網卡隻能建立一個 macvlan 網絡, 如果要支援多個macvlan網絡, 必須使用 sub-interface , 具體方法略.

建立容器

兩台VM上分别建立容器(IP為10/11)之後

docker run --net=mynet --ip=172.16.104.10 -itd --name=test1 docker.io/centos bash           
docker run --net=mynet --ip=172.16.104.11 -itd --name=test2 docker.io/centos bash           

進入容器, 能互相ping通

[root@634408c6c399 /]# ping 172.16.104.10
PING 172.16.104.10 (172.16.104.10) 56(84) bytes of data.
64 bytes from 172.16.104.10: icmp_seq=1 ttl=64 time=0.595 ms           

使用macVLAN模式的容器,無法ping通主控端,主控端也無法ping通該容器,對其他同網段的伺服器和容器都可以聯通

# 容器ping主控端IP
[root@634408c6c399 /]# ping 172.16.104.146
PING 172.16.104.146 (172.16.104.146) 56(84) bytes of data.
^C
--- 172.16.104.146 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2001ms           
# 主機ping另外主機的容器
[root@centos2 ~]# ping 172.16.104.10
PING 172.16.104.10 (172.16.104.10) 56(84) bytes of data.
64 bytes from 172.16.104.10: icmp_seq=1 ttl=64 time=0.762 ms

# 容器内ping另外的主機
[root@634408c6c399 /]# ping 172.16.104.145
PING 172.16.104.145 (172.16.104.145) 56(84) bytes of data.
64 bytes from 172.16.104.145: icmp_seq=1 ttl=64 time=0.513 ms           

pipework

pipework是一個400多行的shell程式,封裝Linux上的ip、brctl等指令, 簡化了在複雜場景下對容器連接配接的操作指令,為我們配置複雜的網絡拓撲提供了一個強有力的工具.

使用pipework指令為容器設定固定IP

格式為:

pipework <網卡> <容器> <IP/掩碼>@<網關>

方法一

這種方法直接綁定到網卡上, 和上面方法類似, 容器内ping不同主控端ip, 其他可以

docker run --net=none -itd --name=test1 -h test1 busybox /bin/sh           
pipework ens33 test1 172.16.104.10/[email protected]           
pipework ens33 test2 172.16.104.11/[email protected]           

執行過程大概包括:

檢視主機是否包含ens33,如果不存在就建立,向容器執行個體test1添加一塊網卡,并配置固定IP:172.16.104.10,若test1已經有預設的路由,則删除掉,将@後面的172.16.104.1設定為預設路由的網關,将test1容器執行個體連接配接到建立的ens33上。

[root@centos1 network-scripts]# docker exec test1 ip addr
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
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
18: eth1@if2: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue qlen 1000
    link/ether f6:c5:fe:92:08:c0 brd ff:ff:ff:ff:ff:ff
    inet 172.16.104.10/24 brd 172.16.104.255 scope global eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::f4c5:feff:fe92:8c0/64 scope link
       valid_lft forever preferred_lft forever           

容器可以ping通另外的主機了

[root@centos1 network-scripts]# docker exec test1 ping 172.16.104.147
PING 172.16.104.147 (172.16.104.147): 56 data bytes
64 bytes from 172.16.104.147: seq=0 ttl=64 time=1.343 ms
64 bytes from 172.16.104.147: seq=1 ttl=64 time=0.553 ms           

方法二

該方法效果較好, 容器和主控端互通, 但是配置的時候需要通過VNC或者序列槽連接配接(單網卡), 要斷網

啟動容器, pipework綁定過程和方法一相同, 這裡省略

$ ip addr add 172.16.104.148/24 dev br0
$ ip addr del 172.16.104.148/24 dev ens33
$ brctl addif br0 ens33
$ ip route del default
$ ip route add default via 172.16.104.1 dev br0           

過程中會斷網, 可以寫到一條指令中, 但實測過程中并不好用 (因為可能中間哪條抛錯下面的就執行不了, 實測中第一次執行時候第四條抛錯)

ip addr add 172.16.104.148/24 dev br0;\
ip addr del 172.16.104.148/24 dev ens33;\
brctl addif br0 ens33;\
ip route del default;\
ip route add default via 172.16.104.1 dev br0;\