无法将多个网络命名空间链接在一起

无法将多个网络命名空间链接在一起

问题陈述

通过以下配置,在默认/主网络命名空间和名为 的 netns 之间创建一个 veth 对ns1

该配置还创建了第二个 veth 对:veth2 在 netns 中ns1,而 veth3 在 netns 中ns2,这会加入ns1创建ns2链:default netns-veth0 <-> veth1-ns1-veth2 <-> veth3-ns2

sudo ip link add veth0 type veth peer name veth1
sudo ip -6 addr add CCFF::0/127 peer CCFF::1/127 dev veth0
sudo ip link set up dev veth0

sudo ip netns add ns1
sudo ip link set veth1 netns ns1
sudo ip -n ns1 -6 addr add CCFF::1/127 peer CCFF::0/127 dev veth1
sudo ip -n ns1 link set up dev veth1
sudo ip -n ns1 -6 route add default via CCFF::0

sudo ip link add veth2 type veth peer name veth3
sudo ip link set veth2 netns ns1
sudo ip -n ns1 -6 addr add CCFF::2/127 peer CCFF::3/127 dev veth2
sudo ip -n ns1 link set up dev veth2
sudo ip -n ns1 -6 route add CCFF::/64 via CCFF::3

sudo ip netns add ns2
sudo ip link set veth3 netns ns2
sudo ip -n ns2 -6 addr add CCFF::3/127 peer CCFF::2/127 dev veth3
sudo ip -n ns2 link set up dev veth3
sudo ip -n ns2 -6 route add default via CCFF::2

sudo ip -6 r add CCFF::/64 via CCFF::1

从默认网络,我可以 ping 位于同一网络的 veth0。从默认网络,我可以 ping 位于 中的 veth1 和 veth2 ns1。从默认网络,我无法 ping 位于 中的 veth3 ns2

如果我按如下方式扩展更改,即在 中添加 veth4ns2并在 中添加 veth5,ns3则会出现同样的问题。我可以从 中的任何接口 pingns1到 中的任何接口ns2,但无法到达 中的任何接口ns3

sudo ip link add veth4 type veth peer name veth5
sudo ip link set veth4 netns ns2
sudo ip netns exec ns2 ip -6 addr add CCFF::4/127 peer CCFF::5/127 dev veth4
sudo ip netns exec ns2 ip link set up dev veth4
sudo ip netns exec ns2 ip -6 route add CCFF::/64 via CCFF::5

sudo ip netns add ns3
sudo ip link set veth5 netns ns3
sudo ip netns exec ns3 ip -6 addr add CCFF::5/127 peer CCFF::4/127 dev veth5
sudo ip netns exec ns3 ip link set up dev veth5
sudo ip netns exec ns3 ip -6 route add default via CCFF::4

看来我只能 ping 到与我 ping 的直接“相邻”/“连接”网络中的接口。我无法 ping 过网络命名空间链。路由全部有效;默认网络可以 ping 中的任何接口,ns1但不能进一步 ping, 中的接口ns1可以 ping 默认网络中的任何接口或ns2但不能 ping 中的任何接口ns3,并且ns3可以 ping 中的任何内容ns2但不能pingns1或默认网络之外的内容。

这是网络命名空间的限制吗?

故障排除

IPv6 转发已启用,ip6tables 仅设置为“允许所有”,我不确定还要检查什么。

$ip -6 r
ccff::1 dev veth0 proto kernel metric 256 pref medium
ccff::/127 dev veth0 proto kernel metric 256 pref medium
ccff::/64 via ccff::1 dev veth0 metric 1024 pref medium
fe80::/64 dev veth0 proto kernel metric 256 pref medium

$sudo ip -n ns1 -6 r
ccff:: dev veth1 proto kernel metric 256 pref medium
ccff::/127 dev veth1 proto kernel metric 256 pref medium
ccff::3 dev veth2 proto kernel metric 256 pref medium
ccff::2/127 dev veth2 proto kernel metric 256 pref medium
ccff::/64 via ccff::3 dev veth2 metric 1024 pref medium
fe80::/64 dev veth1 proto kernel metric 256 pref medium
fe80::/64 dev veth2 proto kernel metric 256 pref medium
default via ccff:: dev veth1 metric 1024 pref medium

$sudo ip -n ns2 -6 r
ccff::2 dev veth3 proto kernel metric 256 pref medium
ccff::2/127 dev veth3 proto kernel metric 256 pref medium
ccff::5 dev veth4 proto kernel metric 256 pref medium
ccff::4/127 dev veth4 proto kernel metric 256 pref medium
ccff::/64 via ccff::5 dev veth4 metric 1024 pref medium
fe80::/64 dev veth3 proto kernel metric 256 pref medium
fe80::/64 dev veth4 proto kernel metric 256 pref medium
default via ccff::2 dev veth3 metric 1024 pref medium

$sudo ip -n ns3 -6 r
ccff::4/127 dev veth5 proto kernel metric 256 linkdown pref medium
default via ccff::4 dev veth5 metric 1024 linkdown pref medium

$cat /proc/sys/net/ipv6/conf/all/forwarding 
1

$cat /proc/sys/net/ipv6/conf/default/forwarding 
1

$sudo ip6tables-save
# Generated by ip6tables-save v1.8.4 on Wed Nov 17 22:02:48 2021
*filter
:INPUT ACCEPT [76565:173401906]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [50440:6536664]
COMMIT
# Completed on Wed Nov 17 22:02:48 2021

$lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 20.04.3 LTS
Release:    20.04
Codename:   focal

$uname -a
Linux l13-ubuntu 5.11.0-40-generic #44~20.04.2-Ubuntu SMP Tue Oct 26 18:07:44 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

答案1

已启用 IPv6 转发

可能不是:当我在我的系统上尝试使用问题开头给出的命令时,我也无法达到veth3

$ ping -6 CCFF::3
PING CCFF::3(ccff::3) 56 data bytes
^C
--- CCFF::3 ping statistics ---
13 packets transmitted, 0 received, 100% packet loss, time 12290ms

但是,当我在ns1

echo 1 | sudo ip netns exec ns1 tee /proc/sys/net/ipv6/conf/all/forwarding

有用:

$ ping -6 CCFF::3
PING CCFF::3(ccff::3) 56 data bytes
64 bytes from ccff::3: icmp_seq=1 ttl=63 time=0.112 ms
64 bytes from ccff::3: icmp_seq=2 ttl=63 time=0.054 ms

因此,您可能也没有在 中启用 IPv6 转发ns1。(请记住,转发是每个命名空间;您是否在主命名空间中启用了它,但没有在ns1?)


我通过tcpdump在每个接口上执行此操作来调试这个问题;ping 没有到达,veth2表明转发未启用。

如果您想知道“但是为什么veth2如果没有启用转发,我可以 ping 通”:Linux 将所有本地地址视为相同,因此您可以从任何接口访问任何本地地址。这与转发完全无关。

顺便说一句,它可以帮助你们xterm在每个命名空间中运行;这使得调试变得容易得多。

答案2

我得出了与 @dirkt 相同的完全有效的结论,每个命名空间本身都是一个网络主机,包括它是否像路由器一样运行的设置(默认为关闭)。/proc/sys/net 设置对于每个命名空间都是独立的。解析是独立的,接口链接是独立的(但主机名不是,为此您必须创建 UTS 命名空间)。所以基本上这就是您的答案。

无论如何,我都不会贬低它,但为了将来参考,我会添加一些内容并稍微重新安排和简化它。您实际上不需要默认命名空间中的路由设置,除非您想将外部流量路由到这些命名空间或反之亦然。

总结一下默认命名空间和 ns1 加 ns2 的构造。

# create namespaces
ip netns add ns1
ip netns add ns2

# loopbacks, nice to have
ip -n ns1 link set lo up
ip -n ns2 link set lo up

# make veth pairs for each new namespace
ip link add veth0 type veth peer name veth1
ip link add veth2 type veth peer name veth3

# add interfaces to their namespaces
ip link set veth1 netns ns1
ip link set veth2 netns ns1
ip link set veth3 netns ns2

# assign addresses
ip -6 addr add CCFF::0/127 dev veth0
ip -n ns1 -6 addr add CCFF::1/127 dev veth1
ip -n ns1 -6 addr add CCFF::2/127 dev veth2
ip -n ns2 -6 addr add CCFF::3/127 dev veth3

# set the new links to up
ip link set up dev veth0
ip -n ns1 link set up dev veth1
ip -n ns1 link set up dev veth2
ip -n ns2 link set up dev veth3

# namespaces that should forward
ip netns exec ns1 sysctl -w net.ipv6.conf.all.forwarding=1

# route any ip6 outward towards host through namespace 1
ip -n ns2 -6 route add default via CCFF::2

# route any ccff ip6 inward from host
# to a more inner space through namespace 1
ip -6 r add CCFF::/64 via CCFF::1

然后你可以进行一些测试:

ip netns list
ip netns exec ns2 ping6 ccff::0
ip netns exec ns2 ping6 ccff::1
ip netns exec ns2 ping6 ccff::3

# Or put your shell (e.g. bash) in the namespace ns2
ip netns exec ns2 /bin/bash
ping6 ccff::0
exit

您还可以进行一些解析和主机文件更改

# Setup a resolver 
# (replace with your own DNS, does not work with a loopback resolver)

mkdir -p /etc/netns/ns2
echo nameserver dns-ip > /etc/netns/ns2/resolv.conf

# Maybe give it its own hosts file, to do edits
cp /etc/hosts /etc/netns/ns2/hosts

相关内容