新聞中心
作者 | 中國移動云能力中心PaaS產(chǎn)品部 張永曦

創(chuàng)新互聯(lián)建站秉承實現(xiàn)全網(wǎng)價值營銷的理念,以專業(yè)定制企業(yè)官網(wǎng),成都網(wǎng)站設計、網(wǎng)站建設、外貿(mào)網(wǎng)站建設,重慶小程序開發(fā),網(wǎng)頁設計制作,手機網(wǎng)站開發(fā),全網(wǎng)整合營銷推廣幫助傳統(tǒng)企業(yè)實現(xiàn)“互聯(lián)網(wǎng)+”轉(zhuǎn)型升級專業(yè)定制企業(yè)官網(wǎng),公司注重人才、技術和管理,匯聚了一批優(yōu)秀的互聯(lián)網(wǎng)技術人才,對客戶都以感恩的心態(tài)奉獻自己的專業(yè)和所長。
01知識儲備
首先,我們提前熱身一下,學一點網(wǎng)絡基礎知識。
1.1 網(wǎng)絡命名空間
維基百科的定義是這樣的“Network namespaces virtualize the network stack”,意思就是說linux network namespace對network stack做了虛擬化。什么是network stack呢?網(wǎng)絡棧包括了網(wǎng)卡(network interface),回環(huán)設備(loopback device),路由表(routing tables)和iptables規(guī)則。打個比方,當你登錄一臺linux服務器時,你默認用的就是Host網(wǎng)絡棧。
1.2 網(wǎng)橋設備
網(wǎng)橋是在內(nèi)核中虛擬出來的,可以將主機上真實的物理網(wǎng)卡(如eth0,eth1),或虛擬的網(wǎng)卡橋接上來。橋接上來的網(wǎng)卡就相當于網(wǎng)橋上的端口,端口收到的數(shù)據(jù)包都提交給這個虛擬的“網(wǎng)橋”,讓其進行轉(zhuǎn)發(fā)。
1.3 對設備
Veth Pair設備被創(chuàng)建出來后,總是以兩個虛擬網(wǎng)卡(Veth Peer)的形式成對出現(xiàn),其中一張“網(wǎng)卡”發(fā)出的數(shù)據(jù)包可以直接在出現(xiàn)在對應的“網(wǎng)卡”上。Veth Pair常用作連接不同Network Namespace的網(wǎng)線。
1.4 VXLAN
VXLAN(Virtual extensible Local Area Network,虛擬擴展局域網(wǎng)),是由IETF定義的NVO3(Network Virtualization over Layer 3)標準技術之一,是對傳統(tǒng)VLAN協(xié)議的一種擴展。VXLAN的特點是將L2的以太幀封裝到UDP報文(即L2 over L4)中,并在L3網(wǎng)絡中傳輸。
VXLAN本質(zhì)上是一種隧道技術,在源網(wǎng)絡設備與目的網(wǎng)絡設備之間的IP網(wǎng)絡上,建立一條邏輯隧道,將用戶側報文經(jīng)過特定的封裝后通過這條隧道轉(zhuǎn)發(fā)。從用戶的角度來看,接入網(wǎng)絡的服務器就像是連接到了一個虛擬的二層交換機的不同端口上,可以方便地通信。
1.5 BGP(邊界網(wǎng)關協(xié)議)
邊界網(wǎng)關協(xié)議(Border Gateway Protocol,縮寫:BGP)是互聯(lián)網(wǎng)上一個核心的去中心化自治路由協(xié)議。它通過維護IP路由表或“前綴”表來實現(xiàn)自治系統(tǒng)(AS)之間的可達性,屬于矢量路由協(xié)議。BGP不使用傳統(tǒng)的內(nèi)部網(wǎng)關協(xié)議(IGP)的指標,而使用基于路徑、網(wǎng)絡策略或規(guī)則集來決定路由。
02什么是微服務的可觀測性單機容器網(wǎng)絡
好了,經(jīng)過上一章的熱身,大家對網(wǎng)絡基礎知識應該有了大致的了解。那么咱們接下來先嘗試探索一下單機容器網(wǎng)絡模型,這也是docker默認使用的單機容器網(wǎng)絡模型。
圖1 宿主機上不同容器通過網(wǎng)橋進行互通
單機容器網(wǎng)絡的示意圖如圖1,圖中給出了如下幾個關鍵點:
- 每個容器(Container)分別擁有自己的Network Namespace。
- 容器通過對設備,連接到宿主機的Host Network Namespace。對設備在容器Network Namespace這一端的“網(wǎng)卡”是eth0,eth0配置的ip即容器的ip。對設備連接Host Namespace的那一端掛載到網(wǎng)橋設備docker0。
- 網(wǎng)橋設備docker0,掛載著所有容器的對設備的Host Namespace這一端。并且,掛載在網(wǎng)橋上的設備,會被降級成網(wǎng)橋上的一個端口,端口的唯一作用就是轉(zhuǎn)發(fā)網(wǎng)橋或另一端對設備的數(shù)據(jù)包。
- 從Container1發(fā)送到Container2的數(shù)據(jù)包,首先經(jīng)過Container1中的eth0,到達docker0網(wǎng)橋,docker0網(wǎng)橋經(jīng)過二層轉(zhuǎn)發(fā),將數(shù)據(jù)包發(fā)送到Container2對應的端口(Container2對設備的docker0網(wǎng)橋這一端),這樣數(shù)據(jù)包就被直接送到Container2中了。
上述就是單機容器網(wǎng)絡的基本原理,在對單機容器網(wǎng)絡模型有了初步的認識后,接下來我們進入正題,開始對K8S網(wǎng)絡模型的探索。
03K8S網(wǎng)絡模型
接觸過K8S的同學,大致都聽說過Flannel和Calico兩種網(wǎng)絡模型。但是,這兩種網(wǎng)絡模型具體是什么樣子,工作原理是什么,可能很多同學就比較困惑了。沒關系,接下來我們就開始對k8S網(wǎng)絡模型的探索吧!
3.1 Flannel網(wǎng)絡模型
在上一章中,介紹了單機容器網(wǎng)絡的原理。那么,要理解容器如何“跨主機通信”的原理,一定要從Flannel這個項目說起。Flannel項目是CoreOS公司推出的容器網(wǎng)絡方案,目前它支持三種后端實現(xiàn):
- UDP
- VXLAN
- Host-gw
3.1.1 Flannel-UDP
UPD模式Flannel最早實現(xiàn)的一種方式,也是性能最差的,目前已被棄用。但是這種方式也是最直接,最容易理解的方式,所以我們從這種方式開始介紹。
圖2 Flannel-UDP模式跨主機通信示意圖
圖2是Flannel-UDP模式的原理圖。與單機容器網(wǎng)絡相比,這里新增了一個flannel0設備和flanneld進程。flannel0設備是一個TUN設備,它的作用非常簡單,就是在系統(tǒng)內(nèi)核和用戶應用程序之間傳包;flanneld進程的職責,就是封裝和解封裝。數(shù)據(jù)包是如何從Node1中的container-1容器發(fā)送到Node2的container-2容器的呢?
- 數(shù)據(jù)包從container-1,來到了網(wǎng)橋docker0上,由于數(shù)據(jù)包的目的地址不屬于網(wǎng)橋的網(wǎng)段,所以數(shù)據(jù)包經(jīng)由docker0網(wǎng)橋,出現(xiàn)在宿主機上。
- 在宿主機的路由表中,去往100.96.0.0/16網(wǎng)段的包經(jīng)由flannel0處理。flannel0收到數(shù)據(jù)包之后,將數(shù)據(jù)包送到flanneld進程,flanneld進程會對數(shù)據(jù)包封裝成一個UDP數(shù)據(jù)包,src和dst地址分別為兩個容器對應的宿主機的地址。這樣,數(shù)據(jù)包就可以到達Node2了。
- 數(shù)據(jù)包到達Node2的8285端口,即Node2上的flanneld進程,會被執(zhí)行解封裝操作,之后數(shù)據(jù)包被發(fā)送到TUN設備,即flannel0設備。剩下的事情就簡單了,數(shù)據(jù)包經(jīng)過docker0網(wǎng)橋到達container-2。
3.1.2 Flannel-VXLAN
經(jīng)過上一小節(jié)的介紹,大家對Flannel-UDP模式大致了解了吧,那聰明的你們已經(jīng)猜到為什么Flannel-UDP被棄用了吧?沒錯,因為效率太低了,數(shù)據(jù)包每次經(jīng)過flannel0設備,都會經(jīng)過內(nèi)核態(tài)-用戶態(tài)-內(nèi)核態(tài)的這一頓折騰。
圖3 TUN設備示意圖
那有沒有辦法不要這么折騰呢?有,F(xiàn)lannel-VXLAN方案就解決了這個問題。Flannel-VXLAN方案用VXLAN技術替代了flannel0設備,讓數(shù)據(jù)包能夠在內(nèi)核態(tài)上實現(xiàn)數(shù)據(jù)包的封裝和解封裝。
圖4 Flannel-VXLan 網(wǎng)絡模型示意圖
Flannel-VXLan 網(wǎng)絡模型的原理如圖4所示,你會發(fā)現(xiàn),這和Flannel-UDP基本上的是一樣。事實也的確如此,F(xiàn)lannel-VXLAN是Flannel-UDP的升級版。這里需要交代一下他們之間的不同點。
- Flannel-UDP的TUN設備flannel0,升級成了VXLAN的VTEP設備。數(shù)據(jù)包的封裝和解封裝在內(nèi)核態(tài)就能完成。
- 數(shù)據(jù)包的格式中,增加了VXLAN Header,這個Header的作用和Flannel-UDP的數(shù)據(jù)包中的dport:8285的作用是一樣的,當數(shù)據(jù)包來到Node2時,操作系統(tǒng)能根據(jù)VXLAN Header,把數(shù)據(jù)包直接給到flannel.1設備。
3.1.3 Flannel-host-gw
此時,聰明的你肯定會說,F(xiàn)lannel-VXLAN雖然效率提高了,但是還是用到了隧道技術,效率還是會受到影響,能不能不用隧道技術呢?答案是能。接下來我們繼續(xù)探索Flannel-host-gw網(wǎng)絡模型,一個基于三層的網(wǎng)絡方案。老規(guī)矩,上圖。
圖5 Flannel-host-gw網(wǎng)絡模型示意圖
圖5是Flannel-host-gw網(wǎng)絡模型,相比較之前的兩個網(wǎng)絡模型,隧道設備確實沒有了,取而代之的是一堆路由規(guī)則。那,數(shù)據(jù)包又是怎么從container1到container2的呢?
- 當數(shù)據(jù)包從container1到了網(wǎng)橋之后,通過Host網(wǎng)絡棧的路由表,發(fā)現(xiàn)去container2的路已經(jīng)指明,經(jīng)由eth0,達到Node2(10.168.0.3/24)即可。
- 當數(shù)據(jù)包到了Node2之后,通過Host網(wǎng)絡棧的路由表,找到cni0網(wǎng)橋,container2自然也就找到了。
肉眼可見,F(xiàn)lannel-host-gw的性能確實提高了很多,那為什么還要用Flannel-VXLAN呢?原因很明顯,F(xiàn)lannel-host-gw只支持宿主機在二層連通的網(wǎng)絡,并且,K8S的規(guī)模不能太大,否則每臺機器的路由表就太多了。
3.2 Calico網(wǎng)絡模型
經(jīng)過上一小節(jié)的介紹,大家對Flannel應該有個大致的了解了??赡苡腥藭枺薋lannel,K8S還有別的網(wǎng)絡模型么。當然有了,下面我們開始探索Calico網(wǎng)絡模型。
3.2.1 Calico(非IPIP模式)
實際上Calico網(wǎng)絡模型的解決方案,幾乎和Flannel-host-gw是一樣的。不同的是Flannel-host-gw使用etcd來維護主機的路由表,而Calico則使用BGP(邊界網(wǎng)關協(xié)議)來維護主機的路由表。BGP協(xié)議的定義看著有點高深,換成通俗的說法,大家可以理解為在每個邊界網(wǎng)關都會都運行著一個小程序,它們會交換各自的路由信息,將需要的信息更新到自己的路由表里。BGP這個能力正好可以取代Flannel-host-gw利用Etcd維護主機上路由表的功能,并且更為強大。
除了BGP之外,Calico另外一個不同之處就在于它不需要維護一個網(wǎng)橋,Calico網(wǎng)絡模型如6所示:
圖6 Calico網(wǎng)絡模型示意圖
圖6是Calico網(wǎng)絡模型示意圖,其中BGP Client和Felix的作用是和K8S集群其他節(jié)點交換路由信息,并更新Host網(wǎng)絡棧的路由信息。
由于沒有了網(wǎng)橋設備,每個對設備Host網(wǎng)絡棧的這一端,需要配置一條路由規(guī)則,將目的地址為對應Container的數(shù)據(jù)包轉(zhuǎn)入該對設備。對應的路由如下所示:
10.233.1.2 dev cali9c02e56 scope link
數(shù)據(jù)包是如何從Container1走到Container3的呢?過程基本上和Flannel-host-gw無異了。唯一區(qū)別就是數(shù)據(jù)包進出容器,不再依賴網(wǎng)橋,而是直接通過宿主機路由表找到容器的另一端對設備。
3.2.2 Calico(IPIP模式)
Calico聽著挺強大的,實則和Flannel-host-gw一樣,只支持宿主機二層聯(lián)通的情況。假設Container1和Container3的宿主機在不同的子網(wǎng),那通過二層網(wǎng)絡是無法將數(shù)據(jù)包傳到下一跳的地址的。如圖7所示,Calico會在Node1創(chuàng)建這樣一條路由規(guī)則:
10.233.2.0/16 via 192.168.2.2 eth0
此時問題就出現(xiàn)了,下一跳是192.168.2.2,和Node1不在一個子網(wǎng)里,根本就找不到。
圖7 Calico(IPIP模式)網(wǎng)絡模型示意圖
Calico的IPIP模式解決了上述問題,在每一臺宿主機上,都會增加一個tunl0設備(IP隧道設備),并且會對應增加如下一條路由策略:
10.233.2.0/16 via 192.168.2.2 tunl0
這樣一來,Container1去往Container3的數(shù)據(jù)包就會經(jīng)過tunl0設備的處理,tunl0設備會在源IP報頭之外新增一個外部IP報頭,拿本例來說,這個外部IP報頭的src和dst分別為Node1和Node2的IP,這樣,數(shù)據(jù)包就偽裝成了從Node1發(fā)到Node2的數(shù)據(jù)包。當數(shù)據(jù)包到達Node2之后,Node2上的tunl0會把外部IP報頭拿掉,從而拿到原始的IP包。
我知道,聰明的你此時肯定會有一個更好的想法,為什么不在Router1和Router2上也用BGP協(xié)議的方式,同步容器的IP路由信息呢?這樣宿主機上不就可以不用tunl0設備了么。這個方法確實很好,并且在一些場景也得到了應用。
03CNI網(wǎng)絡插件
最后,我再介紹一下CNI網(wǎng)絡插件。CNI(Container Network Interface)顧名思義,是K8S的網(wǎng)絡接口。這個接口的作用就是當K8S的 kubelet創(chuàng)建Pod時,dockershim會預先調(diào)用Docker API創(chuàng)建并啟動Infra容器,執(zhí)行SetUpPod的方法。這個方法會為CNI網(wǎng)絡插件準備參數(shù)和環(huán)境變量,然后調(diào)用CNI插件為Infra容器配置網(wǎng)絡。CNI網(wǎng)絡插件僅需實現(xiàn)ADD和DEL兩種方法,分別對應Pod加入K8S網(wǎng)絡,以及Pod移出K8S網(wǎng)絡。
用大白話再解釋一遍,就是當Pod創(chuàng)建時,需要對網(wǎng)絡進行一些設置,包括前邊的提到的創(chuàng)建對設備,把對設備的一端掛載到網(wǎng)橋上,添加Pod以及主機的Network Namespace的路由規(guī)則等,這些操作當然可以由運維人員手動完成(不嫌累的話),CNI網(wǎng)絡插件就是一個腳本,自動對網(wǎng)絡進行設置。
Flannel和Calico各自都有專門的CNI插件,大家可以去Github上研究一下源碼,并親自部署一下試試。這里就不多介紹了,畢竟看再多的資料,都不如自己動手實踐一遍理解得深刻。?
網(wǎng)頁標題:二十分鐘了解K8S網(wǎng)絡模型原理
路徑分享:http://fisionsoft.com.cn/article/dpgdhsi.html


咨詢
建站咨詢
