IPvlan 网络驱动程序

IPvlan 驱动程序让用户能够完全控制 IPv4 和 IPv6 寻址。VLAN 驱动程序在此基础上构建,让操作员可以完全控制第 2 层 VLAN 标记,甚至为对底层网络集成感兴趣的用户提供 IPvlan L3 路由。对于抽象掉物理约束的覆盖部署,请参阅 多主机覆盖 驱动程序。

IPvlan 是对久经考验的网络虚拟化技术的一种新尝试。Linux 实现非常轻量级,因为它们不使用传统的 Linux 网桥进行隔离,而是与 Linux 以太网接口或子接口关联,以强制网络之间的分离以及与物理网络的连接。

IPvlan 提供了许多独特的功能,并为各种模式的进一步创新留下了充足的空间。这些方法的两大优势是,绕过 Linux 网桥带来的积极性能影响以及活动部件更少带来的简单性。移除传统上位于 Docker 主机 NIC 和容器接口之间的网桥,留下了一个简单的设置,即容器接口直接附加到 Docker 主机接口。这种结果使面向外部的服务易于访问,因为在这些情况下不需要端口映射。

选项

下表描述了在使用 ipvlan 驱动创建网络时可以传递给 --opt 的驱动特定选项。

选项默认值描述
ipvlan_model2设置 IPvlan 操作模式。可以是以下之一:l2l3l3s
ipvlan_flagbridge设置 IPvlan 模式标志。可以是以下之一:bridgeprivatevepa
parent指定要使用的父接口。

示例

先决条件

  • 本页上的示例都是单主机的。
  • 所有示例都可以在运行 Docker 的单台主机上执行。任何使用子接口(如 eth0.10)的示例都可以替换为 eth0 或 Docker 主机上的任何其他有效父接口。带 . 的子接口是即时创建的。-o parent 接口也可以在 docker network create 中完全省略,驱动程序将创建一个 dummy 接口,该接口将启用本地主机连接以执行示例。
  • 内核要求
    • IPvlan Linux 内核 v4.2+(对早期内核的支持存在,但有 bug)。要检查您当前的内核版本,请使用 uname -r

IPvlan L2 模式用法示例

IPvlan L2 模式拓扑的一个示例如下图所示。驱动程序使用 -d driver_name 选项指定。在本例中为 -d ipvlan

Simple IPvlan L2 Mode Example

下一个示例中的父接口 -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 模式。

Multiple IPvlan hosts

以下命令将创建与之前创建的 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 trunk L2 模式用法示例

从架构上讲,IPvlan L2 模式中继在网关和 L2 路径隔离方面与 Macvlan 相同。存在一些细微差别,可能对 ToR 交换机中的 CAM 表压力、每个端口一个 MAC 地址以及主机父 NIC 上的 MAC 耗尽等情况有利。802.1Q 中继场景看起来是相同的。两种模式都遵守标记标准,并与物理网络无缝集成,以实现底层集成和硬件供应商插件集成。

同一 VLAN 上的主机通常在同一个子网中,并且几乎总是根据其安全策略分组在一起。在大多数情况下,多层应用程序会分层到不同的子网中,因为每个进程的安全配置文件都需要某种形式的隔离。例如,将您的信用卡处理托管在与前端 Web 服务器相同的虚拟网络上将是一个法规遵从性问题,同时也规避了分层纵深防御架构的长期最佳实践。VLAN 或在使用覆盖驱动程序时的等效 VNI(虚拟网络标识符)是隔离租户流量的第一步。

Docker VLANs in-depth

带有 VLAN 标记的 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 表示 eth0 的一个子接口,标记为 VLAN ID 为 10。等效的 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 中继链路接入 Docker 主机。该虚拟链接将是在网络创建中传递的 -o parent=。对于未标记(非 VLAN)的链接,它就像 -o parent=eth0 一样简单,或者对于具有 VLAN ID 的 802.1Q 中继,每个网络都映射到来自网络的相应 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 将如何适应容器网络的人,请看以下示例。

Docker IPvlan L2 mode

IPvlan L3 模式会丢弃所有广播和多播流量。仅凭这一点,IPvlan L3 模式就成为那些寻求大规模、可预测的网络集成的首选。它是可预测的,反过来将带来更高的正常运行时间,因为它不涉及桥接。桥接环路曾导致一些备受瞩目的中断,根据故障域的大小,这些中断可能很难精确定位。这是由于 BPDU(桥接端口数据单元)的级联性质,它们在广播域(VLAN)中泛洪以查找和阻止拓扑环路。消除桥接域,或者至少将其隔离到一对 ToR(机架顶部交换机),将减少难以排查的桥接不稳定性。IPvlan L2 模式非常适合仅中继到一对 ToR 的隔离 VLAN,这些 ToR 可以提供无环路的非阻塞结构。更进一步的下一步是通过 IPvlan L3 模式在边缘进行路由,这将故障域缩小到仅限本地主机。

  • L3 模式需要位于与默认命名空间不同的子网上,因为它需要在默认命名空间中有一个指向 IPvlan 父接口的 netlink 路由。
  • 本示例中使用的父接口是 eth0,它位于子网 192.168.1.0/24 上。请注意,docker networketh0 不在同一个子网上。
  • 与 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 routeip -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 子网。该子网是隔离的,除非上游网络在 VLAN 139 上显式路由它。

# 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

下一个示例将设置一个双栈 IPv4/IPv6 网络,示例 VLAN ID 为 140

接下来创建一个包含两个 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 请求并使用辅助子网。然而,IPvlan L3 只要共享相同的 -o parent 父链接,就会在不同的子网之间路由单播流量。

双栈 IPv4 IPv6 IPvlan L3 模式

示例:IPvlan L3 模式双栈 IPv4/IPv6,多子网,带 802.1Q VLAN 标签:118

与所有示例一样,不必使用带标签的 VLAN 接口。子接口可以替换为 eth0eth1bond0 或主机上除 lo 回环接口外的任何其他有效接口。

您将看到的主要区别是,L3 模式不会创建带有下一跳的默认路由,而是设置一个仅指向 dev eth 的默认路由,因为根据设计,ARP/广播/多播都被 Linux 过滤掉了。由于父接口实质上充当路由器,因此父接口的 IP 和子网需要与容器网络不同。这与桥接和 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
注意

当指定 --ip6= 地址时可能存在一个 bug,即当您删除一个带有指定 v6 地址的容器,然后启动一个具有相同 v6 地址的新容器时,它会抛出以下错误,就像地址没有被正确释放到 v6 池中一样。它将无法卸载容器并使其处于死机状态。

docker: Error response from daemon: Address already in use.

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 用户提供最大的灵活性。

© . This site is unofficial and not affiliated with Kubernetes or Docker Inc.