我有一个用例,我创建了一个 Docker macvlan 网络(默认桥接模式)并将此网络连接到正在运行的 Docker 容器(例如 C1)。因此,容器将有一个新的 macvlan 接口(例如 eth1)。
docker network create -d macvlan --subnet=172.16.16.0/24 --gateway=172.16.16.1 -o parent=ens224 macvlan-ens224
docker network connect macvlan-ens224 C1
在容器 C1 内部,我使用 macvlan(eth1)接口和分配的 IP 创建了一个 macvtap 接口。
ip link add link eth1 name mymacvtap0 type macvtap mode private
ip addr add 172.17.17.2/24 dev mymacvtap0
ip link set up dev mymacvtap0
现在,当我从容器内部 ping 子网 172.17.17.2/24 的某个 IP 时,使用容器 macvtap 接口的源 MAC 地址广播 ARP 请求。目标 IP 发回 ARP 回复。ARP 回复到达物理接口 ens224(从 tcpdump 中看到)。但回复从未到达容器内部。
请有人指出我这里遗漏了什么?
答案1
这是 macvlan 驱动程序的工作主要方案:
+---------------+
| network stack |
+---------------+
| | | |
+---------+ | | +------------------+
| | +------------------+ |
| +------------------+ | |
| | | |
| aa +----------+ | | |
| eth0 +-----| macvlan0 |---+ | |
| / +----------+ | |
Wire +------+ +---------------+ bb +----------+ | |
--------| eth0 |------/ if dst mac is /--------| macvlan1 |------+ |
+------+ +---------------+ \ +----------+ |
\ cc +----------+ |
+-----| macvlan2 |---------+
+----------+
如您所见,这种类型的接口按照下一个原理工作:它监听物理网卡并捕获自身的 mac 地址。
如果您要在 macvlan 底部添加任何其他接口。例如网桥或其他 macvlan/macvtap 接口,它会将任何流量从其传输到外部网络,但不会传输到反方向。因为它仅捕获自身 mac 地址的流量。
为了解决您的问题,您应该使用 Linux Bridge,并通过 veth 接口对将您的容器连接到 Bridge。
您仅应在端点时使用 macvlan/macvtap 接口。
您可以在这里获得有关此类接口的更多信息: