1. 使用 macvlan 网络
有些应用程序,特别是监视网络流量的遗留应用程序或应用程序,希望直接连接到物理网络。 在这种情况下,你可以使用 macvlan 网络驱动程序为每个容器的虚拟网络接口分配一个 MAC 地址,使其看起来像一个直接连接到物理网络的物理网络接口。 在这种情况下,您需要在 Docker 主机上指定一个用于 macvlan 的物理接口,以及 macvlan 的子网和网关。 您甚至可以使用不同的物理网络接口来隔离您的 macvlan 网络。 记住以下几点:
由于 IP 地址耗尽或“ VLAN 扩散” ,很容易无意中损坏您的网络,这种情况下,您的网络中有大量不适当的唯一 MAC 地址。
你的网络设备需要能够处理“混杂模式” ,其中一个物理接口可以分配多个 MAC 地址。
如果您的应用程序可以使用网桥(在单个 Docker 主机上)或覆盖(跨多个 Docker 主机通信) ,那么从长远来看,这些解决方案可能更好。
1.1 创建一个 macvlan 网络
当您创建 macvlan 网络时,它可以是桥接模式或802.1 q vlan 桥接模式。
在桥接模式下,macvlan 流量通过主机上的一个物理设备。
在802.1 q vlan 桥模式下,流量通过 Docker 动态创建的802.1 q 子接口。 这允许您在更细粒度的级别上控制路由和过滤。
1.2 桥接模式
要创建一个连接给定物理网络接口的 macvlan 网络,可以使用 --driver macvlan
和 docker network create
命令。 您还需要指定父接口,它是流量将在 Docker 主机上物理地经过的接口。
$ docker network create -d macvlan \
--subnet=172.16.86.0/24 \
--gateway=172.16.86.1 \
-o parent=eth0 pub_net
如果你需要排除在 macvlan 网络中使用的 IP 地址,比如当一个给定的 IP 地址已经在使用时,使用 – aux-addresses:
$ docker network create -d macvlan \
--subnet=192.168.32.0/24 \
--ip-range=192.168.32.128/25 \
--gateway=192.168.32.254 \
--aux-address="my-router=192.168.32.129" \
-o parent=eth0 macnet32
1.3 集束桥接模式(vlan)
如果您指定父接口名称并包含一个点,例如 eth0.50,Docker 将其解释为 eth0的子接口,并自动创建子接口。
$ docker network create -d macvlan \
--subnet=192.168.50.0/24 \
--gateway=192.168.50.1 \
-o parent=eth0.50 macvlan50
1.4 使用 ipvlan 而不是 macvlan
在上面的示例中,您仍然在使用 L3桥。 你可以使用 ipvlan 代替,并得到一个 L2桥。 指定 -o ipvlan 模式 l2。
$ docker network create -d ipvlan \
--subnet=192.168.210.0/24 \
--subnet=192.168.212.0/24 \
--gateway=192.168.210.254 \
--gateway=192.168.212.254 \
-o ipvlan_mode=l2 ipvlan210
1.5 使用 IPv6
如果已经将 Docker 守护进程配置为允许 IPv6,则可以使用双栈 ipv4 / IPv6 macvlan 网络。
$ docker network create -d macvlan \
--subnet=192.168.216.0/24 --subnet=192.168.218.0/24 \
--gateway=192.168.216.1 --gateway=192.168.218.1 \
--subnet=2001:db8:abc8::/64 --gateway=2001:db8:abc8::10 \
-o parent=eth0.218 \
-o macvlan_mode=bridge macvlan216
2. 实践练习 macvlan 网络
该实践处理网络独立的容器连接到 macvlan 网络。 在这种类型的网络中,Docker 主机在其 IP 地址接受对多个 MAC 地址的请求,并将这些请求路由到适当的容器。
2.1 目标
目标是建立一个桥接 macvlan 网络和附加一个容器到它,然后建立一个802.1 q 集束聚合 macvlan 网络和附加一个容器到它。
2.2 先决条件
大多数云提供商都会屏蔽 macvlan 网络,您可能需要对网络设备进行物理访问。
Macvlan 网络驱动程序只能在 Linux 主机上使用,而且不支持 Docker Desktop for Mac,Docker Desktop for Windows,或 Docker EE for Windows Server。
您至少需要3.9版本的 Linux 内核,并且推荐4.0或更高版本。
这些例子假设您的以太网接口是 eth0。如果您的设备有一个不同的名称,请使用相应的名称。
2.3 桥接模式
在简单的桥接示例中,流量通过 eth0和 Docker 使用容器的 MAC 地址将流量路由到容器。 对于网络上的网络设备,容器看起来是物理连接到网络的。
创建一个称为 my-macvlan-net 的 macvlan 网络。 将子网、网关和父值修改为在环境中有意义的值。
$ docker network create -d macvlan \ --subnet=172.16.86.0/24 \ --gateway=172.16.86.1 \ -o parent=eth0 \ my-macvlan-net
您可以使用 docker 网络 ls 和 docker 网络检查 my-macvlan-net 命令,以验证网络存在并且是 macvlan 网络。
启动一个
alpine
容器并将其连接到my-macvlan-net
网络。-dit
标志在后台启动容器,但允许您附加到它。-rm
标志意味着容器在停止时被移除。$ docker run --rm -itd \ --network my-macvlan-net \ --name my-macvlan-alpine \ alpine:latest \ ash
检查
my-macvlan-alpine
容器,注意网络键中的MacAddress
键:$ docker container inspect my-macvlan-alpine ...truncated... "Networks": { "my-macvlan-net": { "IPAMConfig": null, "Links": null, "Aliases": [ "bec64291cd4c" ], "NetworkID": "5e3ec79625d388dbcc03dcf4a6dc4548644eb99d58864cf8eee2252dcfc0cc9f", "EndpointID": "8caf93c862b22f379b60515975acf96f7b54b7cf0ba0fb4a33cf18ae9e5c1d89", "Gateway": "172.16.86.1", "IPAddress": "172.16.86.2", "IPPrefixLen": 24, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "02:42:ac:10:56:02", "DriverOpts": null } } ...truncated
通过运行两个 docker exec 命令,查看容器如何看待自己的网络接口。
$ docker exec my-macvlan-alpine ip addr show eth0 9: eth0@tunl0: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP link/ether 02:42:ac:10:56:02 brd ff:ff:ff:ff:ff:ff inet 172.16.86.2/24 brd 172.16.86.255 scope global eth0 valid_lft forever preferred_lft forever
$ docker exec my-macvlan-alpine ip route default via 172.16.86.1 dev eth0 172.16.86.0/24 dev eth0 scope link src 172.16.86.2
停止容器(因为
--rm
标志,Docker 删除了它) ,并删除网络。$ docker container stop my-macvlan-alpine $ docker network rm my-macvlan-net
2.4 集束桥接(vlan)
在802.1 q 集束桥接的示例中,流量通过 eth0(称为 eth0.10)的子接口流动,而 Docker 使用容器的 MAC 地址将流量路由到容器。 对于网络上的网络设备,容器看起来是物理连接到网络的。
创建一个名为 my-8021q-macvlan-net 的 macvlan 网络。 将子网、网关和父值修改为在环境中有意义的值。
$ docker network create -d macvlan \ --subnet=172.16.86.0/24 \ --gateway=172.16.86.1 \ -o parent=eth0.10 \ my-8021q-macvlan-net
您可以使用
docker network ls
和docker network inspection my-8021q-macvlan-net
命令来验证网络是否存在,是否是macvlan
网络,以及是否具有父eth0.10
。 您可以在 Docker 主机上使用ip addr show
来验证接口eth0.10
是否存在并具有单独的 IP 地址启动一个
alpine
容器并将其连接到my-8021q-macvlan-net
网络。-dit
标志在后台启动容器,但允许您附加到它。-rm
标志意味着容器在停止时被移除。$ docker run --rm -itd \ --network my-8021q-macvlan-net \ --name my-second-macvlan-alpine \ alpine:latest \ ash
检查
my-second-macvlan-alpine
容器,注意网络键中的MacAddress
键:$ docker container inspect my-second-macvlan-alpine ...truncated... "Networks": { "my-8021q-macvlan-net": { "IPAMConfig": null, "Links": null, "Aliases": [ "12f5c3c9ba5c" ], "NetworkID": "c6203997842e654dd5086abb1133b7e6df627784fec063afcbee5893b2bb64db", "EndpointID": "aa08d9aa2353c68e8d2ae0bf0e11ed426ea31ed0dd71c868d22ed0dcf9fc8ae6", "Gateway": "172.16.86.1", "IPAddress": "172.16.86.2", "IPPrefixLen": 24, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "02:42:ac:10:56:02", "DriverOpts": null } } ...truncated
通过运行两个 docker exec 命令,查看容器如何看待自己的网络接口。
$ docker exec my-second-macvlan-alpine ip addr show eth0 11: eth0@if10: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP link/ether 02:42:ac:10:56:02 brd ff:ff:ff:ff:ff:ff inet 172.16.86.2/24 brd 172.16.86.255 scope global eth0 valid_lft forever preferred_lft forever
$ docker exec my-second-macvlan-alpine ip route default via 172.16.86.1 dev eth0 172.16.86.0/24 dev eth0 scope link src 172.16.86.2
停止容器(因为 – rm 标志,Docker 删除了它) ,并删除网络。
$ docker container stop my-second-macvlan-alpine $ docker network rm my-8021q-macvlan-net