IPvlan 网络驱动程序
IPvlan 驱动程序使用户能够完全控制 IPv4 和 IPv6 地址。VLAN 驱动程序在该驱动程序的基础上构建,使用户能够完全控制第 2 层 VLAN 标记,甚至对于有兴趣进行底层网络集成的用户,还可以实现 IPvlan L3 路由。对于抽象化物理约束的覆盖部署,请参阅 多主机覆盖 驱动程序。
IPvlan 是一种经过验证的网络虚拟化技术的全新演绎。Linux 实现非常轻量级,因为它们不是使用传统的 Linux 网桥进行隔离,而是与 Linux 以太网接口或子接口关联,以在网络之间以及与物理网络之间的连接强制执行分离。
IPvlan 提供了许多独特的功能,并且由于各种模式,还有很大的创新空间。这两种方法的两个高级优势是:绕过 Linux 网桥带来的积极性能影响,以及拥有更少移动部件带来的简单性。在 Docker 主机 NIC 和容器接口之间通常存在的网桥被移除后,留下一个简单的设置,该设置由直接连接到 Docker 主机接口的容器接口组成。对于外部面向服务的,这种结果易于访问,因为这些情况下不需要端口映射。
选项
下表描述了使用 ipvlan
驱动程序创建网络时,可以传递给 --option
的驱动程序特定选项。
选项 | 默认值 | 说明 |
---|---|---|
ipvlan_mode | l2 | 设置 IPvlan 操作模式。可以是以下之一:l2 、l3 、l3s |
ipvlan_flag | bridge | 设置 IPvlan 模式标记。可以是以下之一:bridge 、private 、vepa |
parent | 指定要使用的父接口。 |
示例
先决条件
- 本页上的示例均为单主机示例。
- 所有示例都可以在运行 Docker 的单个主机上执行。任何使用子接口(如
eth0.10
)的示例都可以替换为eth0
或 Docker 主机上的任何其他有效父接口。带点 (.
) 的子接口将动态创建。-o parent
接口也可以完全从docker network create
中省略,驱动程序将创建dummy
接口,该接口将启用本地主机连接以执行示例。 - 内核要求
- IPvlan Linux 内核 v4.2+(支持更早的内核,但存在错误)。若要检查您当前的内核版本,请使用
uname -r
- IPvlan Linux 内核 v4.2+(支持更早的内核,但存在错误)。若要检查您当前的内核版本,请使用
IPvlan L2 模式示例用法
下图显示了 IPvlan L2
模式的拓扑结构示例。驱动程序由 -d driver_name
选项指定。在本例中为 -d ipvlan
。


在下一个示例中,父接口 -o parent=eth0
配置如下
$ ip addr show eth0
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
inet 192.168.1.250/24 brd 192.168.1.255 scope global eth0
使用主机的接口的网络作为 docker network create
中的 --subnet
。容器将连接到与通过 -o parent=
选项设置的主机接口相同的网络。
创建 IPvlan 网络并运行一个连接到该网络的容器
# IPvlan (-o ipvlan_mode= Defaults to L2 mode if not specified)
$ docker network create -d ipvlan \
--subnet=192.168.1.0/24 \
--gateway=192.168.1.1 \
-o ipvlan_mode=l2 \
-o parent=eth0 db_net
# Start a container on the db_net network
$ docker run --net=db_net -it --rm alpine /bin/sh
# NOTE: the containers can NOT ping the underlying host interfaces as
# they are intentionally filtered by Linux for additional isolation.
IPvlan 的默认模式为 l2
。如果未指定 -o ipvlan_mode=
,则将使用默认模式。同样,如果 --gateway
为空,则网络上的第一个可用地址将被设置为网关。例如,如果网络创建中提供的子网为 --subnet=192.168.1.0/24
,则容器接收的网关为 192.168.1.1
。
为了帮助理解这种模式如何与其他主机交互,下图显示了两个 Docker 主机之间的同一个第 2 层段,该段适用于 IPvlan L2 模式。


以下将创建与之前创建的网络 db_net
完全相同的网络,该网络使用驱动程序默认值 --gateway=192.168.1.1
和 -o ipvlan_mode=l2
。
# IPvlan (-o ipvlan_mode= Defaults to L2 mode if not specified)
$ docker network create -d ipvlan \
--subnet=192.168.1.0/24 \
-o parent=eth0 db_net_ipv
# Start a container with an explicit name in daemon mode
$ docker run --net=db_net_ipv --name=ipv1 -itd alpine /bin/sh
# Start a second container and ping using the container name
# to see the docker included name resolution functionality
$ docker run --net=db_net_ipv --name=ipv2 -it --rm alpine /bin/sh
$ ping -c 4 ipv1
# NOTE: the containers can NOT ping the underlying host interfaces as
# they are intentionally filtered by Linux for additional isolation.
驱动程序还支持 --internal
标记,该标记将完全隔离网络上的容器,使其无法与该网络外部的任何通信进行通信。由于网络隔离与网络的父接口紧密耦合,因此在 docker network create
中省略 -o parent=
选项的结果与 --internal
选项完全相同。如果未指定父接口或使用了 --internal
标记,则会为用户创建一个 netlink 类型 dummy
父接口,并用作父接口,从而有效地完全隔离网络。
以下两个 docker network create
示例会生成相同的网络,您可以将容器连接到这些网络
# Empty '-o parent=' creates an isolated network
$ docker network create -d ipvlan \
--subnet=192.168.10.0/24 isolated1
# Explicit '--internal' flag is the same:
$ docker network create -d ipvlan \
--subnet=192.168.11.0/24 --internal isolated2
# Even the '--subnet=' can be left empty and the default
# IPAM subnet of 172.18.0.0/16 will be assigned
$ docker network create -d ipvlan isolated3
$ docker run --net=isolated1 --name=cid1 -it --rm alpine /bin/sh
$ docker run --net=isolated2 --name=cid2 -it --rm alpine /bin/sh
$ docker run --net=isolated3 --name=cid3 -it --rm alpine /bin/sh
# To attach to any use `docker exec` and start a shell
$ docker exec -it cid1 /bin/sh
$ docker exec -it cid2 /bin/sh
$ docker exec -it cid3 /bin/sh
IPvlan 802.1Q 中继 L2 模式示例用法
在架构上,IPvlan L2 模式中继与 Macvlan 在网关和第 2 层路径隔离方面相同。有一些细微差别对 ToR 交换机的 CAM 表压力有利,例如每个端口一个 MAC 和主机父 NIC 上的 MAC 耗尽。802.1Q 中继场景看起来相同。这两种模式都符合标记标准,并与物理网络无缝集成,以实现底层集成和硬件供应商插件集成。
位于同一个 VLAN 上的主机通常位于同一个子网,并且几乎总是根据其安全策略进行分组。在大多数情况下,多层应用程序被分层到不同的子网,因为每个进程的安全配置文件都需要某种形式的隔离。例如,将信用卡处理与前端 Web 服务器托管在同一个虚拟网络上将构成法规遵从问题,并且会绕过长期的最佳实践,即深度防御分层架构。VLAN 或使用覆盖驱动程序时的等效 VNI(虚拟网络标识符)是隔离租户流量的第一步。


标记并隔离的 Linux 子接口可以使用户在调用 docker network create
时已经存在或将被创建。docker network rm
将删除子接口。eth0
等父接口不会被删除,只有 netlink 父索引 > 0 的子接口会被删除。
为了使驱动程序能够添加/删除 VLAN 子接口,格式需要为 interface_name.vlan_tag
。可以使用其他子接口命名作为指定的父级,但链接不会在调用 docker network rm
时自动删除。
能够使用现有的父 VLAN 子接口或让 Docker 管理这些子接口,使用户能够完全管理 Linux 接口和网络,或者让 Docker 创建和删除 VLAN 父子接口(netlink ip link
),而无需用户进行任何操作。
例如:使用 eth0.10
来表示标记为 VLAN ID 10
的 eth0
的子接口。等效的 ip link
命令为 ip link add link eth0 name eth0.10 type vlan id 10
。
本示例创建 VLAN 标记网络,然后启动两个容器以测试容器之间的连接。不同的 VLAN 无法互相 ping 通,除非有一个路由器在两个网络之间进行路由。根据 IPvlan 的设计,默认命名空间不可达,以便将容器命名空间与底层主机隔离。
VLAN ID 20
在第一个由 Docker 主机标记和隔离的网络中,eth0.20
是标记为 VLAN ID 20
的父接口,并使用 -o parent=eth0.20
指定。可以使用其他命名格式,但需要使用 ip link
或 Linux 配置文件手动添加和删除链接。只要存在 -o parent
,只要它符合 Linux netlink,就可以使用任何内容。
# now add networks and hosts as you would normally by attaching to the master (sub)interface that is tagged
$ docker network create -d ipvlan \
--subnet=192.168.20.0/24 \
--gateway=192.168.20.1 \
-o parent=eth0.20 ipvlan20
# in two separate terminals, start a Docker container and the containers can now ping one another.
$ docker run --net=ipvlan20 -it --name ivlan_test1 --rm alpine /bin/sh
$ docker run --net=ipvlan20 -it --name ivlan_test2 --rm alpine /bin/sh
VLAN ID 30
在第二个由 Docker 主机标记和隔离的网络中,eth0.30
是标记为 VLAN ID 30
的父接口,并使用 -o parent=eth0.30
指定。ipvlan_mode=
默认设置为 l2 模式 ipvlan_mode=l2
。它也可以显式设置,结果与下一个示例中显示的结果相同。
# now add networks and hosts as you would normally by attaching to the master (sub)interface that is tagged.
$ docker network create -d ipvlan \
--subnet=192.168.30.0/24 \
--gateway=192.168.30.1 \
-o parent=eth0.30 \
-o ipvlan_mode=l2 ipvlan30
# in two separate terminals, start a Docker container and the containers can now ping one another.
$ docker run --net=ipvlan30 -it --name ivlan_test3 --rm alpine /bin/sh
$ docker run --net=ipvlan30 -it --name ivlan_test4 --rm alpine /bin/sh
网关在容器内部设置,作为默认网关。该网关通常是网络上的外部路由器。
$$ ip route
default via 192.168.30.1 dev eth0
192.168.30.0/24 dev eth0 src 192.168.30.2
示例:多子网 IPvlan L2 模式,在同一个子网启动两个容器并互相 ping 通。为了使 192.168.114.0/24
能够到达 192.168.116.0/24
,它需要 L2 模式下的外部路由器。L3 模式可以路由在共享同一个 -o parent=
的子网之间。
网络路由器上的辅助地址很常见,当地址空间耗尽时,可以在 L3 VLAN 接口上添加另一个辅助地址,或者通常称为“交换虚拟接口”(SVI)。
$ docker network create -d ipvlan \
--subnet=192.168.114.0/24 --subnet=192.168.116.0/24 \
--gateway=192.168.114.254 --gateway=192.168.116.254 \
-o parent=eth0.114 \
-o ipvlan_mode=l2 ipvlan114
$ docker run --net=ipvlan114 --ip=192.168.114.10 -it --rm alpine /bin/sh
$ docker run --net=ipvlan114 --ip=192.168.114.11 -it --rm alpine /bin/sh
一个关键的要点是,运营商能够将他们的物理网络映射到他们的虚拟网络,从而将容器集成到他们的环境中,而无需任何操作上的改造。NetOps 将一个 802.1Q trunk 放入 Docker 主机。该虚拟链接将是网络创建时传递的 -o parent=
。对于未标记(非 VLAN)链接,它与 -o parent=eth0
一样简单,或者对于带有 VLAN ID 的 802.1Q trunk,每个网络都映射到网络中相应的 VLAN/子网。
例如,NetOps 提供 VLAN ID 和与之关联的子网,这些子网是在以太网链接上传递到 Docker 主机服务器上的 VLAN。在配置 Docker 网络时,这些值将被插入 docker network create
命令中。这些是持久配置,每次 Docker 引擎启动时都会应用,从而避免了管理通常很复杂的配置文件的麻烦。网络接口也可以通过预先创建进行手动管理,Docker 网络不会修改它们,并使用它们作为父接口。从 NetOps 到 Docker 网络命令的示例映射如下所示
- VLAN: 10,子网:172.16.80.0/24,网关:172.16.80.1
--subnet=172.16.80.0/24 --gateway=172.16.80.1 -o parent=eth0.10
- VLAN: 20,IP 子网:172.16.50.0/22,网关:172.16.50.1
--subnet=172.16.50.0/22 --gateway=172.16.50.1 -o parent=eth0.20
- VLAN: 30,子网:10.1.100.0/16,网关:10.1.100.1
--subnet=10.1.100.0/16 --gateway=10.1.100.1 -o parent=eth0.30
IPvlan L3 模式示例
IPvlan 将需要将路由分发到每个端点。该驱动程序只构建 IPvlan L3 模式端口并将容器附加到接口。整个集群的路由分发超出了此单主机范围驱动的初始实现。在 L3 模式下,Docker 主机非常类似于在容器中启动新网络的路由器。它们位于上游网络在没有路由分发的情况下不会知道的网络上。对于那些好奇 IPvlan L3 将如何融入容器网络的人来说,请看以下示例。


IPvlan L3 模式会丢弃所有广播和组播流量。仅此原因就使 IPvlan L3 模式成为那些寻求大规模和可预测网络集成的首选。它具有可预测性,反过来将导致更高的正常运行时间,因为没有涉及桥接。桥接循环导致了高知名度的中断,这些中断很难定位,具体取决于故障域的大小。这是由于 BPDUs(桥接端口数据单元)的级联性质,它们会泛洪整个广播域(VLAN)以查找并阻止拓扑循环。消除桥接域,或者至少将它们隔离到一对 ToR(机架顶端交换机)将减少难以解决的桥接不稳定性。IPvlan L2 模式非常适合隔离的 VLAN,这些 VLAN 仅被 trunk 化到一对 ToR 中,这些 ToR 可以提供无环路非阻塞结构。下一步是通过 IPvlan L3 模式在边缘进行路由,这将使故障域减少到仅本地主机。
- L3 模式需要与默认命名空间位于不同的子网,因为它需要在默认命名空间中指向 IPvlan 父接口的 netlink 路由。
- 本示例中使用的父接口是
eth0
,它位于子网192.168.1.0/24
上。请注意,docker network
不在与eth0
相同的子网上。 - 与 IPvlan l2 模式不同,只要它们共享相同的父接口
-o parent=
,不同的子网/网络就可以相互 ping 通。
$$ ip a show eth0
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:50:56:39:45:2e brd ff:ff:ff:ff:ff:ff
inet 192.168.1.250/24 brd 192.168.1.255 scope global eth0
- 传统网关对 L3 模式 IPvlan 接口没有太大意义,因为不允许广播流量。因此,容器默认网关指向容器的
eth0
设备。有关详细信息,请参阅以下 L3 容器内部的ip route
或ip -6 route
的 CLI 输出。
模式 -o ipvlan_mode=l3
必须显式指定,因为默认的 IPvlan 模式是 l2
。
以下示例没有指定父接口。网络驱动程序将为用户创建一个虚拟类型的链接,而不是拒绝网络创建并将容器隔离,使其只能相互通信。
# Create the IPvlan L3 network
$ docker network create -d ipvlan \
--subnet=192.168.214.0/24 \
--subnet=10.1.214.0/24 \
-o ipvlan_mode=l3 ipnet210
# Test 192.168.214.0/24 connectivity
$ docker run --net=ipnet210 --ip=192.168.214.10 -itd alpine /bin/sh
$ docker run --net=ipnet210 --ip=10.1.214.10 -itd alpine /bin/sh
# Test L3 connectivity from 10.1.214.0/24 to 192.168.214.0/24
$ docker run --net=ipnet210 --ip=192.168.214.9 -it --rm alpine ping -c 2 10.1.214.10
# Test L3 connectivity from 192.168.214.0/24 to 10.1.214.0/24
$ docker run --net=ipnet210 --ip=10.1.214.9 -it --rm alpine ping -c 2 192.168.214.10
注意
请注意,网络创建中没有
--gateway=
选项。如果指定了l3
模式,则会忽略该字段。查看容器内部的容器路由表# Inside an L3 mode container $$ ip route default dev eth0 192.168.214.0/24 dev eth0 src 192.168.214.10
为了从远程 Docker 主机 ping 容器或容器能够 ping 远程主机,远程主机或之间的物理网络需要有一条指向容器的 Docker 主机 eth 接口的主机 IP 地址的路由。
双栈 IPv4 IPv6 IPvlan L2 模式
Libnetwork 不仅使您能够完全控制 IPv4 地址,而且还使您能够完全控制 IPv6 地址,以及这两个地址族之间的功能对等性。
下一个示例将从 IPv6 开始。在同一个 VLAN
139
上启动两个容器,并相互 ping 通。由于没有指定 IPv4 子网,因此默认 IPAM 将提供一个默认的 IPv4 子网。该子网是隔离的,除非上游网络在 VLAN139
上明确路由它。
# Create a v6 network
$ docker network create -d ipvlan \
--ipv6 --subnet=2001:db8:abc2::/64 --gateway=2001:db8:abc2::22 \
-o parent=eth0.139 v6ipvlan139
# Start a container on the network
$ docker run --net=v6ipvlan139 -it --rm alpine /bin/sh
查看容器 eth0 接口和 v6 路由表
# Inside the IPv6 container
$$ ip a show eth0
75: eth0@if55: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default
link/ether 00:50:56:2b:29:40 brd ff:ff:ff:ff:ff:ff
inet 172.18.0.2/16 scope global eth0
valid_lft forever preferred_lft forever
inet6 2001:db8:abc4::250:56ff:fe2b:2940/64 scope link
valid_lft forever preferred_lft forever
inet6 2001:db8:abc2::1/64 scope link nodad
valid_lft forever preferred_lft forever
$$ ip -6 route
2001:db8:abc4::/64 dev eth0 proto kernel metric 256
2001:db8:abc2::/64 dev eth0 proto kernel metric 256
default via 2001:db8:abc2::22 dev eth0 metric 1024
启动第二个容器并 ping 第一个容器的 v6 地址。
# Test L2 connectivity over IPv6
$ docker run --net=v6ipvlan139 -it --rm alpine /bin/sh
# Inside the second IPv6 container
$$ ip a show eth0
75: eth0@if55: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default
link/ether 00:50:56:2b:29:40 brd ff:ff:ff:ff:ff:ff
inet 172.18.0.3/16 scope global eth0
valid_lft forever preferred_lft forever
inet6 2001:db8:abc4::250:56ff:fe2b:2940/64 scope link tentative dadfailed
valid_lft forever preferred_lft forever
inet6 2001:db8:abc2::2/64 scope link nodad
valid_lft forever preferred_lft forever
$$ ping6 2001:db8:abc2::1
PING 2001:db8:abc2::1 (2001:db8:abc2::1): 56 data bytes
64 bytes from 2001:db8:abc2::1%eth0: icmp_seq=0 ttl=64 time=0.044 ms
64 bytes from 2001:db8:abc2::1%eth0: icmp_seq=1 ttl=64 time=0.058 ms
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.044/0.051/0.058/0.000 ms
下一个示例将使用 VLAN ID 为 140
的双栈 IPv4/IPv6 网络进行设置。
接下来,创建一个具有两个 IPv4 子网和一个 IPv6 子网的网络,所有这些子网都有明确的网关
$ docker network create -d ipvlan \
--subnet=192.168.140.0/24 --subnet=192.168.142.0/24 \
--gateway=192.168.140.1 --gateway=192.168.142.1 \
--subnet=2001:db8:abc9::/64 --gateway=2001:db8:abc9::22 \
-o parent=eth0.140 \
-o ipvlan_mode=l2 ipvlan140
启动一个容器并查看 eth0 以及 v4 和 v6 路由表
$ docker run --net=ipvlan140 --ip6=2001:db8:abc2::51 -it --rm alpine /bin/sh
$ ip a show eth0
78: eth0@if77: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default
link/ether 00:50:56:2b:29:40 brd ff:ff:ff:ff:ff:ff
inet 192.168.140.2/24 scope global eth0
valid_lft forever preferred_lft forever
inet6 2001:db8:abc4::250:56ff:fe2b:2940/64 scope link
valid_lft forever preferred_lft forever
inet6 2001:db8:abc9::1/64 scope link nodad
valid_lft forever preferred_lft forever
$$ ip route
default via 192.168.140.1 dev eth0
192.168.140.0/24 dev eth0 proto kernel scope link src 192.168.140.2
$$ ip -6 route
2001:db8:abc4::/64 dev eth0 proto kernel metric 256
2001:db8:abc9::/64 dev eth0 proto kernel metric 256
default via 2001:db8:abc9::22 dev eth0 metric 1024
启动第二个容器,并使用特定的 --ip4
地址使用 IPv4 数据包 ping 第一个主机
$ docker run --net=ipvlan140 --ip=192.168.140.10 -it --rm alpine /bin/sh
注意
在 IPvlan
L2
模式下,同一个父接口上的不同子网无法相互 ping 通。这需要一个路由器来使用辅助子网代理 ARP 请求。但是,只要它们共享相同的-o parent
父链接,IPvlanL3
将在不同的子网之间路由单播流量。
双栈 IPv4 IPv6 IPvlan L3 模式
示例:IPvlan L3 模式双栈 IPv4/IPv6,多子网,带 802.1Q VLAN 标签:118
与所有示例一样,不必使用标记的 VLAN 接口。子接口可以用 eth0
、eth1
、bond0
或主机上的任何其他有效接口(除 lo
环回接口)交换。
您将看到的主要区别是,L3 模式不会创建具有下一跳的默认路由,而是设置一个指向 dev eth
的默认路由,因为根据设计,ARP/广播/组播都被 Linux 过滤。由于父接口本质上充当路由器,因此父接口的 IP 和子网需要与容器网络不同。这与桥接和 L2 模式相反,桥接和 L2 模式需要位于同一个子网(广播域)上才能转发广播和组播数据包。
# Create an IPv6+IPv4 Dual Stack IPvlan L3 network
# Gateways for both v4 and v6 are set to a dev e.g. 'default dev eth0'
$ docker network create -d ipvlan \
--subnet=192.168.110.0/24 \
--subnet=192.168.112.0/24 \
--subnet=2001:db8:abc6::/64 \
-o parent=eth0 \
-o ipvlan_mode=l3 ipnet110
# Start a few of containers on the network (ipnet110)
# in separate terminals and check connectivity
$ docker run --net=ipnet110 -it --rm alpine /bin/sh
# Start a second container specifying the v6 address
$ docker run --net=ipnet110 --ip6=2001:db8:abc6::10 -it --rm alpine /bin/sh
# Start a third specifying the IPv4 address
$ docker run --net=ipnet110 --ip=192.168.112.30 -it --rm alpine /bin/sh
# Start a 4th specifying both the IPv4 and IPv6 addresses
$ docker run --net=ipnet110 --ip6=2001:db8:abc6::50 --ip=192.168.112.50 -it --rm alpine /bin/sh
接口和路由表输出如下所示
$$ ip a show eth0
63: eth0@if59: <BROADCAST,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default
link/ether 00:50:56:2b:29:40 brd ff:ff:ff:ff:ff:ff
inet 192.168.112.2/24 scope global eth0
valid_lft forever preferred_lft forever
inet6 2001:db8:abc4::250:56ff:fe2b:2940/64 scope link
valid_lft forever preferred_lft forever
inet6 2001:db8:abc6::10/64 scope link nodad
valid_lft forever preferred_lft forever
# Note the default route is the eth device because ARPs are filtered.
$$ ip route
default dev eth0 scope link
192.168.112.0/24 dev eth0 proto kernel scope link src 192.168.112.2
$$ ip -6 route
2001:db8:abc4::/64 dev eth0 proto kernel metric 256
2001:db8:abc6::/64 dev eth0 proto kernel metric 256
default dev eth0 metric 1024
注意
当您使用指定的 v6 地址删除一个容器,然后启动一个具有相同 v6 地址的新容器时,在指定
--ip6=
地址时,可能存在一个错误,它会抛出以下错误,就像地址没有正确地释放到 v6 池中一样。它将无法卸载容器,并处于死机状态。
docker: Error response from daemon: Address already in use.
手动创建 802.1Q 链接
VLAN ID 40
如果用户不希望驱动程序创建 VLAN 子接口,则需要在运行 docker network create
之前存在。如果您有子接口命名不是 interface.vlan_id
,则它在 -o parent=
选项中再次得到认可,只要接口存在并且处于启动状态。
手动创建的链接可以命名为任何名称,只要它们在创建网络时存在即可。无论名称如何,在使用 docker network rm
删除网络时,手动创建的链接都不会被删除。
# create a new sub-interface tied to dot1q vlan 40
$ ip link add link eth0 name eth0.40 type vlan id 40
# enable the new sub-interface
$ ip link set eth0.40 up
# now add networks and hosts as you would normally by attaching to the master (sub)interface that is tagged
$ docker network create -d ipvlan \
--subnet=192.168.40.0/24 \
--gateway=192.168.40.1 \
-o parent=eth0.40 ipvlan40
# in two separate terminals, start a Docker container and the containers can now ping one another.
$ docker run --net=ipvlan40 -it --name ivlan_test5 --rm alpine /bin/sh
$ docker run --net=ipvlan40 -it --name ivlan_test6 --rm alpine /bin/sh
示例:使用任何名称手动创建的 VLAN 子接口
# create a new sub interface tied to dot1q vlan 40
$ ip link add link eth0 name foo type vlan id 40
# enable the new sub-interface
$ ip link set foo up
# now add networks and hosts as you would normally by attaching to the master (sub)interface that is tagged
$ docker network create -d ipvlan \
--subnet=192.168.40.0/24 --gateway=192.168.40.1 \
-o parent=foo ipvlan40
# in two separate terminals, start a Docker container and the containers can now ping one another.
$ docker run --net=ipvlan40 -it --name ivlan_test5 --rm alpine /bin/sh
$ docker run --net=ipvlan40 -it --name ivlan_test6 --rm alpine /bin/sh
手动创建的链接可以使用以下命令清理
$ ip link del foo
与所有 Libnetwork 驱动程序一样,它们可以混合搭配使用,甚至可以并行运行第三方生态系统驱动程序,以便为 Docker 用户提供最大的灵活性。