鳴謝

首先於此由衷感謝上學期Linux網管務實課程的林子翔老師(亦是學長)。很幸運自己選到這門非常由內容且生動的課程,且學長和藹可親有問必答。此課程包括網路基礎的介紹、網路服務的搭建、未來網路的展望,完全學下來感覺自己也就能吸收七八成,但這七八成也帶給我很多東西了。於此希望用寒假的時間把課程作業的內容重新實作並總結收錄在blog中。

環境

OS:Debian GNU/Linux 10(buster) 虛擬化軟體:VMware workstation 16 PRO

Netns(Network namespace)介紹

A network namespace is logically another copy of the network stack, with its own routes, firewall rules, and network devices.

Netns是linux下實現網路虛擬化的功能,可以創造多個相同網路棧的隔離空間。 20210130154432

Netns之間通訊:Netns之間通訊通過Veth pair實現

The veth devices are virtual Ethernet devices. They can act as tunnels between network namespaces to create a bridge to a physical network device in another namespace, but can also be used as standalone network devices.

簡單拓撲搭建

ip netns 指令用法:

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 NETNSID := auto | POSITIVE-INT

拓撲1: 20210130154851

  • 創建netns
    1
    2
    3
    root@YoungDebian:~# ip netns add net1
    root@YoungDebian:~# ip netns ls
    net1
  • 創建Vethpair(ip link命令)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    root@YoungDebian:~# ip link add veth0 type veth peer name veth1
    root@YoungDebian:~# ip link ls
    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
    2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 00:0c:29:b0:df:a7 brd ff:ff:ff:ff:ff:ff
    3: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 42:59:b8:5c:d9:26 brd ff:ff:ff:ff:ff:ff
    4: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether ae:c7:ce:2c:c7:f2 brd ff:ff:ff:ff:ff:ff
  • 將veth1加入到net1中
    1
    2
    3
    4
    5
    6
    root@YoungDebian:~# ip link set veth1 netns net1
    root@YoungDebian:~# ip netns exec net1 ip a
    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
    3: veth1@if4: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 42:59:b8:5c:d9:26 brd ff:ff:ff:ff:ff:ff link-netnsid 0
  • 為veth pair添加IP
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    root@YoungDebian:~# ifconfig veth0 10.0.0.1/24 up
    root@YoungDebian:~# ip a | grep "veth0"
    4: veth0@if3: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state LOWERLAYERDOWN group default qlen 1000
    inet 10.0.0.1/24 brd 10.0.0.255 scope global veth0
    root@YoungDebian:~# ip netns exec net1 ifconfig veth1 10.0.0.2/24 up
    root@YoungDebian:~# ip netns exec net1 ip a
    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
    3: veth1@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 42:59:b8:5c:d9:26 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.0.0.2/24 brd 10.0.0.255 scope global veth1
    valid_lft forever preferred_lft forever
    inet6 fe80::4059:b8ff:fe5c:d926/64 scope link
    valid_lft forever preferred_lft forever
  • 測試veth pair之間連通情況
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    root@YoungDebian:~# ping 10.0.0.2
    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.027 ms
    64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.135 ms
    64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=0.067 ms
    ^C
    --- 10.0.0.2 ping statistics ---
    3 packets transmitted, 3 received, 0% packet loss, time 33ms
    rtt min/avg/max/mdev = 0.027/0.076/0.135/0.045 ms
    root@YoungDebian:~# ip netns exec net1 ping 10.0.0.1
    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.025 ms
    64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=0.063 ms
    64 bytes from 10.0.0.1: icmp_seq=3 ttl=64 time=0.066 ms
    ^C
    --- 10.0.0.1 ping statistics ---
    3 packets transmitted, 3 received, 0% packet loss, time 38ms
    rtt min/avg/max/mdev = 0.025/0.051/0.066/0.019 ms
  • 讓Netns與對外網卡連通(將默認路由設在veth pair另一頭)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    root@YoungDebian:~# ip netns exec net1 route add default gw 10.0.0.1
    root@YoungDebian:~# ip netns exec net1 netstat -rn
    Kernel IP routing table
    Destination Gateway Genmask Flags MSS Window irtt Iface
    0.0.0.0 10.0.0.1 0.0.0.0 UG 0 0 0 veth1
    10.0.0.0 0.0.0.0 255.255.255.0 U 0 0 0 veth1
    root@YoungDebian:~# ip netns exec net1 ping 192.168.11.128
    PING 192.168.11.128 (192.168.11.128) 56(84) bytes of data.
    64 bytes from 192.168.11.128: icmp_seq=1 ttl=64 time=0.112 ms
    64 bytes from 192.168.11.128: icmp_seq=2 ttl=64 time=0.068 ms
    64 bytes from 192.168.11.128: icmp_seq=3 ttl=64 time=0.065 ms
    ^C
    --- 192.168.11.128 ping statistics ---
    3 packets transmitted, 3 received, 0% packet loss, time 42ms
    rtt min/avg/max/mdev = 0.065/0.081/0.112/0.023 ms

拓撲2: 20210130164018 多個netns之間的通訊可以通過bridge實現,不用維護過多的vethpair * 創建netns與vethpair與bridge

1
2
3
4
5
6
7
8
root@YoungDebian:~# ip netns add net1
root@YoungDebian:~# ip netns add net2
root@YoungDebian:~# ip netns add net3
root@YoungDebian:~# ip link add veth0 type veth peer name veth1
root@YoungDebian:~# ip link add veth2 type veth peer name veth3
root@YoungDebian:~# ip link add veth4 type veth peer name veth5
root@YoungDebian:~# ip link add br0 type bridge
root@YoungDebian:~# ip link set dev br0 up
* 將vethpair的一端放置於namespace中並賦予ip
1
2
3
4
5
6
root@YoungDebian:~# ip link set veth0 netns net1
root@YoungDebian:~# ip link set veth2 netns net2
root@YoungDebian:~# ip link set veth4 netns net3
root@YoungDebian:~# ip netns exec net1 ifconfig veth0 10.0.1.1/24 up
root@YoungDebian:~# ip netns exec net2 ifconfig veth2 10.0.1.2/24 up
root@YoungDebian:~# ip netns exec net3 ifconfig veth4 10.0.1.3/24 up
* 將vethpair的另一端置於bridge中
1
2
3
4
5
6
root@YoungDebian:~# ip link set dev veth1 master br0
root@YoungDebian:~# ip link set dev veth3 master br0
root@YoungDebian:~# ip link set dev veth5 master br0
root@YoungDebian:~# ip link set dev veth1 up
root@YoungDebian:~# ip link set dev veth3 up
root@YoungDebian:~# ip link set dev veth5 up
* 測試netns之間的連通性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
root@YoungDebian:~# ip netns exec net1 ping 10.0.1.2
PING 10.0.1.2 (10.0.1.2) 56(84) bytes of data.
64 bytes from 10.0.1.2: icmp_seq=1 ttl=64 time=0.144 ms
64 bytes from 10.0.1.2: icmp_seq=2 ttl=64 time=0.086 ms
^C
--- 10.0.1.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 43ms
rtt min/avg/max/mdev = 0.086/0.115/0.144/0.029 ms
root@YoungDebian:~# ip netns exec net1 ping 10.0.1.3
PING 10.0.1.3 (10.0.1.3) 56(84) bytes of data.
64 bytes from 10.0.1.3: icmp_seq=1 ttl=64 time=0.161 ms
64 bytes from 10.0.1.3: icmp_seq=2 ttl=64 time=0.090 ms
^C
--- 10.0.1.3 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 16ms
rtt min/avg/max/mdev = 0.090/0.125/0.161/0.037 ms
root@YoungDebian:~# ip netns exec net2 ping 10.0.1.3
PING 10.0.1.3 (10.0.1.3) 56(84) bytes of data.
64 bytes from 10.0.1.3: icmp_seq=1 ttl=64 time=0.114 ms
64 bytes from 10.0.1.3: icmp_seq=2 ttl=64 time=0.075 ms
^C
--- 10.0.1.3 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 17ms
rtt min/avg/max/mdev = 0.075/0.094/0.114/0.021 ms

後記

簡單的拓撲搭建為後邊使用netns做網路實驗打下基礎。Netns虛擬化的特性可以為後續的實驗提供方便,docker也是使用Netns實現網路資源之間的隔離。

擴充資料: * Linux Namespace:https://man7.org/linux/man-pages/man7/namespaces.7.html * Linux Bridge:https://wiki.linuxfoundation.org/networking/bridge