network namespace 实验

Posted adream307

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了network namespace 实验相关的知识,希望对你有一定的参考价值。

原文链接 : https://www.infoq.cn/article/docker-kernel-knowledge-namespace-resource-isolation


首先我们可以创建一个命名为 test_nsnetwork namespace

sudo ip netns  add test_ns

ip 命令工具创建一个 network namespace 时,会默认创建一个回环设备(loopback interface:lo),并在 /var/run/netns 目录下绑定一个挂载点,这就保证了就算 network namespace 中没有进程在运行也不会被释放,也给系统管理员对新创建的 network namespace 进行配置提供了充足的时间。

通过 ip netns exec 命令可以在新创建的 network namespace 下运行网络管理命令。

$ sudo ip netns exec test_ns ip link list
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

上面的命令为我们展示了新建的 namespace 下可见的网络链接,可以看到状态是 DOWN, 需要再通过命令去启动。可以看到,此时执行 ping 命令是无效的。

$ sudo ip netns exec test_ns ping 127.0.0.1
ping: connect: Network is unreachable

启动命令如下,可以看到启动后再测试就可以 ping 通。

$ sudo ip netns exec test_ns ip link set dev lo up
$ sudo ip netns exec test_ns ip link list
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
$ sudo ip netns exec test_ns ping 127.0.0.1
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.077 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.059 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.059 ms

这样只是启动了本地的回环,要实现与外部 namespace 进行通信还需要再建一个网络设备对,命令如下。

$ sudo ip link add veth0 type veth peer name veth1
$ sudo ip link set veth1 netns test_ns
$ sudo ip netns exec test_ns ifconfig veth1 10.1.1.1/24 up
$ sudo ifconfig veth0 10.1.1.2/24 up
$ sudo ip netns exec test_ns ifconfig
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 6  bytes 504 (504.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 6  bytes 504 (504.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

veth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.1.1.1  netmask 255.255.255.0  broadcast 10.1.1.255
        inet6 fe80::14:66ff:fee4:ba62  prefixlen 64  scopeid 0x20<link>
        ether 02:14:66:e4:ba:62  txqueuelen 1000  (Ethernet)
        RX packets 7  bytes 586 (586.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 7  bytes 586 (586.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

$ ifconfig
ens3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.122.40  netmask 255.255.255.0  broadcast 192.168.122.255
        inet6 fe80::5054:ff:fed4:2310  prefixlen 64  scopeid 0x20<link>
        ether 52:54:00:d4:23:10  txqueuelen 1000  (Ethernet)
        RX packets 1486967  bytes 517846164 (517.8 MB)
        RX errors 0  dropped 534778  overruns 0  frame 0
        TX packets 476833  bytes 118354754 (118.3 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 2404903

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 780277  bytes 131870236 (131.8 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 780277  bytes 131870236 (131.8 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

veth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.1.1.2  netmask 255.255.255.0  broadcast 10.1.1.255
        inet6 fe80::504f:e2ff:fee5:5482  prefixlen 64  scopeid 0x20<link>
        ether 52:4f:e2:e5:54:82  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

  • 第一条命令创建了一个网络设备对,所有发送到 veth0 的包 veth1 也能接收到,反之亦然。
  • 第二条命令则是把 veth1 这一端分配到 test_ns 这个 network namespace
  • 第三、第四条命令分别给 test_ns 内部和外部的网络设备配置 IPveth1IP10.1.1.1veth0IP10.1.1.2

此时两边就可以互相连通了,效果如下。

$ ping 10.1.1.1
PING 10.1.1.1 (10.1.1.1) 56(84) bytes of data.
64 bytes from 10.1.1.1: icmp_seq=1 ttl=64 time=0.169 ms
64 bytes from 10.1.1.1: icmp_seq=2 ttl=64 time=0.071 ms
64 bytes from 10.1.1.1: icmp_seq=3 ttl=64 time=0.069 ms
^C
--- 10.1.1.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2055ms
rtt min/avg/max/mdev = 0.069/0.103/0.169/0.046 ms
$ sudo ip netns exec test_ns ping 10.1.1.2
PING 10.1.1.2 (10.1.1.2) 56(84) bytes of data.
64 bytes from 10.1.1.2: icmp_seq=1 ttl=64 time=0.019 ms
64 bytes from 10.1.1.2: icmp_seq=2 ttl=64 time=0.094 ms
64 bytes from 10.1.1.2: icmp_seq=3 ttl=64 time=0.089 ms
^C
--- 10.1.1.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2040ms
rtt min/avg/max/mdev = 0.019/0.067/0.094/0.034 ms

读者有兴趣可以通过下面的命令查看,新的 test_ns 有着自己独立的路由和 iptables

$ sudo ip netns exec test_ns route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.1.1.0        0.0.0.0         255.255.255.0   U     0      0        0 veth1

$ sudo ip netns exec test_ns iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

做完这些实验,你还可以通过下面的命令删除这个 network namespace

$ sudo ip netns delete test_ns
$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 52:54:00:d4:23:10 brd ff:ff:ff:ff:ff:ff
    altname enp0s3
    inet 192.168.122.40/24 brd 192.168.122.255 scope global dynamic ens3
       valid_lft 3074sec preferred_lft 3074sec
    inet6 fe80::5054:ff:fed4:2310/64 scope link 
       valid_lft forever preferred_lft forever

以上是关于network namespace 实验的主要内容,如果未能解决你的问题,请参考以下文章

《Kubernetes网络权威指南》读书笔记 | 网络虚拟化基石:network namespace

《Kubernetes网络权威指南》读书笔记 | 网络虚拟化基石:network namespace

Kubernetes网络自学系列 | 网络虚拟化基石:network namespace

13网络--实验一(通过网桥连接两个namespace)

14网络--实验二(通过veth_pair连接两个namespace)

namespace的理解