第6章 簡潔的服務(wù)模型

6.1 服務(wù)的本質(zhì)是什么

K8s集群的服務(wù),其實(shí)就是負(fù)載均衡或反向代理。這跟阿里云的負(fù)載均衡有很多類似的地方、和負(fù)載均衡一樣,服務(wù)有它的IP地址以及前端端口,同時(shí)服務(wù)后面會掛載多個容器組作為其“后端服務(wù)器”,這些“后端服務(wù)器”有自己的IP地址以及監(jiān)聽端口。如下圖所示。

當(dāng)這樣的負(fù)載均衡和后端的架構(gòu)與K8s集群結(jié)合的時(shí)候,我們可以想到的最直觀的實(shí)現(xiàn)方式,就是集群中某一個節(jié)點(diǎn)專門做負(fù)載均衡(類似Linux虛擬服務(wù)器)的角色,見圖6-2,而其他節(jié)點(diǎn)則用來承載后端容器組。

這樣的實(shí)現(xiàn)方法有一個巨大的缺陷,就是單點(diǎn)問題。K8s集群是Google多年來自動化運(yùn)維實(shí)踐的結(jié)晶,這樣的實(shí)現(xiàn)顯然與其自動化運(yùn)維的哲學(xué)背離。

6.2 自帶通信員

邊車(sidecar)模式是微服務(wù)領(lǐng)域的核心概念。邊車模式換一個通俗一點(diǎn)的說法,就是自帶通信員模式。如圖6-3所示。

在K8s集群中,服務(wù)的實(shí)現(xiàn)實(shí)際上是為每一個集群節(jié)點(diǎn)部署了一個反向代理sidecar、而所有對集群服務(wù)的訪問,都會被節(jié)點(diǎn)上的反向代理轉(zhuǎn)換成對服務(wù)后端容器組的訪問?;旧?,節(jié)點(diǎn)和這些sidecar的關(guān)系如圖6-4所示。

6.3 讓服務(wù)照進(jìn)現(xiàn)實(shí)

K8s集群的服務(wù)本質(zhì)上是負(fù)載均衡,即反向代理;在具體實(shí)現(xiàn)中,這個反向代理,并不是部署在集群某一個節(jié)點(diǎn)上的,二是作為集群節(jié)點(diǎn)的sidecar部署在每個節(jié)點(diǎn)上的。

在這里讓服務(wù)“照”進(jìn)反向代理這個“現(xiàn)實(shí)”的,是K8s集群的一個控制器,即kube-proxy。簡單來說,kube-proxy作為部署在集群節(jié)點(diǎn)上的控制器,通過集群API Server監(jiān)聽著集群狀態(tài)變化。當(dāng)有新的服務(wù)被創(chuàng)建的時(shí)候,kube-proxy會把集群服務(wù)的狀態(tài)、屬性,翻譯成反向代理的配置,整個過程如圖6-5所示。

那剩下的問題就是反向代理(即圖6-5中的proxy)的實(shí)現(xiàn)了

6.4 基于Netfilter的實(shí)現(xiàn)

K8s集群節(jié)點(diǎn)實(shí)現(xiàn)服務(wù)反向代理的方法目前主要有三種,即userspace、iptables以及ipvs。本章以阿里云Flannel集群網(wǎng)絡(luò)為范本,僅對基于iptables的服務(wù)實(shí)現(xiàn)做深入探討。

6.4.1 過濾器框架

Netfilter實(shí)際上是一個過濾器框架。Netfilter在網(wǎng)絡(luò)包收發(fā)及路由的“管道”上,一共"切"開了5個扣,分別是PREROUTING、FORWARD、POSTROUTING、INPUT、以及OUTPUT,同時(shí)Netfilter定義了包括NAT、Filter在內(nèi)的若干個網(wǎng)絡(luò)包處理方式。NetFilter框架如圖6-9所示。

需要注意的是,Routing和FORWARD很大程序上增加了以上Netfilter的復(fù)雜程度,如果我們不考慮Routing和FORWARD,那么NetFilter就會變得和我們的水過濾框架一樣簡單。

6.4.2 節(jié)點(diǎn)網(wǎng)絡(luò)大圖

參考圖6-10所示的K8s集群節(jié)點(diǎn)網(wǎng)絡(luò)全貌。橫向來看,節(jié)點(diǎn)上的網(wǎng)絡(luò)環(huán)境被分割成不同的網(wǎng)絡(luò)命名空間,包括主機(jī)網(wǎng)絡(luò)命名空間和Pod網(wǎng)絡(luò)命名空間;縱向來看,每個網(wǎng)絡(luò)命名空間包括完整的網(wǎng)絡(luò)棧:從應(yīng)用到協(xié)議棧,再到網(wǎng)絡(luò)設(shè)備。

在網(wǎng)絡(luò)設(shè)備這一層,我們通過cni0虛擬網(wǎng)橋組建出系統(tǒng)內(nèi)部的一個虛擬局域網(wǎng)。Pod網(wǎng)絡(luò)通過Veth對連接到這個虛擬局域網(wǎng)內(nèi),cni0虛擬局域網(wǎng)通過主機(jī)路由以及網(wǎng)口eth0與外部通信。

在網(wǎng)絡(luò)協(xié)議棧這一層,我們可以通過在Netfilter過濾器框架上編程,來實(shí)現(xiàn)集群節(jié)點(diǎn)的反向代理。

實(shí)現(xiàn)反向代理,歸根結(jié)底就是做DNAT,即把發(fā)送給集群服務(wù)IP地址和端口的數(shù)據(jù)包,修改成發(fā)給具體容器組的IP地址和端口。參考圖6-9中的Netfilter過濾器框架。在Netfilter里,可以通過在PREROUTING、OUTPUT以及POSTROUTING三個位置加入NAT規(guī)則,來改變數(shù)據(jù)包的源地址或目的地址。

因?yàn)檫@里需要做的是DNAT,需要改變目的地址,這樣的修改必須在路由(Routing)之前發(fā)生以保證數(shù)據(jù)包可以被路由正確處理,所以實(shí)現(xiàn)反向代理的規(guī)則,需要被加到PREROUTING和OUTPUT兩個位置。

其中,PREROUTING的規(guī)則用來處理從Pod訪問服務(wù)的流量。數(shù)據(jù)包從Pod網(wǎng)絡(luò)Veth發(fā)送到cni0之后,進(jìn)入主機(jī)協(xié)議棧,首先會經(jīng)過Netfilter PREROUTING的處理,所以發(fā)送給服務(wù)的數(shù)據(jù)包,會在這個位置做DNAT。經(jīng)過DNAT處理之后,數(shù)據(jù)包的目的地址變成另一個Pod的地址,從而經(jīng)過主機(jī)路由轉(zhuǎn)發(fā)到eth0,發(fā)送給正確的集群節(jié)點(diǎn)。

而添加在OUTPUT這個位置的DNAT規(guī)則,則用來處從主機(jī)網(wǎng)絡(luò)發(fā)給服務(wù)的數(shù)據(jù)包,原理也是類似的,即在經(jīng)過路由之前修改目的地址,以方便路由轉(zhuǎn)發(fā)。

6.4.3 升級過濾器框架

在"過濾器框架"一節(jié),我們看到Netfilter是一個過濾器框架。Netfilter在數(shù)據(jù)“管道”上“切“了5個口,分別在這5個扣上做了一些數(shù)據(jù)包處理工作。雖然固定切口位置以及網(wǎng)絡(luò)包處理方式分類已經(jīng)極大地優(yōu)化了過濾器框架,但是有一個關(guān)鍵的問題,就是我們還需要再管道上做修改以滿足新的功能。換句話說,這個框架沒有做到管道和過濾功能兩者的徹底解耦。

為了實(shí)現(xiàn)管道和過濾功能兩者的解耦,Netfilter用了表的概念,表就是Netfilter的過濾中心,其核心功能是過濾方式的分類(表),以及每種過濾方式中過濾規(guī)則的組織(鏈),如圖6-11所示。

把管道和過濾功能解耦之后,所有對數(shù)據(jù)包的處理都變成了對表的配置。而管道上的5個切口,僅僅變成了流量的出入口,負(fù)責(zé)把流量發(fā)送到過濾中心,并把處理之后的流量沿著管道繼續(xù)傳送下去。

Netfilter把表中的規(guī)則組織成鏈。表中有針對每個管道切口的默認(rèn)鏈,也有我們我們自己加入的自定義鏈。默認(rèn)鏈?zhǔn)菙?shù)據(jù)的入口,默認(rèn)鏈可以通過跳轉(zhuǎn)到自定義鏈來完成一些復(fù)雜的功能,比如實(shí)現(xiàn)K8s集群節(jié)點(diǎn)的反向代理,我們可以使用自定義鏈來使我們的規(guī)則模塊化。

6.4.4 用自定義鏈實(shí)現(xiàn)服務(wù)的反向代理

集群服務(wù)的反向代理,實(shí)際上就是利用自定義鏈,模塊化實(shí)現(xiàn)數(shù)據(jù)包的DNAT轉(zhuǎn)換。KUBE-SERVICE是整個反向代理的入口鏈,其對應(yīng)所有服務(wù)的總?cè)肟冢籏UBE-SVC-XXXX鏈?zhǔn)蔷唧w某一個服務(wù)的入口鏈。KUBE-SERVICE鏈會根據(jù)服務(wù)IP地址,跳轉(zhuǎn)到具體服務(wù)的KUBE-SVC-XXXX鏈。KUBE-SEP-XXXX鏈代表著某一個具體Pod的地址和端口,即Endpoint,具體服務(wù)鏈KUBE-SVC-XXXXX會按照一定的負(fù)載均衡算法跳轉(zhuǎn)到Endpoint鏈,其整體結(jié)構(gòu)如圖6-12所示。

而如前面提到的,因?yàn)檫@里需要做的是DNAT,即改變目的地址,這樣的修改必須在路由之前發(fā)生以保證數(shù)據(jù)包可以被路由正確處理,所以KUBE-SERVICE會被PREROUTING和OUTPUT兩個默認(rèn)鏈所調(diào)用、

6.5總結(jié)

服務(wù)本質(zhì)上是負(fù)載均衡

服務(wù)負(fù)載均衡的實(shí)現(xiàn)采用了與服務(wù)網(wǎng)格類似的邊車模式,而不是LVS類型的獨(dú)占模式。

kube-proxy本質(zhì)上是一個集群控制器。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • kube-proxy是管理service的訪問入口,包括集群內(nèi)Pod到Service的訪問和集群外訪問servic...
    程序員札記閱讀 2,419評論 0 2
  • 一、問題 首先,我們思考這樣一個問題: 訪問k8s集群中的pod, 客戶端需要知道pod地址,需要感知pod的狀態(tài)...
    陳sir的知識圖譜閱讀 3,378評論 0 11
  • kube-proxy 我們知道,Kubernetes中Pod的生命是短暫了,它隨時(shí)可能被終止。即使使用了Deplo...
    Tommy1989閱讀 892評論 0 1
  • 目錄: ipvs vs iptables ipvs kube-proxy原理分析2.1.cluster-ip到po...
    Feel_狗煥閱讀 28,306評論 0 13
  • 當(dāng)我們部署kube-prox時(shí)都會存在一個選擇, 是選擇ipvs模式還是iptables哪個好呢? 也還存在其它的...
    一瓶多先生閱讀 3,019評論 0 1

友情鏈接更多精彩內(nèi)容