网络命名空间
在 Linux 中,网络名字空间可以被认为是隔离的拥有单独网络栈(网卡、路由转发表、iptables)的环境。网络名字空间经常用来隔离网络设备和服务,只有拥有同样网络名字空间的设备,才能看到彼此。
从逻辑上说,网络命名空间是网络栈的副本,有自己的网络设备、路由选择表、邻接表、Netfilter表、网络套接字、网络procfs条目、网络sysfs条目和其他网络资源。
从系统的角度来看,当通过clone()系统调用创建新进程时,传递标志CLONE_NEWNET将在新进程中创建一个全新的网络命名空间。
从用户的角度来看,我们只需使用工具ip(package is iproute2)来创建一个新的持久网络命名空间。
创建netns
查看是否存在命名空间:ip netns list
若报错,需要更新系统内核,以及 ip 工具程序。
1 | 列出网卡 |
创建新的虚拟网卡:
1 | #ip link add veth0 type veth peer name veth1 |
同时创建veth0和veth1两个虚拟网卡
这个时候这两个网卡还都属于“default”或“global”命名空间,和物理网卡一样。
把其中一个网卡转移到命名空间ns1中:ip link set veth1 netns ns1
验证:ip netns exec ns1 ip link list
删除:ip netns exec ns1 ip link del veth1
1 | #ip link set veth1 netns ns1 |
配置命名空间中的端口:
1 | #ip netns exec ns1 ip addr add 10.1.1.100/24 dev veth1 |
配置宿主机上网卡ip:
1 | #ip addr add 10.1.1.101/24 dev veth0 |
此时在ns1中ping自己10.1.1.100能通: (掩码都是24,网络在一个二层内)
ip netns exec ns1 ping 10.1.1.100
PING 10.1.1.100 (10.1.1.100) 56(84) bytes of data.
64 bytes from 10.1.1.100: icmp_seq=1 ttl=64 time=0.058 ms
但还不能ping通10.1.1.101,因为ns1中未设置路由。
设置命名空间路由
设置默认路由
1 | #ip netns exec ns1 ip route add default via 10.1.1.100 |
此时能够ping通主机:
1 | #ip netns exec ns1 ping 10.1.1.101 |
使能IP转发
但是到了这里依旧还不够,ns1命名空间中已经可以联通主机上的网络,但是依旧连不同主机以外的外部网络。这个时候必须在host主机上启动转发,并且在iptables中设置伪装。
Linux系统的IP转发的意思是,当Linux主机存在多个网卡的时候,允许一个网卡的数据包转发到另外一张网卡;在linux系统中默认禁止IP转发功能,可以打开如下文件查看,如果值为0说明禁止进行IP转发:
1 | cat /proc/sys/net/ipv4/ip_forward: |
#刷新forward规则
iptables -F FORWARD
iptables -t nat -F
#刷新nat规则
iptables -t nat -L -n
#使能IP伪装
iptables -t nat -A POSTROUTING -s 10.1.1.0/255.255.255.0 -o ens32 -j MASQUERADE # ens32连接外网
#允许veth0和ens32之间的转发
iptables -A FORWARD -i ens32 -o veth0 -j ACCEPT
iptables -A FORWARD -o ens32 -i veth0 -j ACCEPT
使能IP伪装这条语句,添加了一条规则到NAT表的POSTROUTING链中,对于源IP地址为10.1.1.0网段的数据包,用ens32网口的IP地址替换并发送。
iptables -A FORWARD这两条语句使能物理网口ens32和veth0之间的数据转发
总结
Linux网络命名空间提供了强大的虚拟化功能,使用得当能够达到事半功倍的效果。
本文简要介绍了Linux提供的6种命名空间,对命名空间的作用和使用场景作了详细的介绍。
着重对Linux网络命名空间进行了讲解,包括命名空间的创建、使用,与主机通信以及与外部网络的连接等。
对于一般的应用而言,掌握网络命名空间的创建、使用、ip命令等就能顺当使用命名空间了。