導航:首頁 > 操作系統 > linuxtaptun

linuxtaptun

發布時間:2023-03-18 17:50:12

『壹』 TUN/TAP設備淺析(一) -- 原理淺析

TUN 設備是一種虛擬網路設備,通過此設備,程序可以方便地模擬網路行為。 TUN 模擬的是一個三層設備,也就是說,通過它可以處理來自網路層的數據,更通俗一點的說,通過它,我們可以處理 IP 數據包。

先來看看物理設備是如何工作的:

上圖中的 eth0 表示我們主機已有的真實的網卡介面 ( interface )。

網卡介面 eth0 所代表的真實網卡通過網線( wire )和外部網路相連,該物理網卡收到的數據包會經由介面 eth0 傳遞給內核的網路協議棧( Network Stack )。然後協議棧對這些數據包進行進一步的處理。

對於一些錯誤的數據包,協議棧可以選擇丟棄;對於不屬於本機的數據包,協議棧可以選擇轉發;而對於確實是傳遞給本機的數據包,而且該數據包確實被上層的應用所需要,協議棧會通過 Socket API 告知上層正在等待的應用程序。

下面看看 TUN 的工作方式:

我們知道,普通的網卡是通過網線來收發數據包的話,而 TUN 設備比較特殊,它通過一個文件收發數據包。

如上圖所示, tunX 和上面的 eth0 在邏輯上面是等價的, tunX 也代表了一個網路介面,雖然這個介面是系統通過軟體所模擬出來的.

網卡介面 tunX 所代表的虛擬網卡通過文件 /dev/tunX 與我們的應用程序(App) 相連,應用程序每次使用 write 之類的系統調用將數據寫入該文件,這些數據會以網路層數據包的形式,通過該虛擬網卡,經由網路介面 tunX 傳遞給網路協議棧,同時該應用程序也可以通過 read 之類的系統調用,經由文件 /dev/tunX 讀取到協議棧向 tunX 傳遞的 所有 數據包。

此外,協議棧可以像操縱普通網卡一樣來操縱 tunX 所代表的虛擬顫碰網卡。比如說,給 tunX 設定 IP 地址,設置路由,總之,在協議棧看來, tunX 所代表的網卡和其他普通的網卡區別不大,當然,硬要說區別,那還是有的,那就是 tunX 設備不存在 MAC 地址,這個很好理解, tunX 只模擬到了網路層,要 MAC 地址沒有任何意義。當然,如果是 tapX 的話,在協議棧的眼中, tapX 和真是網卡沒有任何區別。

如果我們使用 TUN 設備搭建一個基於 UDP VPN ,那麼整個處理過程可能是這幅樣子:

首先,我們的應用程序通過 eth0 和遠程的 UDP 程序相連,對方傳遞過來的 UDP 數據包經茄猜由左邊的協議棧傳遞給了應用程序, UDP 數據包的內容其實是一個網路層的數據包,比如說 IP 數據報,應用程序接收到該數據包的數據(剝除了各種頭部之後的 UDP 數據)之後,然後進行一定的處理,處理完成後將處理後的數據寫入文件 /dev/tunX ,這樣,數據會第二次到達協議棧。需要注意的是,上圖中繪制的兩個協議棧其實是同一個協議棧,之所顫洞型以這么畫是為了敘述的方便。

TAP 設備與 TUN 設備工作方式完全相同,區別在於:

最後,關於文章中出現的二層,三層,我這里說明一下,第一層是物理層,第二層是數據鏈路層,第三層是網路層,第四層是傳輸層。

參考文章:
[1]. https://blog.kghost.info/2013/03/27/linux-network-tun/

『貳』 計算機網路-k8s網路

K8S網路模型設計:扁平的可連通的網路

K8S的網路是一個極其復雜的網路,如果想要用兩個簡單的詞來描述K8S網路,那麼我覺得扁平和可連通是K8S網路最大的特點(不懂隔離性)。

何為連通呢?

二層網路的連通:如果能夠直接通過MAC幀直接通信的網路便是二層連通的網路,LAN就是這種網路

比如無限WIFI網路,比如乙太網

三層網路的連通:如果能夠通過IP報直接通信的網路便是三層連通的網路,便是三層連通

三層網路的連通分為兩個部分,第一個部分是三層網路中的每一個LAN都是二層連通的,其次需要存在能夠連通的路由來保證;這里可以簡單回顧下三層網路通信的流程

通過路由表確定目標ip是否在鏈路上

如果在鏈路上,通過arp協議獲取對應主機的mac地址,發送mac幀到鏈路上;

如果不在同一個鏈路上,通過本地路由表發送mac幀給下一跳,然後下一跳解析mac幀,分析ip報,繼續路由直到最終跳到目標網路再次通過mac幀發送到目標主機或者到達ttl消失。

假如其中任何一個步驟不滿足或者出問題,三層網路就無法連通

何為扁平呢?

就是希望可以在pod內直接通過IP進行互相通信而不需要在pod內部使用vpn之類的東西來連接其他pod(基礎架構化),具體的可以看下k8s對網路的設計與要求。

k8s在設計其網路時,就希望網路對運行在其中的pod是透明的,因此提出了以下的一些要求與原則

k8s組網要求

所有的Pods之間可以在不使用 NAT網路地址轉換 的情況下相互通信

所有的Nodes之間可以在不使用NAT網路地址轉換的情況下相互通信

每個Pod自己看到的自己的ip和其他Pod看到的一致

k8s網路模型設計原則

每個Pod都擁有一個獨立的 IP地址,而且 假定所有 Pod 都在一個可以直接連通的、扁平的網路空間中 。

不管它們是否運行在同 一 個 Node (宿主機)中,都要求它們可以直接通過對方的 IP 進行訪問。

設計這個原則的原因 是,用戶不需要額外考慮如何建立 Pod 之間的連接,也不需要考慮將容器埠映射到主機埠等問題。

而要想深入了解K8S的網路,就不得不去了解Linux操作系統中的網路以及計算機網路協議棧和一些網路技術

其中關於計算機網路協議棧道部分上次分享已經分享過了,所以本次的主題更多是Linux操作系統的網路以及一些網路技術

Linux操作系統中的網路

首先,我們來看下基本的linux網路,如下圖所示

一個APP生成socket數據,然後經過網路協議棧包裝IP報文,然後封裝成MAC幀,在經過網路協議棧的過程中,會存在netfilters對數據進行一定的處理,同時也會存在路由的過程,

如果在同一個物理鏈路內,將直接通過ARP協議獲取目標IP地址的MAC地址最終發送出去;

如果不在同一個物理鏈路則通過路由表確定下一跳的MAC地址,封裝成MAC幀發送到目標地址。

在這個過程中,會根據路由表選擇對應的埠,如果是lo埠,則會將幀原封不動的返回計算機網路協議棧,然後回到監聽對應埠的SOCKET里。

如果是乙太網埠則走乙太網埠,如果是藍牙或者無線網埠同理。

iptables與netfilters

iptables是一個用戶空間的應用程序,通過該程序可以修改一些配置文件,這些文件定義了防火牆的一些行為,netfilters是操作系統內核的一部分,netfilters里有5個回調鉤子會觸發iptables里的規則;iptables只是Linux防火牆的管理工具而已,位於/sbin/iptables。真正實現防火牆功能的是

netfilter,它是Linux內核中實現包過濾的內部結構。

這里不具體講述其實現的原理,僅僅列出netfilters的一些功能:

1)filter表——三個鏈:INPUT、FORWARD、OUTPUT

作用:過濾數據包 內核模塊:iptables_filter.

2)Nat表——三個鏈:PREROUTING、POSTROUTING、OUTPUT

作用:用於網路地址轉換(IP、埠) 內核模塊:iptable_nat

3)Mangle表——五個鏈:PREROUTING、POSTROUTING、INPUT、OUTPUT、FORWARD

作用:修改數據包的服務類型、TTL、並且可以配置路由實現QOS內核模塊:iptable_mangle(別看這個表這么麻煩,咱們設置策略時幾乎都不會用到它)

4)Raw表——兩個鏈:OUTPUT、PREROUTING

作用:決定數據包是否被狀態跟蹤機制處理 內核模塊:iptable_raw

虛擬網路設備 tap/tun

TUN 和 TAP 設備是 Linux 內核虛擬網路設備,純軟體實現。TUN(TUNnel)設備模擬網路層設備,處理三層報文如 IP

報文。TAP 設備模擬鏈路層設備,處理二層報文,比如乙太網幀。TUN 用於路由,而 TAP 用於創建網橋。OS 向連接到 TUN/TAP

設備的用戶空間程序發送報文;用戶空間程序可像往物理口發送報文那樣向 TUN/TAP 口發送報文,在這種情況下,TUN/TAP

設備發送(或注入)報文到 OS 協議棧,就像報文是從物理口收到一樣。

虛擬網路設備 veth-pairs

虛擬乙太網電纜。使用雙向有名管道實現。常用於不同 namespace 之間的通信,即 namespace 數據穿越或容器數據穿越。

虛擬網路設備 bridge

bridge是linux自帶的虛擬交換機(網橋),其可以連接多個乙太網設備,擁有智能處理MAC幀的能力,流向交換機的MAC幀將智能的被傳輸到相應的二層鏈路

網路命名空間

在 Linux 中,網路名字空間可以被認為是隔離的擁有單獨網路棧(網卡、路由轉發表、iptables)的環境。網路名字空間經常用來隔離網路設備和服務,只有擁有同樣網路名字空間的設備,才能看到彼此。

從邏輯上說,網路命名空間是網路棧的副本,有自己的網路設備、路由選擇表、鄰接表、Netfilter表、網路套接字、網路procfs條目、網路sysfs條目和其他網路資源。

從系統的角度來看,當通過clone()系統調用創建新進程時,傳遞標志CLONE_NEWNET將在新進程中創建一個全新的網路命名空間。

從用戶的角度來看,我們只需使用工具ip(package is iproute2)來創建一個新的持久網路命名空間。

從系統實現來說,就是原本一個數據結構是static公共的,後來變成進程私有的,在PCB里存在一個命名空間的結構,命名空間里有著網路命名空間,網路命名空間擁有著所有跟網路相關的配置數據

默認空的網路命名空間可能只有一個未啟動的lo回環網卡。

兩個網路命名空間可以通過乙太網攬直接連著兩個網路命名空間的網卡,也可以通過乙太網網橋連接。

通過乙太網網橋或者乙太網攬連接的兩個網路命名空間只能說是在二層連通的,如果希望在三層連通,還需要給每個網路命名空間配置相應的路由表規則以及分配IP地址。

如何使用虛擬網路設備聯通網路命名空間

SingleHost容器網路

none模式

本質上就是創建一個網路命名空間,裡面沒有路由表,也沒有通過veths-pair連接任何鏈路,外部無法訪問這個容器,容器也無法訪問外部

host模式

本質上就是使用宿主機的默認網路命名空間

container模式

本質上就是將當前容器部署在另一個容器所在的網路命名空間,這樣發給本地的報文最終通過回環網卡回到了本機,這是同一個網路命名空間可以互通的原因

bridge模式

橋接模式就是在這些網路命名空間通過veth-pairs連接到同一個虛擬交換機上(二層連通),同時在對應的命名空間配置對應的路由表規則,但是從圖片中可以看到交換機另一端連的上網路協議棧。

也就是那些MAC幀都會被宿主機接收,但是宿主機接收並不一定會處理,比如並沒有開啟ip轉發功能(工作於路由器模式還是主機模式),那麼不是本地ip的報文都會被丟棄;或者說netfilters拒絕處理

這些奇怪的報文。

理論上,這些容器發送給其他容器的mac報文是會被虛擬交換機智能轉發到對應的容器的,這是同一主機不同容器互相連通的原因

假如宿主機配備了相應的路由規則和防火牆規則,那麼容器的報文說能夠通過路由最終轉發出去的,這也是容器訪問互聯網的原理

但是這種模式是沒法運用在多主機的情況下,因為宿主機不知道其他宿主機里的虛擬網路的路由,當相關ip報到達宿主機時,這些ip報將會被宿主機交給默認路由(下一跳:路由器)

最終路由器會把相關的ip報丟失或者到達ttl最終丟失

MultiHost容器網路

路由方案

回顧docker的單機網路模型,我們發現多主機不能通行的原因就在於你只能給當前主機配置路由規則和防火牆規則,而其他主機並不知道這些ip在你的虛擬網路中,假如能夠將這些路由信息同步到其他

宿主機,那麼網路便會打通。比較直接的想法就是給每台宿主機配置路由規則。而路由規則要求下一跳必須在當前網路,所以假如宿主機是二層互聯的,那麼通過給這些宿主機同步這些路由規則便能夠

實現一個扁平的連通的網路。

其中布置在每一台宿主機可以通過k8s的daemonSet實現,而這種數據的管理可以交給etcd來實現。

這類方案便是基於路由,基於這個方案的實現有基於靜態路由的flannel的host-gateway,以及基於動態路由的calico(使用邊際路由協議以及一堆深奧的名詞的實現)。

下面來看看Flannel的host-gateway原理(每一台宿主機都相當於本機容器網路的路由器):

通過路由方案構建的網路,宿主機也能訪問這些虛擬網路里的Pod

詢問基德大佬得知國際化sit環境的k8s網路介面實現就是Flannel的Host-gateway,而我們的辦公網路和集群網路之間的路由是搭建好的,所以我們應該可以直接通過podId訪問pod里的服務

下面是sit環境的兩個服務

跟蹤路由發現符合猜想

其中10.1.9.56和10.1.1.24就是宿主機的ip,這些宿主機在一個LAN里,這些宿主機相當於虛擬網路中的路由器;

猜測我們辦公網和qunhe集群在一個VLAN里(二層可達)

隧道方案

隧道方案比較典型的就是UDP和XVLAN,兩者都是使用Overlay網路(覆蓋網路,所謂的大二層技術);其實用隧道技術最多的是VPN應用

其中UDP是XVLAN的替代品(早期Linux沒有支持XVLAN協議,通過tun/tap技術將流量引到用戶空間然後解包生成包再發,因為發生在用戶空間而且多次導致性能較差,所以一般不推薦,除非你的linux版本比較低沒法用xvlan)

下面就簡單介紹下XVLAN技術的大概原理,下圖是XVLAN的報文格式,可以發現就是在高層協議的報文里塞了二層報文

其中XVLAN頭里有一個關鍵的欄位,VNID這是個24位的欄位,每個虛擬的網路主機都有一個自身的VNID作為標識,理論上支持2的24次方個虛擬網路。

在docker的橋接網路里,是使用docker0網橋,在Flannel的xvlan方案里則是使用cni0作為網橋(和docker0沒啥區別),主要的不同是cni網橋後面連接的是flannel.1這個網路設備,應該是一個虛擬網卡

這個網卡將原始報文包裝成XVLAN報文(linux高版本支持xvlan報文)

這時需要的信息有 源nodeId,目標nodeId,源vnid,源macId,目標macId,源podId,目標podId

其中目標nodeId,目標macId這兩個信息是不存在的;因此需要有個方式根據目標podId獲取目標nodeId以及目標macId

因此需要記錄如何根據目標podId獲取目標macId以及目標nodeId即可

這些數據是可以託管在某個地方的,Flannel就是將這些信息記錄在etcd上

在每個node上的flannel.1網路設備通過etcd來通過對方的podId獲取nodeId和macId

這樣最終報文就變成了一個源ip是源nodeIp,目標ip是目標nodeIp的IP報文了(兩台宿主機三層可達)

原本經過虛擬網橋是直接連接網路協議棧,但在xvlan模式下,則改為連接一個flannel1,在flannel1中將對原始報文封裝成overlay報文轉發

udp模式類似,只是udp轉發報文說通過tap連通到用戶空間,用戶空間對報文進行處理然後發送(因為多次內核態用戶態切換且數據問題,性能較差,僅在不支持xvlan的低版本linux中使用)

當然xvlan是一個技術,上面只是簡單介紹最簡單的形式

參考:

開發內功修煉之網路篇: https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MjM5Njg5NDgwNA==&action=getalbum&album_id=1532487451997454337&scene=173&from_msgid=2247485270&from_itemidx=1&count=3&nolastread=1#wechat_redirect

K8S知識圖譜: https://zhaohuabing.com/post/2020-02-22-k8s-mindmap/

VXLAN協議原理簡介: https://cizixs.com/2017/09/25/vxlan-protocol-introction/

閱讀全文

與linuxtaptun相關的資料

熱點內容
如何用python寫vlookup函數 瀏覽:794
社保加密狗廠商 瀏覽:212
php編譯運行說法 瀏覽:953
程序員說喂 瀏覽:238
抖音直播雲伺服器 瀏覽:627
一加7pro文件夾data 瀏覽:424
程序員淋雨 瀏覽:947
python輸出數字序列中的空格 瀏覽:78
怎麼將pdf文件大小 瀏覽:734
氧原子相對分子量演算法 瀏覽:988
加密機為什麼是安全的 瀏覽:451
單片機拼音輸入法 瀏覽:789
蘋果筆記本t2加密晶元怎麼打開 瀏覽:796
安卓如何把手機投屏至電視 瀏覽:739
方舟編譯器現在可提速哪些軟體 瀏覽:60
微信加密為什麼是黑屏 瀏覽:473
android去電狀態 瀏覽:604
蘋果13如何加密視頻 瀏覽:815
linuxweblogic緩存 瀏覽:69
雲伺服器不同地域 瀏覽:946