按特定顺序将新 NIC 添加到 Docker 容器

Adding a new NIC to a Docker container in a specific order

我正在尝试创建一个带有两个网络接口的 CentOS 容器。 在浏览了 Docker 文档和 "googleing" 之后,我发现 this GitHub issue comment 指定了如何实现这一点。

接着,我创建了一个新网络(默认类型:bridge

docker network create my-network

检查新网络,我可以看到 Docker 将其分配给了子网 172.18.0.0/16 和网关 172.18.0.1/16

然后,在创建容器的时候,我特地附加了新的网络:

docker create -ti --privileged --net=my-network --mac-address 08:00:AA:AA:AA:FF <imageName>

在容器内,我可以用 ifconfig 检查接口是否确实存在,并且 mac 地址:

eth0      Link encap:Ethernet  HWaddr 08:00:AA:AA:AA:FF  
          inet addr:172.18.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::a00:aaff:feaa:aaff/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:3 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:258 (258.0 b)  TX bytes:258 (258.0 b)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

当我将容器连接到默认 Docker 网络时出现问题 (bridge0 a.k.a bridge):

docker network connect bridge <my-container>

正在检查容器中的接口:

eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02  
          inet addr:172.17.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:acff:fe11:2/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:17 errors:0 dropped:0 overruns:0 frame:0
          TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:2941 (2.8 KiB)  TX bytes:508 (508.0 b)

eth1      Link encap:Ethernet  HWaddr 08:00:AA:AA:AA:FF  
          inet addr:172.18.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::a00:aaff:feaa:aaff/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:17 errors:0 dropped:0 overruns:0 frame:0
          TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:2941 (2.8 KiB)  TX bytes:508 (508.0 b)

我的新网络接口移至 eth1,同时默认网络接口变为 eth0

另外,在查看接口配置文件(/etc/sysconfig/network-scripts/ifcfg-eth0)时,我发现那里指定的MAC地址与我在运行时手动设置的地址不同容器(08:00:AA:AA:AA:FF):

DEVICE="eth0"
BOOTPROTO="dhcp"
HWADDR="52:54:00:85:11:33"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
MTU="1500"
NM_CONTROLLED="yes"
ONBOOT="yes"
TYPE="Ethernet"
UUID="25016937-1ff9-40d7-b4c3-18e08af0f98d"

In /etc/sysconfig/network-scripts there is only the configuration file for eth0. The file for eth1 (the newly added interface) is missing.

由于我所从事的工作需要,我需要第一个接口必须始终禁用,并且必须专门设置其MAC地址。

任何其他与网络相关的工作都必须通过新连接的 NIC。

我的问题是:

如何将新的 NIC 附加到容器,以便 eth0 将具有所需的 MAC 地址。

在图像级别执行此操作也很好。

目标是拥有一个带有两个 NIC 的 运行 容器:eth0eth1

eth0 将有一个特定的 MAC 地址(比方说,AA:AA:AA:AA:AA:AA)并将被禁用。所有网络都将通过 eth1.

完成

I will assume that the Docker image has a user with rights to execute ifdown and/or ifconfig

eth0 已经存在于映像中,"talks" 到默认的 Docker 网络:bridge(在安装 Docker 时创建)。

我们必须修改图像中 eth0 的配置文件 (/etc/sysconfig/network-scripts/ifcg-eth0) 以修改其 MAC 地址:文件中名为 HWADDR 的字段。

在此之后,我们必须提交 对新图像的更改。我们称它为 myImage.

现在,我们必须为第二个接口创建一个新网络:

docker network create myNetwork

By default it is a bridge network (which is enough in my case).

由于要求 eth0 具有自定义 MAC 地址,因此我们必须在不指定网络的情况下创建容器;这会将它连接到默认的桥接网络。

docker create -ti --mac-address=AA:AA:AA:AA:AA:AA --privileged --hostname=myHostnane --name=myContainer myImage

It is important to create the container with the --privileged switch so we can take down the eth0 interface.

现在,在启动容器之前,我们将它连接到新网络:

docker network connect myNetwork myContainer

现在容器有两个接口:bridge 网络的原始 eth0myNetwork 网络的新 eth1

此时,我们可以启动容器:

docker start myContainer

然后执行命令取下eth0:

docker exec myContainer /bin/bash -c "sudo ifdown eth0"

To take down the interface, we must do this when running a container. The reason is that any changes in the networking files will only persist in its running container, so it's not possible to commit the down interface (old, but still relevant).