linux網絡虛擬化: network namespace 簡介及實驗


namespace(命名空間)和cgroup是軟件容器化(想想Docker)趨勢中的兩個主要內核技術。簡單來說,cgroup是一種對進程進行統一的資源監控和限制,它控制着你可以使用多少系統資源(CPU,內存等)。而namespace是對全局系統資源的一種封裝隔離,它通過Linux內核對系統資源進行隔離和虛擬化的特性,限制了您可以看到的內容。

Linux 3.8內核提供了6種類型的命名空間:Process ID (pid)、Mount (mnt)、Network (net)、InterProcess Communication (ipc)、UTSUser ID (user)。例如,pid命名空間內的進程只能看到同一命名空間中的進程。mnt命名空間,可以將進程附加到自己的文件系統(如chroot)。在本文中,我只關注網絡命名空間 Network (net)。

網絡命名空間為命名空間內的所有進程提供了全新隔離的網絡協議棧。這包括網絡接口,路由表和iptables規則。通過使用網絡命名空間就可以實現網絡虛擬環境,實現彼此之間的網絡隔離,這對於雲計算中租戶網絡隔離非常重要,Docker中的網絡隔離也是基於此實現的,如果你已經理解了上面所說的,那么我們進入正題,介紹如何使用網絡命名空間。

准備工作以及環境:

系統:centos 7系統(因為namespace是linux 內核3.8開始支持的,所以要想進行本文的實驗,請用linux內核3.8及以上版本)

安裝iproute(yum install iproute2,其他平台請自行下載iproute2工具)

注意:本文作者使用ip命令,因為它已成為Linux中的首選網絡工具,舊的ifconfig,route等命令也已經被淘汰了。請注意,ip命令需要root權限,因此ip命名要以root用戶身份運行或預先添加sudo。

1.新增一個網絡命名空間(名稱netns1)

# ip netns add netns0

解釋:從系統的角度來看,當通過clone()系統調用創建一個新進程時,傳遞標志CLONE_NEWNET將在新進程中創建一個全新的網絡命名空間。從用戶的角度來看,我們只需使用工具ip(iproute2工具包)來創建一個新的持久網絡命名空間:此命令將創建一個名為netns0的新網絡命名空間。創建命名空間后,ip命令會在/var/run/netns目錄下增加一個netns0文件(In Linux, Everything is a File)。

# ls /var/run/netns
netns0

 

2.使用命令 ip netns show或ip netns list,列出系統中可用的命名空間:

# ip netns show
netns0

 

3.如前所述,網絡命名空間包含自己的網絡資源:接口,路由表等。默認添加網絡命名空間netns1后,在netns1命名空間中會自動添加一個loopback(回環)接口:

首先開啟回環口lo網卡

# ip netns exec netns0 ip link set lo up

 

查看網絡lo回環口信息:

# ip netns exec netns0 ip a
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

ping 127.0.0.1
# ip netns exec netns0 ping 127.0.0.1 -c 3
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.016 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.033 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.033 ms

--- 127.0.0.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1999ms
rtt min/avg/max/mdev = 0.016/0.027/0.033/0.009 ms


既然已經了解了網絡命名空間后,那我們通過兩個隔離的命名空間來實現互通(模擬兩台主機直接的互通,作為網絡開發人員,有時候需要很多台機器來測試網絡,但是只有一台機器,那么有了網絡命名空間這個特性,完全就可以在一台主機上模擬多台主機之間互通的網絡測試),如下所示:

 

 

 

 

 

# ip netns add netns1
# ip netns show
netns0
netns1

  

模擬兩台機器,這時候就需要有一根網線連接兩台主機,此時就出現了新的神器veth(虛擬以太網),veth是一種總是成對出現的虛擬網絡設備。你可以把這對看作一根物理網線,通過這根線一端發送的所有東西都會在另一端出來。(veth詳細解釋會在后續文章中詳細介紹,本文就先不詳細介紹了)

模擬創建一根網線:

# ip link add name vnet0 type veth peer name vnet1
# ip a
1: vnet1@vnet0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
  link/ether 52:42:c3:02:54:38 brd ff:ff:ff:ff:ff:ff
2: vnet0@vnet1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
  link/ether a6:20:57:dc:c6:dd brd ff:ff:ff:ff:ff:ff

 

可以看見創建了一個vnet1@vnet0和vnet0@vnet1兩張虛擬網卡,現在要把一頭插到netns0主機中,另外一套插在netns1主機中,命令如下:

# ip link set vnet0 netns netns0
# ip link set vnet1 netns netns1

  

給兩個主機分別配置ip,192.168.0.2和192.168.0.3,然后互ping

# ip netns exec netns0 ip link set vnet0 up
# ip netns exec netns1 ip link set vnet1 up
# ip netns exec netns0 ip a add 192.168.0.2 dev vnet0
# ip netns exec netns1 ip a add 192.168.0.3 dev vnet1
# ip netns exec netns0 ping 192.168.0.3
connect: 網絡不可達

  

 
網絡不可達???what??為什么會這樣?其實是因為沒有路由(查看路由命令如下)

# ip netns exec netns0 ip r

 

添加路由

# ip netns exec netns0 ip r add 192.168.0.3 dev vnet0
# ip netns exec netns1 ip r add 192.168.0.2 dev vnet1

 

在netns0中去ping netns1主機

# ip netns exec netns0 ping 192.168.0.3 -c 2
PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.
64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.021 ms
64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.047 ms

--- 192.168.0.3 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.021/0.034/0.047/0.013 ms

  

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM