我创建了一个桥 br0 和 veth(v0 和 v1),但它们不能互操作。 tcpdump 显示 ICMP 的 IP 源已更改。当Mask为/24时,它们将可以互操作。感谢您的帮助。
[root@VM-12-6-centos ~]# ip netns exec n1 ip addr
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
1147: v0@if1146: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 46:39:b5:cf:bd:b6 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 192.168.0.2/16 scope global v0
valid_lft forever preferred_lft forever
inet6 fe80::4439:b5ff:fecf:bdb6/64 scope link
valid_lft forever preferred_lft forever
[root@VM-12-6-centos ~]# ip netns exec n2 ip addr
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
1149: v1@if1148: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 56:c0:82:05:6f:7d brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 192.168.0.3/16 scope global v1
valid_lft forever preferred_lft forever
inet6 fe80::54c0:82ff:fe05:6f7d/64 scope link
valid_lft forever preferred_lft forever
[root@VM-12-6-centos ~]# ip netns exec n2 ping 192.168.0.2
PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data. ^C
--- 192.168.0.2 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 81ms
[root@VM-12-6-centos ~]# ip netns exec n1 tcpdump -ni v0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on v0, link-type EN10MB (Ethernet), capture size 262144 bytes
23:49:35.395270 IP 10.0.12.6 > 192.168.0.2: ICMP echo request, id 7989, seq 1, length 64 23:49:40.562143 ARP, Request who-has
192.168.0.2 tell 192.168.0.3, length 28 23:49:40.562154 ARP, Reply 192.168.0.2 is-at 46:39:b5:cf:bd:b6, length 28
[root@VM-12-6-centos ~]# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.12.1 0.0.0.0 UG 100 0 0 eth0
10.0.12.0 0.0.0.0 255.255.252.0 U 100 0 0 eth0
10.42.0.0 0.0.0.0 255.255.255.0 U 0 0 0 cni0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
172.20.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker_gwbridge
172.31.0.0 0.0.0.0 255.255.0.0 U 0 0 0 br-3f74298c82df
192.168.0.0 0.0.0.0 255.255.240.0 U 0 0 0 br-447c96a995be
[root@VM-12-6-centos ~]# brctl show bridge name bridge id STP enabled interfaces br-3f74298c82df 8000.0242cacea67f no vethf4618dd br-447c96a995be 8000.024273831baf no vethbf5d89d br0 8000.7ae1f3216832 no br-v0
br-v1 cni0 8000.52bc6b3b510e no veth0f9960a8
veth1cd3811c
veth2a89c6ed
veth3aeb1ce7
vethca9494e3 docker0 8000.0242fcf19461 no docker_gwbridge
8000.02420fc41a90 no veth85a243e
vethd1cfb42
答案1
为了使一切正常工作,您需要创建两对veth
管道。一方面,它们必须包含在桥中。网桥和 veth 接口的末端位于根网络命名空间中。管道 v1 和 v2 的另一端分别位于命名空间 n1 和命名空间 n2 中。例子:
ip netns add n1
ip netns add n2
桥中包含的两端称为 bv1 和 bv2:
ip link add v1 netns n1 type veth peer name bv1
ip link add v2 netns n2 type veth peer name bv2
ip link add br0 type bridge
ip link set br0 up
ip link set bv1 master br0
ip link set bv2 master br0
ip link set bv1 up
ip link set bv2 up
brctl show
bridge name bridge id STP enabled interfaces
br0 8000.d2dba1636571 no bv1
bv2
转到n1:
nsenter --net=/var/run/netns/n1
ip addr add 192.168.0.2/16 dev v1
ip link set v1 up
ip link set lo up
exit
转到n2:
nsenter --net=/var/run/netns/n2
ip addr add 192.168.0.3/16 dev v2
ip link set v2 up
ip link set lo up
exit
结果:
ip netns exec n1 ping -c2 -I v1 192.168.0.3
PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.
64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.265 ms
64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.220 ms
ip netns exec n2 ping -c2 -I v2 192.168.0.2
PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.
64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=0.195 ms
64 bytes from 192.168.0.2: icmp_seq=2 ttl=64 time=0.227 ms
答案2
问题中没有足够的信息来给出明确的答案,但是:
桥接器中有大量其他接口,并且您提到了 Docker。您看到的 ping 数据包很可能来自 Docker 中的某些内容,而不是您发出的 ping。这就是为什么“源 IP 改变了”(它没有改变,这是一个完全不同的 ping)。
通过在没有 docker 的系统上创建网桥和 veth 来验证这一点。您还需要在第二个终端中运行 tcpdump,它必须在您执行 ping 操作时运行。
另一种选择是 Docker 的众多 iptables 规则之一实际上会影响您的 ping,并且做无论出于何种原因更改源地址。
TL;DR:如果你正在运行 docker,不尝试干扰网络。你将很难让任何东西正常工作,即使你让它正常工作,下次 Docker 更新其 iptables 规则时它也可能再次崩溃。
如果您需要两个容器之间的直接网络,请使用覆盖网络,并且需要五分钟才能完成码头工人组成。
从https://docs.docker.com/network/iptables/,根据评论,强调我的:
在 Linux 上,Docker 操纵 iptables 规则来提供网络隔离。虽然这是一个实施细节并且你不应该修改 Docker 插入的规则到你的 iptables 策略中,它确实对你需要做什么有一些影响,如果你想要另外你自己的政策那些由 Docker 管理的。
这意味着,特别是连接到 Docker 使用的桥的任何内容都将受到 Docker iptables 规则的约束,您可以使用这些规则不应该修改。
您可以对完全独立于 Docker 网络的任何内容制定自己的策略,但我不建议干预 Docker 的网络方式。
这意味着如果你想在 Docker 容器之间建立网络,你应该以简单的方式实现,而不是困难的方式。