Network Namespace(netns) 是Linux内核提供的一项实现网络隔离的功能,它能隔离多个不同的网络空间,并且各自拥有独立的网络协议栈。通过 namespace 可以隔离容器的进程 PID、文件系统挂载点、主机名等多种资源,它可以为不同的命名空间从逻辑上提供独立的网络协议栈,具体包括网络设备(网卡)、路由表、arp表、iptables、以及套接字(socket)等。使得不同的网络空间就都好像运行在独立的网络中一样。如大名鼎鼎的docker便是基于netns实现的网络隔离。
1、ip netns 帮助文档
A network namespace is logically another copy of the network stack, with its own routes, firewall rules, and network devices.
ip-netns
- process network namespace management.
ip netns help
man ip-netns
man ip netns
=========================================
Usage:
ip [ OPTIONS ] netns { COMMAND | help }
ip netns [ list ]
ip netns add NETNSNAME
ip [-all] netns delete [ NETNSNAME ]
ip netns set NETNSNAME NETNSID
ip netns identify [ PID ]
ip netns pids NETNSNAME
ip [-all] netns exec [ NETNSNAME ] command...
ip netns monitor
ip netns list-id
1.将 {网卡名字} 移动到 {网络命名空间}
ip link set {网卡名字} netns {网络命名空间}
2.将接口iner1从网络名称空间ns2移动到网络名称空间ns1
ip netns exec ns2 ip link set iner1 netns ns1
3.将接口iner1从名称空间ns2移动到Linux上默认网络名称空间
2、ip netns 实践
2.1、添加两个tap设备并配置IP信息
添加两个tap设备并配置IP信息
1.添加并启动虚拟网卡tap设备
ip tuntap add dev tap0 mode tap
ip tuntap add dev tap1 mode tap
ip link set tap0 up
ip link set tap1 up
2.配置IP
ip addr add 10.0.0.1/24 dev tap0
ip addr add 10.0.0.2/24 dev tap1
在宿主机器上使用测试与tap0 10.0.0.1
的网络连通性 (通
)
ping -c 1 10.0.0.1
===========================================================
在宿主机器上使用测试与tap0 10.0.0.2
的网络连通性 (通
)
ping -c 1 10.0.0.2
===========================================================
2.2、添加两个netns,移动tap设备到netns中
然后添加两个netns,最后将tap设备移动到netns中
3.添加netns
ip netns add ns0
ip netns add ns1
4.将虚拟网卡tap0,tap1分别移动到ns0和ns1中
ip link set tap0 netns ns0
ip link set tap1 netns ns1
在宿主机器上使用测试与tap0 10.0.0.1
的网络连通性 (不通
)
ping -c 1 10.0.0.1
===========================================================
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
--- 10.0.0.1 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms
在宿主机器上使用测试与tap0 10.0.0.2
的网络连通性 (不通
)
ping -c 1 10.0.0.2
===========================================================
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
--- 10.0.0.2 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms
在命名空间ns0中测试与tap1的网络连通性 (不通
)
ip netns exec ns0 ping -c 1 10.0.0.2
====================================
connect: Network is unreachable
在命名空间ns1中测试与tap0的网络连通性 (不通
)
ip netns exec ns1 ping -c 1 10.0.0.1
====================================
connect: Network is unreachable
在netns中执行命令有两种方式,一种是先在宿主机器上执行ip netns exec bash进入netns,然后就可以像是在本机一样执行命令了。另一种是每次在宿主机器上使用完整的命令,为了明显区分,我们这里都使用完整的命令,例如ip netns exec ns0 ping 10.0.0.2的含义为在命名空间ns0中执行ping 10.0.0.2命令
可以看到在宿主机器上访问netns是丢包,而在netns中互相访问是网络不可达了,这是为什么呢?让我们来检查一下netns吧。
使用ip netns exec ns0 ip a在ns0中查看网卡
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
16: tap0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 42:ad:98:a2:cc:81 brd ff:ff:ff:ff:ff:ff
使用ip netns exec ns1 ip a在ns1中查看网卡
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
17: tap1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 12:06:1d:06:41:57 brd ff:ff:ff:ff:ff:ff
可以看到不仅本地环回lo和tap设备的状态都是DOWN,甚至就连tap设备的IP信息也没有了,这是因为在不同的网络命名空间中移动虚拟网络接口时会重置虚拟网络接口的状态。
我们将ns0和ns1中的相关设备都重新启动并配置上IP
ip netns exec ns0 ip link set lo up
ip netns exec ns0 ip link set tap0 up
ip netns exec ns0 ip addr add 10.0.0.1/24 dev tap0
ip netns exec ns1 ip link set lo up
ip netns exec ns1 ip link set tap1 up
ip netns exec ns1 ip addr add 10.0.0.2/24 dev tap1
首先我们测试一下netns中本地网络是否正常
使用ip netns exec ns0 ping 10.0.0.1在命名空间ns0中测试本地网卡是否启动
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=0.036 ms
64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=0.033 ms
64 bytes from 10.0.0.1: icmp_seq=3 ttl=64 time=0.084 ms
64 bytes from 10.0.0.1: icmp_seq=4 ttl=64 time=0.044 ms
^C
--- 10.0.0.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 65ms
rtt min/avg/max/mdev = 0.033/0.049/0.084/0.021 ms
使用ip netns exec ns1 ping 10.0.0.2在命名空间ns1中测试本地网卡是否启动
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.033 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.034 ms
64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=0.065 ms
64 bytes from 10.0.0.2: icmp_seq=4 ttl=64 time=0.035 ms
^C
--- 10.0.0.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 65ms
rtt min/avg/max/mdev = 0.033/0.049/0.084/0.021 ms
可以看出本地网络没有问题,然后我们再来测试一下两个netns之间的网络连通性
使用ip netns exec ns0 ping 10.0.0.2在命名空间ns0中测试与tap1的网络连通性
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
^C
--- 10.0.0.2 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 84ms
使用ip netns exec ns1 ping 10.0.0.1在命名空间ns1中测试与tap0的网络连通性
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
^C
--- 10.0.0.1 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 30ms
可以看出没有任何ICMP回复包,netns确实把在同一台主机上的两张虚拟网卡隔离起来了。在这里我们只是简单的使用ping命令来测试网络的连通性,实际上可以做到更多,例如修改某一个netns的路由表或者防火墙规则,完全不会影响到其他的netns,当然也不会影响到宿主机器,在这里由于篇幅原因就不再展开实验了,感兴趣的同学可以实验一下。下一节我们将学习另一个网络设备veth pair,使用它来把两个netns连接起来,让两个隔离的netns之间可以互相通信。
初心易得,始终难守;不忘初心,方得始终。