Linux的網卡驅動中內含了很多“虛擬網卡”。早先的文章曾經詳細分析過tun,ifb等虛擬網卡,類似的思路,在虛擬化大行其道的趨勢下,Linux源碼樹中不斷增加對“網絡虛擬化”的支持,不光是為了支持“虛擬機”技術,更多的是給了用戶和程序員更多的選擇。
這些對網絡虛擬化的支持技術包括任何重量級的虛擬化技術,比較重的比如對虛擬機技術的支持,輕量級的則是net namespace技術。近期的工作基于net namespace技術,關于這個技術我也不多說了,它主要是提供了每個namespace獨立的協議棧以及網卡,對于網絡協議棧以及網卡之外的部分,所 有namespace是共享的,這種輕量級的針對網絡的虛擬化技術對于模擬多客戶端網絡連接特別有用而且操作簡單。我會單獨寫一篇文章來展示這種操作。
嵌入式進階教程分門別類整理好了,看的時候十分方便,由于內容較多,這里就截取一部分圖吧。
需要的朋友私信【內核】即可領取。
如果僅僅為了完成工作,那么我不會寫這篇文章,早在去年的時候,我寫過一篇關于net namespace的,根據那個里面的step by step,工作就已經可以完成了,并且在去年年末到今年年初,這個工作我們也已經做過了,然而對于學習而言,就不是這樣了。學習應該是碰到一點折騰一點, 我知道,很多人都知道,現在不比上學那會兒了,我們誰都沒有整塊的時間系統地進行學習,特別是對于我這種結了婚有了孩子,需要為了還貸款而不再任性的路人 丙來講,更是這樣。因此就需要對所碰到的技術有一種可遇而不可求的相見恨晚的感覺,這樣就有動力把它吃透了。
本文中,我想通過幾張圖來介紹一下Linux中常用的幾類和網絡虛擬化相關的虛擬網卡,當然,這些虛擬網卡的使用場景并不僅限于net namespace,重量級的虛擬機也可以使用,之所以用net namespace舉例是因為它的簡單性。總體來說,這些虛擬網卡的原理就擺在那里,具體在什么場景下使用它們,就看你自己的想象力了。
網絡虛擬化總 體來講,所謂的網絡虛擬化在本文中指的是主機中的網絡虛擬化,側重于在一臺物理主機中,分離出多個TCP/IP協議棧的意思。網絡虛擬化可以獨立實現,也 可以依托別的技術實現。在Linux中,獨立的網絡虛擬化實現就是net namespace技術,依托別的技術實現的網絡虛擬化就是虛擬機技術,我們當然知道,每個虛擬機里面都有自己的協議棧,而這種依托虛擬機技術實現的網絡 虛擬化可能還要更簡單一些,因為宿主機并不需要去“實現”一個協議棧,而是把這個任務交給了虛擬機的操作系統來完成,宿主機“相信”虛擬機里面一定運行著 一個擁有協議棧的操作系統。
理解虛擬網卡的要旨
你要知道,一塊網卡就是一道門,一個接口,它上面一般接協議棧,下面一般接介質。最關鍵的是,你要明確它們確實在上面和下面接的是什么。
由于網卡的上接口在OS中實現,或者使用PF技術在用戶態實現,總而言之,它們是軟的,這就意味著你可以任意實現它們。反之,下接口便不受機器運行軟件的 控制了,你無法通過軟件改變雙絞線的事實,不是嗎?故此,我們一般關注網卡下面接的是什么,是什么呢?姑且將它叫做endpoint吧。
在開始正文之前, 我先列舉幾個常見的endpoint:
以太網ETHx:普通雙絞線或者光纖;TUN/TAP:用戶可以用文件句柄操作的字符設備;IFB:一次到原始網卡的重定向操作;VETH:觸發虛擬網卡對兒peer的RX;VTI:加密引擎;...關于數據在宿主網卡和虛擬網卡之間的路由(廣義的路由),有很多方式,在早期的內核中,對bridge(Linux的bridge也算是一種虛擬網卡)的 支持是靠一個在netif_receive_skb中硬編碼調用的一個br_handle_frame_hook鉤子來實現的,這個鉤子由bridge模 塊注冊。
但是隨著虛擬網卡種類的越來越多,總不能每一種都硬編碼這么一種鉤子,這樣會使得netif_receive_skb顯得太臃腫,因此一種新的方 式被提出來了,事實上很簡單,就是將這種鉤子向上抽象了一層,不再硬編碼,而是統一在netif_receive_skb中調用唯一的一個 rx_handler的鉤子。
具體如何設置這種鉤子,就看這個宿主網卡需要綁定哪種類型的虛擬網卡了,比如:
對于bridge:調用netdev_rx_handler_register(dev, br_handle_frame, p),在netif_receive_skb中調用的是br_handle_frame;對于bonding:調用netdev_rx_handler_register(slave_dev, bond_handle_frame, new_slave),在netif_receive_skb中調用的是bond_handle_frame;對于MACVLAN:調用netdev_rx_handler_register(dev, macvlan_handle_frame, port),在netif_receive_skb中調用的是macvlan_handle_frame;對于IPVLAN:調用netdev_rx_handler_register(dev, ipvlan_handle_frame, port),在netif_receive_skb中調用的是ipvlan_handle_frame;對于...每一塊宿主網卡只能注冊一個rx_handler,但是網卡和網卡卻可以疊加。
VETH虛擬網卡技術關于這個虛擬網卡,我在《 Open×××多處理之-netns容器與iptables CLUSTER》 中有提到過,每一個VETH網卡都是一對兒以太網卡,除了xmit接口與常規的以太網卡驅動不同之外,其它的幾乎就是一塊標準的以太網卡。VETH網卡既 然是一對兒兩個,那么我們把一塊稱作另一塊的peer,標準上也是這么講的。其xmit的實現就是:將數據發送到其peer,觸發其peer的RX。那么 問題來了,這些數據如何發送到VETH網卡對兒之外呢?自問必有自答,自答如下:
1.如果確實需要將數據發到外部,通過將一塊VETH網卡和一塊普通ETHx網卡進行bridge,通過bridge邏輯將數據forward到ETHx,進而發出;
2.難道非要把數據包發往外部嗎?類似loopback那樣的,不就是自發自收嗎?使用VETH可以很方面并且隱秘地將數據包從一個net namespace發送到同一臺機器的另一個net namespace,并且不被嗅探到。
VETH虛擬網卡非常之簡單,原理圖如下所示:
ETH使用原始樸素的方式連接了不同的net namespace,符合UNIX的風格,因此你需要動用很多別的技術或者工具來完成net namespace的隔離以及數據的發送。
MACVLAN虛擬網卡技術MACVLAN技術可謂是提出一種將一塊以太網卡虛擬成多塊以太網卡的極簡單的方案。一塊以太網卡需要有一個MAC地址,這就是以太網卡的核心中的核心。
以往,我們只能為一塊以太網卡添加多個IP地址,卻不能添加多個MAC地址,因為MAC地址正是通過其全球唯一性來標識一塊以太網卡的,即便你使用了創建 ethx:y這樣的方式,你會發現所有這些“網卡”的MAC地址和ethx都是一樣的,本質上,它們還是一塊網卡,這將限制你做很多二層的操作。有了 MACVLAN技術,你可以這么做了。
我們先來看一下MACVLAN技術的流程示意圖:
在具體的執行上,通過下面的命令,你可以創建一個MACVLAN網卡,它是基于eth0虛擬出來的:
ip link add link eth0 name macv1 type macvlan
你 可以認為有人將雙絞線“物理上”每根一分為二,接了兩個水晶頭,從而連接了兩塊網卡,其中一塊是虛擬的MACVLAN網卡。但是既然共享介質,難道不用運 行CSMA/CD嗎?當然不用,因為事實上,最終的數據是通過eth0發出的,而現代的以太網卡工作的全雙工模式,只要是交換式全雙工(某些標準而言,這 是必須的),eth0自己能做好。
現在可以說一下MACVLAN技術構建的虛擬網卡的模式了。之所以MACVLAN擁有所謂的模式,是因為相比VETH,它更是將復雜性建立在了一個已經容 不下什么的以太網概念上,因此相互交互的元素就會太多,它們之間的關系不同,導致最終MACVLAN的行為不同。還是圖解的方式:
1.bridge模式
這 個bridge只是針對同屬于一塊宿主以太網卡的MACVLAN網卡以及宿主網卡之間的通信行為的,與外部通信無關。所謂的bridge指的是在這些網卡 之間,數據流可以實現直接轉發,不需要外部的協助,這有點類似于Linux BOX內建了一個bridge,即用brctl命令所做的那一切。
2.VEPA模式
EPA模式我后面會專門講。現在要知道的是,在VEPA模式下,即使是MACVLANeth1和MACVLANeth2同時配在在eth0上,它們兩者之間的通信也不能直接進行,而必須通過與eth0相連的外部的交換機協助,這通常是一個支持“發夾彎”轉發的交換機。
3.private模式
這 種private模式的隔離強度比VEPA更強。在private模式下,即使是MACVLANeth1和MACVLANeth2同時配在在eth0 上,eth0連接了外部交換機S,S支持“發夾彎”轉發模式,即便這樣,MACVLANeth1的廣播/多播流量也無法到達MACVLANeth2,反之 亦然,之所以隔離廣播流量,是因為以太網是基于廣播的,隔離了廣播,以太網將失去了依托。
如果你想配置MACVLAN的模式,請在ip link命令后面添加mode參數:
ip link add link eth0 name macv1 type macvlan mode bridge|vepa|private
VETH網卡與MACVLAN網卡之間的異同,我們先看一下如何配置一個獨立的net namespace。
1.VETH方式
ip netns add ns1ip link add v1 type veth peer name veth1ip link t v1 netns ns1brctl addbr br0brctl addif br0 eth0brctl addif br0 veth1ifconfig br0 192.168.0.1/16
2.MACVLAN方式
ip link add link eth0 name macv1 type macvlanip link t macv1 netns ns1
可 以看到,MACVLAN做起同樣的事,比VETH來的簡單了。那么效率呢?Linux的bridge基于軟件實現,需要不斷查找hash表,這個同樣也是 MACVLAN bridge模式的做法,但是VEPA模式和private模式下,都是直接轉發的。它們的區別可以從下圖展示出來:
VEPA技術VEPA 是什么?Virtual Ethernet Port Aggregator。它是HP在虛擬化支持領域對抗Cisco的VN-Tag的技術。所以說,Cisco的VN-Tag和VEPA旨在解決同一個問題或 者說同一類問題。解決的是什么問題呢?通俗點說,就是虛擬機之間網絡通信的問題,特別是位于同一個宿主機內的虛擬機之間的網絡通信問題。
難道這個問題沒有解決嗎?我使用的VMWare可以在我的PC中創建多個虛擬機,即便我拔掉我的PC機網線,這些虛擬機之間也能通信...VMWare內 部有一個vSwitch。就是說,幾乎所有的虛擬機技術,內置的交叉網絡都能解決虛擬機之間的通信問題。那么還要VN-Tag以及VEPA干什么?
這個問題涉及到兩個領域,一個是擴展性問題,另一個是職責邊界問題。說明白點就是,內置的vSwitch之類的東西在性能和功能上足以滿足要求嗎?它屬于 虛擬機軟件廠商的邊緣產品,甚至說不是一個獨立的產品,它一般都是附屬虛擬機軟件贈送的,沒有自己的銷售盈利模式,虛擬機廠商之所以內置它是因為它只是為 了讓用戶體驗到虛擬機之間“有相互通信的能力”,所以廠商是不會發力將這種內置的虛擬交換機或者虛擬路由器做完美的,它們推的是虛擬機軟件本身。
另外,千百年來,網絡管理員和系統管理員之間的職責邊界是清晰的,直到到達了虛擬化時代。如果使用內置的虛擬交換機,那么如果這個交換機出了故障或者有復 雜的配置任務計劃,找誰呢?要知道這個虛擬交換機內置于宿主服務器內部,這是系統管理員的領域,一般的網管設置無法觸摸到這些設備,數據中心復雜的三權分 立管理模式也無法讓網管去登錄服務器。反過來,系統管理員對網絡協議的認知程度又遠遠比不上專業網管。這就造成了內置于虛擬機軟件的虛擬網絡設備的尷尬處 境。另一方面,這個虛擬的網絡設備確實不是很專業的網絡設備。
Cisco不愧為網絡界的大咖。它總是在出現這種尷尬場景的時候率先提出一個標準,于是它改造了以太網協議,推出了VN-Tag,就像ISL之于 IEEE802.1q那樣。VN-Tag在標準的協議頭中增加了一個全新的字段,這種做法的前提是Cisco有能力用最快的速度推出一款設備并讓其真正跑 起來。在看看HP的反擊,HP沒有Cisco那樣的能力,它不會去修改協議頭,但是它可以修改協議的行為從而解決問題,雖然比Cisco晚了一步,但是 HP提出的VEPA不愧是一種更加開放的方式,Linux可以很容易的增加對其的支持。
VEPA,它很簡單,一個數據包從一個交換機的一個網口進入,然后從同一個網口發回去,好像是毫無意義的做法,但是它卻沒有改變以太網的協議頭。這種做法 在平常看來真的是毫無意義的,因為正常來講,一塊網卡連接一根網線,如果是自己發給自己的數據,那么這個數據是不會到達網卡的,對于Linux而言,直接 就被loopback給bypass了。
但是對于虛擬化場景而言,情況就有所不同了,雖然物理宿主機上可能擁有一塊以太網卡,但是從該網卡發出的數據包卻 不一定來自同一個協議棧,它可能來自不同的虛擬機或者不同的net namespace(僅針對Linux),因為在支持虛擬化OS的內部,一塊物理網卡被虛擬成了多塊虛擬網卡,每一塊虛擬網卡屬于一個虛擬機...此時, 如果不修改以太網協議頭且又沒有內置的虛擬交換機,就需要外部的一臺交換機來協助轉發,典型的就是從一個交換口收到數據包,把它從該口再發出去,由宿主網 卡決定是否接收以及如何接收。如下圖所示:
對于以太網卡而言,硬件上根本就不需要任何修改,軟件驅動修改即可,對于交換機而言,需要修改的很少,只要在MAC/Port映射表查詢失敗的情況下,將 數據包廣播到包括入口的所有端口即可,對于STP協議,也是類似的修改。對于HP而言,發出VEPA是一個正確的選擇,因為它不像Cisco和Intel 那樣,可以大量生產網卡和設備,從而控制硬件標準。對于支持VEPA的交換機而言,僅僅需要支持一種“發夾彎”的模式就可以了。爆炸!
IPVLAN虛擬網卡技術這 個小節我們來看下IPVLAN。在理解了MACVLAN之后,理解IPVLAN就十分容易了。IPVLAN和MACVLAN的區別在于它在IP層進行流量 分離而不是基于MAC地址,因此,你可以看到,同屬于一塊宿主以太網卡的所有IPVLAN虛擬網卡的MAC地址都是一樣的,因為宿主以太網卡根本不是用 MAC地址來分流IPVLAN虛擬網卡的流量的。具體的流程如下圖所示:
IPVLAN的創建命令如下:
ip link add link <master-dev> <slave-dev> type ipvlan mode { l2 | L3 }
將一個IPVLAN虛擬網卡放入一個獨立的net namespace的方式和MACVLAN完全一樣,但是它倆之間改如何作出選擇呢?好在IPVLAN有Linux源碼樹上的Document,因此我就不多嘴了:
4.1 L2 mode: In this mode TX processing happens on the stack instance attached to the slave device and packets are switched and queued to the master device to nd out. In this mode the slaves will RX/TX multicast and broadcast (if applicable) as well.4.2 L3 mode: In this mode TX processing upto L3 happens on the stack instance attached to the slave device and packets are switched to the stack instance of the master device for the L2 processing and routing from that instance will be ud before packets are queued on the outbound device. In this mode the slaves will not receive nor can nd multicast / broadcast traffic.5. What to choo (macvlan vs. ipvlan)? The two devices are very similar in many regards and the specific u ca could very well define which device to choo. if one of the following situations defines your u ca then you can choo to u ipvlan - (a) The Linux host that is connected to the external switch / router has policy configured that allows only one mac per port. (b) No of virtual devices created on a master exceed the mac capacity and puts the NIC in promiscous mode and degraded performance is a concern. (c) If the slave device is to be put into the hostile / untrusted network namespace where L2 on the slave could be changed / misud.MACVTAP虛擬網卡技術
這是本文談到的最后一種虛擬網卡。為什么會有這種虛擬網卡呢?我們還是先從問題說起。
如果一個用戶態實現的虛擬機或者模擬器,它在運行OS的時候,怎么模擬網卡呢?或者說我們實現了一個用戶態的協議棧,和內核協議棧完全獨立,你可以把它們 想象成兩個net namespace,此時如何把物理網卡的流量路由到用戶狀態呢?或者反過來,如何將用戶態協議棧發出的數據路由到BOX外部呢?按照常規的想法,我們知道 TAP網卡的endpoint是一個用戶態可訪問的字符設備,Open×××使用的就是它,很多輕量級用戶態協議棧也有用到它,我們會給出下面的方案:
又要用到“萬能的bridge”。這是多么的麻煩,這是多么的可悲。
正如MACVLAN替代VETH+Bridge一樣,稍微該一下的MACVLAN也能替代TAP+Bridge,很簡單,那就是將rx_handler實 現修改一下,宿主以太網卡收到包之后,不交給MACVLAN的虛擬網卡上接口連接的協議棧,而是發到一個字符設備隊列。很簡單吧,這就是MACVTAP!
導讀-最新發表 - 我愛內核網 - 構建全國最權威的內核技術交流分享論壇
Linux源碼樹:基于Netnamespace的虛擬網卡技術 - 論壇 - 我愛內核網 - 構建全國最權威的內核技術交流分享論壇
本文發布于:2023-02-28 20:14:00,感謝您對本站的認可!
本文鏈接:http://www.newhan.cn/zhishi/a/167766488882431.html
版權聲明:本站內容均來自互聯網,僅供演示用,請勿用于商業和其他非法用途。如果侵犯了您的權益請與我們聯系,我們將在24小時內刪除。
本文word下載地址:虛擬網卡(虛擬網卡不存在或被禁用請檢查虛擬網卡配置).doc
本文 PDF 下載地址:虛擬網卡(虛擬網卡不存在或被禁用請檢查虛擬網卡配置).pdf
| 留言與評論(共有 0 條評論) |