11.5 服務(wù)是如何實(shí)現(xiàn)的
在第5 章中學(xué)習(xí)過(guò)Service,Service允許長(zhǎng)時(shí)間對(duì)外暴露一系列pod钉迷、穩(wěn)定的IP地址以及端口。為了聚焦Service的目的以及它們?nèi)绾伪皇褂茫覀儺?dāng)時(shí)并沒(méi)有深入探究其工作原理肥荔。但是骇两,要真正理解服務(wù),并更好地了解當(dāng)事情的行為與預(yù)期不一致時(shí)應(yīng)該從哪著手拳喻,就需要了解服務(wù)的實(shí)現(xiàn)原理哭当。
11.5.1 引入kube-proxy
和Service相關(guān)的任何事情都由每個(gè)節(jié)點(diǎn)上運(yùn)行的kube-proxy進(jìn)程處理。開(kāi)始的時(shí)候冗澈,kube-proxy確實(shí)是一個(gè)proxy钦勘,等待連接,對(duì)每個(gè)進(jìn)來(lái)的連接亚亲,連接到一個(gè)pod彻采。這稱為userspace(用戶空間)代理模式。后來(lái)捌归,性能更好的iptables代理模式取代了它肛响。iptables代理模式目前是默認(rèn)的模式,如果你有需要也仍然可以配置Kubernetes使用舊模式惜索。
在我們繼續(xù)之前特笋,先快速回顧一下Service的幾個(gè)知識(shí)點(diǎn),對(duì)理解下面幾段有幫助巾兆。
我們之前了解過(guò)猎物,每個(gè)Service有其自己穩(wěn)定的IP地址和端口〗撬埽客戶端(通常為pod)通過(guò)連接該IP和端口使用服務(wù)蔫磨。IP地址是虛擬的,沒(méi)有被分配給任何網(wǎng)絡(luò)接口圃伶,當(dāng)數(shù)據(jù)包離開(kāi)節(jié)點(diǎn)時(shí)也不會(huì)列為數(shù)據(jù)包的源或目的IP地址堤如。Service的一個(gè)關(guān)鍵細(xì)節(jié)是,它們包含一個(gè)IP留攒、端口對(duì)(或者針對(duì)多端口Service有多個(gè)IP煤惩、端口對(duì)),所以服務(wù)IP本身并不代表任何東西炼邀。這就是為什么你不能夠ping它們魄揉。
11.5.2 kube-proxy 如何使用iptables
當(dāng)在API服務(wù)器中創(chuàng)建一個(gè)服務(wù)時(shí),虛擬IP地址立刻就會(huì)分配給它拭宁。之后很短時(shí)間內(nèi)洛退,API服務(wù)器會(huì)通知所有運(yùn)行在工作節(jié)點(diǎn)上的kube-proxy客戶端有一個(gè)新服務(wù)已經(jīng)被創(chuàng)建了瓣俯。然后,每個(gè)kube-proxy都會(huì)讓該服務(wù)在自己的運(yùn)行節(jié)點(diǎn)上可尋址兵怯。原理是通過(guò)建立一些iptables規(guī)則彩匕,確保每個(gè)目的地為服務(wù)的IP/端口對(duì)的數(shù)據(jù)包被解析,目的地址被修改媒区,這樣數(shù)據(jù)包就會(huì)被重定向到支持服務(wù)的一個(gè)pod驼仪。
除了監(jiān)控API對(duì)Service的更改,kube-proxy也監(jiān)控對(duì)Endpoint對(duì)象的更改袜漩。我們?cè)诘?章討論過(guò)绪爸,下面回顧一下,因?yàn)槟慊旧喜粫?huì)去手動(dòng)創(chuàng)建它們宙攻,所以比較容易忘記它們的存在奠货。Endpoint對(duì)象保存所有支持服務(wù)的pod的IP/端口對(duì)(一個(gè)IP/端口對(duì)也可以指向除pod之外的其他對(duì)象)。這就是為什么kube-proxy必須監(jiān)聽(tīng)所有Endpoint對(duì)象座掘。畢竟Endpoint對(duì)象在每次新創(chuàng)建或刪除支持pod時(shí)都會(huì)發(fā)生變更递惋,當(dāng)pod的就緒狀態(tài)發(fā)生變化或者pod的標(biāo)簽發(fā)生變化,就會(huì)落入或超出服務(wù)的范疇溢陪。
現(xiàn)在讓我們了解一下kube-proxy如何讓客戶端能夠通過(guò)Service連接到這些pod萍虽,如圖11.17所示。
圖11.17 發(fā)送到服務(wù)虛擬IP/端口對(duì)的網(wǎng)絡(luò)包會(huì)被修改嬉愧、重定向到一個(gè)隨機(jī)選擇的后端pod
圖中描述kube-proxy做了什么贩挣,以及數(shù)據(jù)包如何通過(guò)客戶端pod發(fā)送到支持服務(wù)的一個(gè)pod上。讓我們檢查一下當(dāng)通過(guò)客戶端pod(圖中的pod A)發(fā)送數(shù)據(jù)包時(shí)發(fā)生了什么没酣。
包目的地初始設(shè)置為服務(wù)的IP和端口(在本例中王财,Service是在 172.30.0.1:80
)。發(fā)送到網(wǎng)絡(luò)之前裕便,節(jié)點(diǎn)A的內(nèi)核會(huì)根據(jù)配置在該節(jié)點(diǎn)上的iptables規(guī)則處理數(shù)據(jù)包绒净。
內(nèi)核會(huì)檢查數(shù)據(jù)包是否匹配任何這些iptables規(guī)則。其中有個(gè)規(guī)則規(guī)定如果有任何數(shù)據(jù)包的目的地IP等于 172.30.0.1
偿衰、目的地端口等于 80挂疆,那么數(shù)據(jù)包的目的地IP和端口應(yīng)該被替換為隨機(jī)選中的pod的IP和端口。
本例中的數(shù)據(jù)包滿足規(guī)則下翎,故而它的IP/端口被改變了缤言。在本例中,pod B2 被隨機(jī)選中了视事,所有數(shù)據(jù)包的目的地IP變更為10.1.2.1
(pod B2 的IP)胆萧,端口改為8080(Service中定義的目標(biāo)端口)。就好像是俐东,客戶端pod直接發(fā)送數(shù)據(jù)包給pod B而不是通過(guò)Service跌穗。
實(shí)際上可能比描述的要更復(fù)雜一點(diǎn)兒订晌,但是上述內(nèi)容是你需要理解的最重要的內(nèi)容。