使用 macvlan 网络进行网络连接

本系列教程涉及连接到 macvlan 网络的独立容器的网络配置。在这种网络类型中,Docker 主机在其 IP 地址处接受多个 MAC 地址的请求,并将这些请求路由到相应的容器。有关其他网络主题,请参阅 概述

目标

这些教程的目标是设置一个桥接的 macvlan 网络并将 容器附加到它上面,然后设置一个 802.1Q 中继的 macvlan 网络并将一个 容器附加到它上面。

前提条件

  • 大多数云提供商阻止 macvlan 网络。您可能需要对网络设备进行物理访问。

  • macvlan 网络驱动程序仅适用于 Linux 主机,在 Docker Desktop for Mac、Docker Desktop for Windows 或 Windows Server 的 Docker EE 上不受支持。

  • 您至少需要 Linux 内核版本 3.9,推荐使用 4.0 或更高版本。

  • 这些示例假设您的以太网接口是 eth0。如果您的设备有不同的名称,请使用该名称。

  • 在 rootless 模式下不支持 macvlan 驱动。

桥接示例

在简单的桥接示例中,您的流量通过 eth0 传输,Docker 使用其 MAC 地址将流量路由到您的容器。对于网络上的 网络设备而言,您的容器看起来像是物理连接到网络的。

  1. 创建一个名为 my-macvlan-netmacvlan 网络。修改 subnetgatewayparent 的值为适合您环境的值。

    $ docker network create -d macvlan \
      --subnet=172.16.86.0/24 \
      --gateway=172.16.86.1 \
      -o parent=eth0 \
      my-macvlan-net
    

    您可以使用 docker network lsdocker network inspect my-macvlan-net 命令来验证网络是否存在以及它是否是一个 macvlan 网络。

  2. 启动一个 alpine 容器并将其连接到 my-macvlan-net 网络。 -dit 标志在后台启动容器,但允许您附加到它。 --rm 标志意味着容器在停止时会被删除。

    $ docker run --rm -dit \
      --network my-macvlan-net \
      --name my-macvlan-alpine \
      alpine:latest \
      ash
    
  3. 检查 my-macvlan-alpine 容器并注意 Networks 键中的 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
    
  4. 通过运行几个 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
    
  5. 停止容器(由于 --rm 标志,Docker 会将其移除),并移除 网络。

    $ docker container stop my-macvlan-alpine
    
    $ docker network rm my-macvlan-net
    

802.1Q trunked 网桥示例

在 802.1Q 中继网桥示例中,您的流量通过 eth0 的子接口(称为 eth0.10)传输,Docker 使用容器的 MAC 地址将流量路由到您的容器。对于您网络上的网络设备来说,您的容器看起来像是物理连接到网络上一样。

  1. 创建一个名为 my-8021q-macvlan-netmacvlan 网络。修改 subnetgatewayparent 的值为适合你环境的值。

    $ 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 lsdocker network inspect my-8021q-macvlan-net 命令来验证网络是否存在,是否为 macvlan 网络,以及是否具有父级 eth0.10。您可以在 Docker 主机上使用 ip addr show 来验证接口 eth0.10 是否存在并具有独立的 IP 地址

  2. 启动一个 alpine 容器并将其附加到 my-8021q-macvlan-net 网络。-dit 标志在后台启动容器,但允许 您附加到它。--rm 标志意味着容器在 停止时被删除。

    $ docker run --rm -itd \
      --network my-8021q-macvlan-net \
      --name my-second-macvlan-alpine \
      alpine:latest \
      ash
    
  3. 检查 my-second-macvlan-alpine 容器并注意 Networks 键中的 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
    
  4. 通过运行几个 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
    
  5. 停止容器(由于 --rm 标志,Docker 会将其移除),并移除 网络。

    $ docker container stop my-second-macvlan-alpine
    
    $ docker network rm my-8021q-macvlan-net
    

其他网络教程