簡(jiǎn)單示例說(shuō)明 kube-proxy 如何與 iptables 配合使用
我們知道 kube-proxy 是 Kubernetes 中一個(gè)運(yùn)行在每個(gè)節(jié)點(diǎn)上的守護(hù)進(jìn)程,它基本上反映了集群中定義的服務(wù)已經(jīng)對(duì)后端 Pod 負(fù)載均衡的規(guī)則管理。
假設(shè)我們有幾個(gè) API 微服務(wù)的 Pods 運(yùn)行在我們的集群中,這些 Pods 的副本通過(guò)一個(gè) Service 服務(wù)暴露,當(dāng)一個(gè)請(qǐng)求到達(dá) Service 的虛擬 IP 時(shí),如何將請(qǐng)求轉(zhuǎn)發(fā)到其中一個(gè)底層 Pod?其實(shí)就是通過(guò) kube-proxy 創(chuàng)建的規(guī)則,雖然表面上并沒(méi)有那么簡(jiǎn)單,但是我們還是可以進(jìn)行大致的了解。
kube-proxy 可以在三種不同的模式下運(yùn)行。
iptables IPvs userspace(不再推薦)
雖然 iptables 模式對(duì)于許多集群和工作負(fù)載來(lái)說(shuō)完全沒(méi)有問(wèn)題,但當(dāng)服務(wù)數(shù)量很多時(shí)(超過(guò)1,000個(gè)),ipvs 就會(huì)很有優(yōu)勢(shì)了,由于 iptables 規(guī)則是按順序讀取的,如果集群中存在許多服務(wù),那么它的使用會(huì)影響路由性能。
Tigera(Calico 的創(chuàng)建者和維護(hù)者)在這篇很棒的文章(https://www.tigera.io/blog/comparing-kube-proxy-modes-iptables-or-ipvs/)中詳細(xì)介紹了 iptables 和 ipvs 模式的區(qū)別。
本文我們將專(zhuān)注于 iptables 模式(下一篇文章將專(zhuān)門(mén)介紹 ipvs 模式)來(lái)說(shuō)明 kube-proxy 是如何定義 iptables 規(guī)則。
為此,我們將使用我剛剛用 kubeadm 創(chuàng)建的一個(gè)雙節(jié)點(diǎn)集群。
$?kubectl?get?nodes
NAME????STATUS???ROLES??????????????????AGE???VERSION
k8s-1???Ready????control-plane,master???57s???v1.20.0
k8s-2???Ready?????????????????????41s???v1.20.0
接下來(lái)我們將部署一個(gè)簡(jiǎn)單的應(yīng)用程序,并通過(guò) NodePort 類(lèi)型的服務(wù)將其暴露出來(lái)。
示例
首先,我們創(chuàng)建一個(gè)基于 ghost 鏡像的 Deployment(ghost 是一個(gè)免費(fèi)開(kāi)源的博客平臺(tái))并指定兩個(gè)副本。
$?kubectl?create?deploy?ghost?--image=ghost?--replicas=2
然后使用 NodePort 類(lèi)型的 Service 來(lái)暴露 Pods。
$?kubectl?expose?deploy/ghost?\
??--port?80?\
??--target-port?2368?\
??--type?NodePort
部署完成后就可以獲取這個(gè)新創(chuàng)建的 Service 的相關(guān)信息了。
$?kubectl?describe?svc?ghost
Name:?????????????????????ghost
Namespace:????????????????default
Labels:???????????????????app=ghost
Annotations:??????????????
Selector:?????????????????app=ghost
Type:?????????????????????NodePort
IP:???????????????????????10.98.141.188
Port:?????????????????????<unset>??80/TCP
TargetPort:???????????????2368/TCP
NodePort:?????????????????<unset>??30966/TCP
Endpoints:????????????????10.44.0.3:2368,10.44.0.4:2368
Session?Affinity:?????????None
External?Traffic?Policy:??Cluster
Events:???????????????????
這里有幾個(gè)需要注意的事項(xiàng):
分配給 Service 的虛擬 IP 地址(VIP)是:10.98.141.188
已分配給該 Service 的 NodePort 端口是 30966。通過(guò)這個(gè)端口,我們可以從集群的任何節(jié)點(diǎn)(本例中使用的集群節(jié)點(diǎn)的IP地址為192.168.64.35 和 192.168.64.36)訪問(wèn) ghost 網(wǎng)頁(yè)界面
Endpoints 屬性顯示了 Service 所暴露的 Pod 的 IP 地址。換句話說(shuō),每個(gè)到達(dá) Service 的虛擬 IP (10.98.141.188) 端口 80 的請(qǐng)求都會(huì)以隨機(jī)的方式轉(zhuǎn)發(fā)到 2368 端口的底層 Pod 的 IP (10.44.0.3 或 10.44.0.4)。
注意:我們也可以使用標(biāo)準(zhǔn)的 kubectl get 命令來(lái)查詢(xún) Endpoints 信息。
$?kubectl?get?endpoints
NAME?????????ENDPOINTS???????????????????????AGE
ghost????????10.44.0.3:2368,10.44.0.4:2368???4m
kubernetes???192.168.64.35:6443??????????????6m
接下來(lái),我們將仔細(xì)研究一下 kube-proxy 創(chuàng)建的 iptables 規(guī)則,以便將請(qǐng)求路由到后端 Pods。
iptables 規(guī)則
每次創(chuàng)建/刪除 Service 或修改 Endpoints 時(shí)(例如,如果由于相關(guān)應(yīng)用的 scale 而導(dǎo)致底層 Pod 數(shù)量發(fā)生變化),kube-proxy 都會(huì)負(fù)責(zé)更新集群每個(gè)節(jié)點(diǎn)上的 iptables 規(guī)則。
讓我們看看我們之前定義的 Service是如何完成的。由于有相當(dāng)多的 iptables 鏈生成,這里我們只考慮主要涉及到的請(qǐng)求的路由,這些請(qǐng)求在 NodePort 上得到并被轉(zhuǎn)發(fā)到其中一個(gè)底層 Pods。
首先,KUBE-NODEPORTS 鏈就是來(lái)處理 NodePort 類(lèi)型的 Service 上的數(shù)據(jù)包。
因此,每一個(gè)來(lái)自 30966 端口的數(shù)據(jù)包都會(huì)首先被 KUBE-MARK-MASQ 處理,它會(huì)給數(shù)據(jù)包打上了 0x4000 的標(biāo)簽。
注意:只有當(dāng)負(fù)載均衡使用 IPVS 模式時(shí),才會(huì)考慮到這個(gè)標(biāo)記。
接下來(lái),這個(gè)數(shù)據(jù)包由 KUBE-SVC-4XJR4EADNBDQKTKS 鏈(在上面的 KUBE-NODEPORTS 鏈中引用)進(jìn)行處理。如果我們仔細(xì)看一下,可以看到多了兩個(gè) iptables 鏈。
KUBE-SEP-7I5NH52DVZSA3QHPKUBE-SEP-PSCUKR75MU2ULAEX
我們可以看到這里隨機(jī)概率為0.5 的 statistic mode,因此進(jìn)入 KUBE-SVC-4XJR4EADNBDQKTKS 鏈的每個(gè)數(shù)據(jù)包都有50%的概率被 KUBE-SEP-7I5NH52DVZSA3QHP 或者 KUBE-SEP-PSCUKR75MU2ULAEX (當(dāng)它被第一個(gè)鏈忽略時(shí))鏈進(jìn)行處理。
如果我們檢查這兩條鏈,可以看到它們定義了 ghost 應(yīng)用的底層 Pod 之一的路由。
通過(guò)幾個(gè) iptables 鏈,我們就能夠了解一個(gè)請(qǐng)求從到達(dá)節(jié)點(diǎn)端口到底層 Pod的歷程。
在本文希望我已經(jīng)澄清了 kube-proxy 在使用 iptables 模式時(shí)的工作方式。接下來(lái)我們將看到當(dāng)使用 ipvs 模式進(jìn)行負(fù)載均衡時(shí),路由是如何進(jìn)行的工作。
“原文鏈接:https://medium.com/better-programming/k8s-a-closer-look-at-kube-proxy-372c4e8b090
”
進(jìn)階訓(xùn)練營(yíng)第二期
本次訓(xùn)練營(yíng)采用線上直播的形式,基于1.19.x版本,根據(jù)第1期課程的打磨,我們總結(jié)出了 Docker 基礎(chǔ) + Kubernetes 基礎(chǔ) + 原理 + 基本使用 + 進(jìn)階技能 +?完整項(xiàng)目實(shí)踐?的課程體系。加強(qiáng)系統(tǒng)知識(shí)吸收、夯實(shí)基礎(chǔ)的同時(shí),并在實(shí)際操作過(guò)程中去了解排查問(wèn)題的方式方法,更為重要的是我們的老師非常負(fù)責(zé)任,隨時(shí)幫你答疑解惑,我們認(rèn)為不只是課堂上講授知識(shí),更重要的是售后支持,完全不用擔(dān)心學(xué)習(xí)不到知識(shí)。
?點(diǎn)擊屏末?|?閱讀原文?|?即刻學(xué)習(xí)








