Docker入门系列 8. Docker 容器网络的概念及网络配置 macvlan


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 macvlandocker 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 地址将流量路由到容器。 对于网络上的网络设备,容器看起来是物理连接到网络的。

  1. 创建一个称为 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 网络。

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

    $ docker run --rm -itd \
    --network my-macvlan-net \
    --name my-macvlan-alpine \
    alpine:latest \
    ash
  3. 检查 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
  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

2.4 集束桥接(vlan)

在802.1 q 集束桥接的示例中,流量通过 eth0(称为 eth0.10)的子接口流动,而 Docker 使用容器的 MAC 地址将流量路由到容器。 对于网络上的网络设备,容器看起来是物理连接到网络的。

  1. 创建一个名为 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 lsdocker network inspection 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 容器,注意网络键中的 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

文章作者: Baymax
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Baymax !
评论
 上一篇
Docker入门系列  9. Docker 容器的数据管理  数据卷 绑定挂载 临时挂载 Docker入门系列 9. Docker 容器的数据管理 数据卷 绑定挂载 临时挂载
因为容器技术,重新构建并运行应用变得容易且快速,容器化应用基本是无需进一步配置的(已经打包好所有依赖并且已配置),只需PULL,然后Deploy(也许还需要一份docker-compose.yml)就好。我们无需太担心硬件,OS,库以及应用
2020-05-25
下一篇 
Docker入门系列  7. Docker 容器网络的概念及网络配置 主机网络 Docker入门系列 7. Docker 容器网络的概念及网络配置 主机网络
1. 使用主机网络如果您使用容器的主机网络模式,那么容器的网络堆栈不会与 Docker 主机隔离(容器共享主机的网络名称空间) ,并且容器不会得到自己的 ip 地址分配。 例如,如果您运行一个绑定到端口80的容器,并且使用主机网络,那么容器
2020-05-25
  目录