Linux中网络命名空间实战各种坑

network namespace

我有一个程序,监听某个端口,在一台Linux机器上,运行多个这样的程序,端口监听一样,冲突怎么办?

可以更改监听端口,这样即使端口不一样,但是程序还是一样的。

如果你硬要监听一样的端口,那么端口肯定是冲突的,除非你另外创建一个网络命名空间,把程序运行在这个命名空间中

可以实战操作一把

root@ubuntu:/home/ubuntu# ip netns --help
Command "--help" is unknown, try "ip netns help".
root@ubuntu:/home/ubuntu# ip netns help
Usage: ip netns list
       ip netns add NAME
       ip netns set NAME NETNSID
       ip [-all] netns delete [NAME]
       ip netns identify [PID]
       ip netns pids NAME
       ip [-all] netns exec [NAME] cmd ...
       ip netns monitor
       ip netns list-id


创建网络命名空间 demo

root@ubuntu:/home/ubuntu# ip netns add demo
root@ubuntu:/home/ubuntu# ip netns ls
demo

添加虚拟网络设备

下面命令添加了两个端对端的网络veth1 veth2

ip link add veth1 type veth peer name veth2

将虚拟网络一端添加到命名空间中, 这里把veth1添加到网络命名空间

ip link set veth1 netns demo

配置网络设备,这里把veth2留在本机并配置IP

ip addr add 172.17.0.1/24 dev veth2

启动设备

ip link set dev veth2 up

查看网络

root@ubuntu:/home/ubuntu# ifconfig -v veth2
veth2: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.255.0  broadcast 0.0.0.0
        ether 8e:7e:64:ff:30:8a  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

给网络命名空间虚拟设备配置IP,并启用网络设备

root@ubuntu:/home/ubuntu# ip netns exec demo ip addr add 172.17.0.2/24 dev veth1
root@ubuntu:/home/ubuntu# ip netns exec demo ip link set dev veth1 up
root@ubuntu:/home/ubuntu# ip netns exec demo ifconfig
veth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.255.0  broadcast 0.0.0.0
        inet6 fe80::38d1:35ff:fe2a:757b  prefixlen 64  scopeid 0x20<link>
        ether 3a:d1:35:2a:75:7b  txqueuelen 1000  (Ethernet)
        RX packets 8  bytes 656 (656.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 8  bytes 656 (656.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

在默认网络与demo命名空间网络,互相ping,都是可以ping通的

但是,最后在demo命名空间中,ping 172.17.0.2 却是没有响应

root@ubuntu:/home/ubuntu# ping 172.17.0.1
PING 172.17.0.1 (172.17.0.1) 56(84) bytes of data.
64 bytes from 172.17.0.1: icmp_seq=1 ttl=64 time=0.107 ms
64 bytes from 172.17.0.1: icmp_seq=2 ttl=64 time=0.159 ms
64 bytes from 172.17.0.1: icmp_seq=3 ttl=64 time=0.158 ms
^C
--- 172.17.0.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2025ms
rtt min/avg/max/mdev = 0.107/0.141/0.159/0.026 ms
root@ubuntu:/home/ubuntu# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.162 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.096 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.092 ms
^C
--- 172.17.0.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2148ms
rtt min/avg/max/mdev = 0.092/0.116/0.162/0.034 ms
root@ubuntu:/home/ubuntu# ip netns exec demo ping 172.17.0.1
PING 172.17.0.1 (172.17.0.1) 56(84) bytes of data.
64 bytes from 172.17.0.1: icmp_seq=1 ttl=64 time=0.217 ms
64 bytes from 172.17.0.1: icmp_seq=2 ttl=64 time=0.090 ms
64 bytes from 172.17.0.1: icmp_seq=3 ttl=64 time=0.096 ms
^C
--- 172.17.0.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2115ms
rtt min/avg/max/mdev = 0.090/0.134/0.217/0.059 ms
root@ubuntu:/home/ubuntu# ip netns exec demo ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.


进入demo命名空间排查,发现回环设备也无法ping通,通过启用lo设备,问题就解决了

root@ubuntu:/home/ubuntu# ping 127.0.0.1
connect: Network is unreachable
root@ubuntu:/home/ubuntu# ping 0.0.0.0
connect: Network is unreachable
root@ubuntu:/home/ubuntu# ip link set dev lo up
root@ubuntu:/home/ubuntu# ping 0.0.0.0
PING 0.0.0.0 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.070 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.086 ms
^C
--- 0.0.0.0 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1013ms
rtt min/avg/max/mdev = 0.070/0.078/0.086/0.008 ms
root@ubuntu:/home/ubuntu# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.077 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.087 ms
^C
--- 172.17.0.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1022ms
rtt min/avg/max/mdev = 0.077/0.082/0.087/0.005 ms

发现demo网络命名空间,无法ping通外网

root@ubuntu:/home/ubuntu# ip netns exec demo ping 114.114.114.114
connect: Network is unreachable

查看路由,发现并没有匹配的路由

root@ubuntu:/home/ubuntu# ip netns exec demo route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
172.17.0.0      0.0.0.0         255.255.255.0   U     0      0        0 veth1

添加一条路由试试,enp0s2为默认网络空间的网络设备名

ip netns exec demo route add default gw 172.17.0.1
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -s 172.17.0.0/24 -o enp0s2 -j MASQUERADE



验证

root@ubuntu:/home/ubuntu# ip netns exec demo ping 114.114.114.114
PING 114.114.114.114 (114.114.114.114) 56(84) bytes of data.
64 bytes from 114.114.114.114: icmp_seq=1 ttl=58 time=13.4 ms
64 bytes from 114.114.114.114: icmp_seq=2 ttl=58 time=7.34 ms
64 bytes from 114.114.114.114: icmp_seq=3 ttl=58 time=10.7 ms

发现demo网络命名空间无法ping通百度

root@ubuntu:/home/ubuntu# ip netns exec demo ping www.baidu.com
ping: www.baidu.com: Temporary failure in name resolution

进入命名空间创建dns解析

root@ubuntu:/home/ubuntu# ip netns exec demo bash
root@ubuntu:/home/ubuntu# mkdir -p /etc/netns/demo
root@ubuntu:/home/ubuntu# vim /etc/netns/demo/resolv.conf
root@ubuntu:/home/ubuntu# cat /etc/netns/demo/resolv.conf
nameserver 114.114.114.114

在默认命名空间,执行如下命令

root@ubuntu:/home/ubuntu# strace  -f ip netns exec demo sleep 1 2>&1|egrep '/etc/|clone|mount|unshare'|egrep -vw '/etc/ld.so|access'
unshare(CLONE_NEWNS)                    = 0
mount("", "/", 0x55ebf359d725, MS_REC|MS_SLAVE, NULL) = 0
umount2("/sys", MNT_DETACH)             = 0
mount("demo", "/sys", "sysfs", 0, NULL) = 0
openat(AT_FDCWD, "/etc/netns/demo", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 5
mount("/etc/netns/demo/resolv.conf", "/etc/resolv.conf", 0x55ebf359d725, MS_BIND, NULL) = 0

发现已经可以ping通百度了

root@ubuntu:/home/ubuntu# ip netns exec demo bash
root@ubuntu:/home/ubuntu# ping www.baidu.com
PING www.a.shifen.com (36.152.44.95) 56(84) bytes of data.
64 bytes from 36.152.44.95 (36.152.44.95): icmp_seq=1 ttl=49 time=12.8 ms
64 bytes from 36.152.44.95 (36.152.44.95): icmp_seq=2 ttl=49 time=11.0 ms
64 bytes from 36.152.44.95 (36.152.44.95): icmp_seq=3 ttl=49 time=13.2 ms



上一篇:Java毕业设计+现成产品:前台预定+后台管理酒店管理系统java+SSM+jsp+mysql


下一篇:【AutoMapper官方文档】DTO与Domin Model相互转换(中)