在 Linux 中,網絡名字空間能夠被認爲是隔離的擁有單獨網絡棧(網卡、路由轉發表、iptables)的環境。網絡名字空間常常用來隔離網絡設備和服務,只有擁有一樣網絡名字空間的設備,才能看到彼此。linux
●Bridge網絡
Bridge和現實世界中的二層交換機有一個區別:數據被直接發到Bridge上,而不是從一個端口接受。這種狀況能夠看作Bridge本身有一個MAC能夠主動發送報文,或者說Bridge自帶了一個隱藏端口和寄主 Linux 系統自動鏈接,Linux 上的程序能夠直接從這個端口向 Bridge 上的其餘端口發數據。因此當一個 Bridge 擁有一個網絡設備時,如 bridge0 加入了 eth0 時,實際上 bridge0 擁有兩個有效 MAC 地址,一個是 bridge0 的,一個是 eth0 的,他們之間能夠通信。spa
由此帶來一個有意思的事情是,Bridge 能夠設置 IP 地址。一般來講 IP 地址是三層協議的內容,不該該出如今二層設備 Bridge 上。可是 Linux 裏 Bridge 是通用網絡設備抽象的一種,只要是網絡設備就可以設定 IP 地址。當一個 bridge0 擁有 IP 後,Linux 即可以經過路由表或者IP表規則在三層定位bridge0,此時至關於Linux擁有了另一個隱藏的虛擬網卡和 Bridge 的隱藏端口相連,這個網卡就是名爲bridge0的通用網絡設備,IP能夠當作是這個網卡的。當有符合此 IP 的數據到達bridge0 時,內核協議棧認爲收到了一包目標爲本機的數據,此時應用程序能夠經過 Socket接收到它。.net
一個更好的對比例子是:現實世界中的帶路由的交換機設備,它也擁有一個隱藏的 MAC 地址,供設備中的三層協議處理程序和管理程序使用。設備裏的三層協議處理程序,對應名爲 bridge0 的通用網絡設備的三層協議處理程序,即寄主Linux系統內核協議棧程序。設備裏的管理程序,對應bridge0寄主Linux系統裏的應用程序。3d
Bridge 的實現當前有一個限制:當一個設備被 attach 到 Bridge 上時,那個設備的 IP 會變的無效,Linux 再也不使用那個 IP 在三層接受數據。舉例以下:若是 eth0 原本的 IP 是 192.168.1.2,此時若是收到一個目標地址是 192.168.1.2 的數據,Linux 的應用程序能經過 Socket 操做接受到它。而當 eth0 被 attach 到一個 bridge0 時,儘管 eth0 的 IP 還在,但應用程序是沒法接受到上述數據的。此時應該把 IP 192.168.1.2 賦予 bridge0。blog
另外須要注意的是:數據流的方向。對於一個被attach到Bridge上的設備來講,只有它收到數據時,此包數據纔會被轉發到Bridge上,進而完成查表廣播等後續操做。當請求是發送類型時,數據是不會被轉發到 Bridge 上的,它會尋找下一個發送出口。用戶在配置網絡時常常忽略這一點從而形成網絡故障。ip
●TAP 設備與 VETH 設備路由
TUN/TAP 設備是一種讓用戶態程序向內核協議棧注入數據的設備,一個工做在三層,一個工做在二層,使用較多的是 TAP 設備。VETH設備出現較早,它的做用是反轉通信數據的方向,須要發送的數據會被轉換成須要收到的數據從新送入內核網絡層進行處理,從而間接的完成數據的注入。it
當一個TAP設備被建立時,在Linux設備文件目錄下將會生成一個對應char設備,用戶程序能夠像打開普通文件同樣打開這個文件進行讀寫。當執行 write()操做時,數據進入 TAP 設備,此時對於 Linux 網絡層來講,至關於 TAP 設備收到了一包數據,請求內核接受它,table
如同普通的物理網卡從外界收到一包數據同樣,不一樣的是其實數據來自Linux上的一個用戶程序。Linux收到此數據後將根據網絡配置進行後續處理,從而完成了用戶程序向Linux內核網絡層注入數據的功能。當用戶程序執行read()請求時,至關於向內核查詢 TAP 設備上是否有須要被髮送出去的數據,有的話取出到用戶程序裏,完成 TAP 設備的發送數據功能。
針對 TAP 設備的一個形象的比喻是:使用 TAP 設備的應用程序至關於另一臺計算機,
TAP 設備是本機的一個網卡,他們之間相互鏈接。應用程序經過 read()/write()操做,
和本機網絡核心進行通信。
VETH 設備老是成對出現,送到一端請求發送的數據老是從另外一端以請求接受的形式出現。
該設備不能被用戶程序直接操做,但使用起來比較簡單。建立並配置正確後,向其一端輸入數據,VETH 會改變數據的方向並將其送入內核網絡核心,完成數據的注入。在另外一端能讀到此數據。
●netns
netns是在linux中提供網絡虛擬化的一個項目,使用netns網絡空間虛擬化能夠在本地虛擬化出多個網絡環境,目前netns在lxc容器中被用來爲容器提供網絡。
使用netns建立的網絡空間獨立於當前系統的網絡空間,其中的網絡設備以及iptables規則等都是獨立的,就好像進入了另一個網絡同樣。不一樣網絡命名空間中的設備是不一樣的,之間不能互相直接通信。
//下述建立的網絡命名空間,重啓後,失效。
linux默認的網絡命名空間時root 命名空間。建立新命名空間nstest的步驟以下:
1,建立命名空間
ip netns add nstest
2,查看命名空間
ip netns OR ip netns list
3,在此命名空間中,執行命令查看網卡
ip netns exec nstest ip a
4,若是網卡未被啓用,就啓用。
ip netns exec nstest ip link set lo up
5,查看netns命名空間下的route表。
ip netns exec nstest route //路由表是空的
6,查看netns命名空間下的防火牆規則。
ip netns exec nstest iptables -nL //以下沒有任何規則
7,netns網絡命名空間下執行ping命令。
ip netns exec nstest ping 10.20.0.250 //此時網絡不通。
●創建虛擬網卡對(virtual ethernet peer),使命名空間netns和root命名空間聯通。
1,建立一個虛擬網卡對vethp。(兩個接頭:tap-nstest,tap-root),默認是在root命名空間中建立的,在nstest空間中是看不到的。
ip link add tap-nstest type veth peer name tap-root // tap設備,類型爲veth
2, 在root命名空間中查看網卡,能夠看到新增了建立的虛擬網卡對的tap設備tap-nstest和tap-root。
ip a
3,查看兩個tap設備是不是成對的關係。若是是成對的,它們的peer_ifindex應該是連續的。
ethtool -S tap-root
ethtool -S tap-nstest
●將tap設備分別分配到兩個網絡命名空間,達到聯通的做用。
4,將tap-nstest分配到nstest命名空間中。分配後,在root命名空間中就看不到了。
ip link set tap-nstest netns nstest //能夠查看ip netns exec nstest ip a
5,爲tap-nstest添加一個ip地址
ip netns exec nstest ip addr add 192.168.10.2/24 dev tap-nstest
ip netns exec nstest ip link set tap-nstest up
6,查看nstest空間中的網卡信息
ip netns exec nstest ip a
7,爲root命名空間中的tap-root添加ip
ip addr add 192.168.10.1/24 dev tap-root //刪除命令:ip del add 192.168.10.1/24 dev tap-root
ip link set tap-root up
8,查看網絡是否聯通。
ping 192.168.10.2
ip netns exec nstest ping 192.168.10.1
●一個帶網橋的配置例:
建立虛擬網絡環境而且鏈接網線
ip netns add net0
ip netns add net1
ip netns add bridge
ip link add type veth
ip link set dev veth0 name net0-bridge netns net0
ip link set dev veth1 name bridge-net0 netns bridge
ip link add type veth
ip link set dev veth0 name net1-bridge netns net1
ip link set dev veth1 name bridge-net1 netns bridge
在bridge中建立而且設置br設備
ip netns exec bridge brctl addbr br
ip netns exec bridge ip link set dev br up
ip netns exec bridge ip link set dev bridge-net0 up
ip netns exec bridge ip link set dev bridge-net1 up
ip netns exec bridge brctl addif br bridge-net0
ip netns exec bridge brctl addif br bridge-net1
•而後配置兩個虛擬環境的網卡
ip netns exec net0 ip link set dev net0-bridge up
ip netns exec net0 ip address add 10.0.1.1/24 dev net0-bridge
ip netns exec net1 ip link set dev net1-bridge up
ip netns exec net1 ip address add 10.0.1.2/24 dev net1-bridge
可參看:https://blog.csdn.net/zhanglidn013/article/details/70241732https://blog.csdn.net/qq_21127151/article/details/79370736