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 使用者提供最大的靈活性。