<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          K8s中Pod的服務(wù)發(fā)現(xiàn)

          共 5707字,需瀏覽 12分鐘

           ·

          2021-02-15 22:34


          Pod是怎么找到請求的Pod的,pod之間又是怎么負載均衡的(iptables模式下)





          01

          iptables知識



          想知道這個問題,首先需要了解一些iptables知識。


          五條鏈


          Iptables是linux內(nèi)核集成的IP信息過濾規(guī)則,負責(zé)將發(fā)往主機的網(wǎng)絡(luò)包進行分發(fā),轉(zhuǎn)換等。當客戶端請求服務(wù)器的某個服務(wù)時,請求信息會先通過網(wǎng)卡進入服務(wù)器內(nèi)核,這時iptables會對包進行過濾,決定這些包是發(fā)往用戶態(tài)的服務(wù)進程或是轉(zhuǎn)發(fā)出去到別的主機。而決定這些路徑的方式在iptables中稱為鏈,剛進入內(nèi)核的請求流會經(jīng)過PREROUTING鏈,根據(jù)路由規(guī)則判斷是是不是發(fā)往本機請求,是則走INPUT鏈進入本機用戶態(tài)進程,否則會走FORWARD鏈并匹配對應(yīng)的規(guī)則最后流出本機;如果是本機發(fā)出的請求會走OUTPUT鏈并進一步到POSTROUTINE鏈流出本機,或轉(zhuǎn)發(fā)到其他機器或回復(fù)信息給客戶端。




          總結(jié)上述幾條鏈:


          • PREROUTINE:流入本機路由前

          • POSTROUTINE:流出本機路由前

          • FORWARD:轉(zhuǎn)發(fā)路徑

          • OUTPUT:由本機用戶程序發(fā)出的

          • INPUT:發(fā)送至本機用戶程序的


          兩個動作


          SNAT


          源地址轉(zhuǎn)換,是指將報文發(fā)送方的ip地址轉(zhuǎn)換,這樣當相應(yīng)方回復(fù)請求時,回復(fù)的是發(fā)送方的地址。


          示例


          client發(fā)送請求給server時,需要經(jīng)過gateway,如果gateway不對包進行源地址轉(zhuǎn)換(SNAT),發(fā)往server的網(wǎng)絡(luò)包攜帶的源地址依然是clientserver會對該源地址響應(yīng),但client并不識別server的地址,會導(dǎo)致該條請求出現(xiàn)錯誤。



          DNAT


          目標地址轉(zhuǎn)換,是將報文的目標地址轉(zhuǎn)換,起到請求轉(zhuǎn)發(fā)到別的目的地的作用。







          02

          k8s基礎(chǔ)知識? ??


          需要了解k8s中的幾種IP類型。


          虛擬IP


          虛IP(下文稱VIP)有ClusterIP(即serviceIP),是集群自己生成的,ping不通,并和PodIP不處于同一網(wǎng)段,避免請求發(fā)生混亂。當創(chuàng)建一個service時,k8s會為該service指派一個IP地址,并會被集群中的所有kube-proxy觀察到,kube-proxy從而會安裝一系列的iptables規(guī)則到宿主機,kube-dns也會相應(yīng)的插入一條域名解析IP的規(guī)則。請求到來的時候,如果符合規(guī)則,iptables會將VIP轉(zhuǎn)化為實際的IP并使用。



          實際IP


          實IP分別有PodIP等,該IP是由CNI插件分配的,在k8s集群啟動時候,需要安裝CNI插件,通常是一個DaemonSet控制器控制,保證每臺節(jié)點都有該進程。他的作用是在集群內(nèi)部產(chǎn)生一套網(wǎng)絡(luò),并給每個pod插上網(wǎng)線,保證pod與節(jié)點,pod與pod是互通的。



          Pod之間通信的方式可以通過實際的PodIP,但是該IP會隨著pod的變化而變化,不適合用該方式,也可以通過ClusterIP的方式通信,比較穩(wěn)定,但是不容易被記住,還可以通過svc.ns這種域名的格式,該方法請求kube-dns域名解析得到域名對應(yīng)的IP






          03

          案例學(xué)習(xí)? ??



          接下來根據(jù)一個案例探討一下。


          案例介紹


          • 集群中有兩個gateway-pod,service類型為NodePort,暴露端口給集群外部,接收外界請求并負載均衡,并將請求轉(zhuǎn)發(fā)到下游pod。


          • 有一個basedao pod,負責(zé)接收gateway pod發(fā)來的請求并響應(yīng),對應(yīng)的service名稱是sts-basedao,命名空間名稱是basedao。


          • Kube-dns pod將域名解析成IP地址,并返回給發(fā)送方。


          查看一下各個pod的IP,該IP是實際的IP。

          [centos@guozhao-50?~]$?kubectl?get?pod?--all-namespaces?-owideNAMESPACE?????NAME????????????????????????????????IP????????????????????basedao???????sts-basedao-0??????????????????????10.34.0.2gateway???????sts-gateway-59d5fdbc54-4d6kv? ?????10.40.0.0gateway???????sts-gateway-59d5fdbc54-dmncq???????10.34.0.1?kube-system???coredns-6c76c8bb89-kztxk???????????10.32.0.4


          查看一下三種pod對應(yīng)service的IP,可以看到gateway service代理的30001端口映射到了外部的31001端口。


          [centos@guozhao-50?~]$ kubectl?get?svc?--all-namespacesNAMESPACE     NAME                   TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                  AGEbasedao       svc-basedao            ClusterIP   10.111.143.223           30003/TCP                70mgateway       svc-gateway            NodePort    10.102.103.1             30001:31001/TCP          70mkube-system???kube-dns???????????????ClusterIP???10.96.0.10???????????????53/UDP,53/TCP,9153/TCP???14d



          client發(fā)起請求


          通過iptables-save命令可以查看到所有的iptables規(guī)則


          當client發(fā)起請求時,會請求服務(wù)器對應(yīng)的端口,對應(yīng)NodePort端口,我們來查看對應(yīng)的iptables規(guī)則,會經(jīng)過PREROUTING,跳轉(zhuǎn)到KUBE-SERVICES規(guī)則

          -A?PREROUTING?-m?comment?--comment?"kubernetes?service?portals"?-j KUBE-SERVICES



          在KUBE-SERVICE中找到符合的規(guī)則,--dst-type LOCAL 代表本地,會繼續(xù)跳轉(zhuǎn)到KUBE-NODEPORTS

          -A KUBE-SERVICES -m comment --comment "kubernetes service nodeports; NOTE: this must be the last rule in this chain" -m addrtype --dst-type LOCAL -j KUBE-NODEPORTS



          該請求會跳轉(zhuǎn)到KUBE-MARK-MASQ給請求打一個標簽,并跳轉(zhuǎn)到下一條規(guī)則KUBE-SVC-4QJQIYWH2AWK2TSA。

          -A?KUBE-NODEPORTS?-p?tcp?-m?comment?--comment?"gateway/svc-gateway:gateway-port"?-m?tcp?--dport?31001?-j?KUBE-MARK-MASQ-A KUBE-NODEPORTS -p tcp -m comment --comment "gateway/svc-gateway:gateway-port" -m tcp --dport 31001 -j KUBE-SVC-4QJQIYWH2AWK2TSA


          跟隨上條規(guī)則有兩條規(guī)則與其對應(yīng),--probability 0.50000000000代表有0.5的概率進入上面的規(guī)則,如果沒有進入上面規(guī)則,就會進入下面的規(guī)則,負載均衡也就是在iptables層面實現(xiàn)的。

          -A KUBE-SVC-4QJQIYWH2AWK2TSA -m comment --comment "gateway/svc-gateway:gateway-port" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-XEQTQPKSTZECBET2-A KUBE-SVC-4QJQIYWH2AWK2TSA -m comment --comment "gateway/svc-gateway:gateway-port" -j KUBE-SEP-OCFEUGRRJNZZEOHZ



          分別查看兩個規(guī)則對應(yīng)的下一條規(guī)則,該規(guī)則指定了目標地址,執(zhí)行了DNAT操作進行目標地址轉(zhuǎn)發(fā),分別對應(yīng)了兩個pod實例的實際IP地址,請求會跟隨這條規(guī)則轉(zhuǎn)發(fā)到實際的gateway。

          -A?KUBE-SEP-XEQTQPKSTZECBET2?-p?tcp?-m?comment?--comment?"gateway/svc-gateway:gateway-port"?-m?tcp?-j?DNAT?--to-destination?10.34.0.1:30001-A KUBE-SEP-OCFEUGRRJNZZEOHZ -p tcp -m comment --comment "gateway/svc-gateway:gateway-port" -m tcp -j DNAT --to-destination 10.40.0.0:30001



          在最終發(fā)出請求之前會走POSTROUTING鏈,會對該請求做一個SNAT操作,MASQUERADE代表執(zhí)行了SNAT操作修改了請求源地址。

          -A POSTROUTING -m comment --comment "kubernetes postrouting rules" -j KUBE-POSTROUTING-A KUBE-POSTROUTING -m comment --comment "kubernetes service traffic requiring SNAT" -j MASQUERADE


          gateway發(fā)起請求


          此時gateway收到了來自client的請求,他會向basedao發(fā)起請求,請求方式是通過域名即sts-basedao.basedao:30002格式。該請求會發(fā)送給dns服務(wù)器進行解析返回一個實際IP地址,當然,該地址也是一個VIP。


          在pod被創(chuàng)建時候,就會在pod中創(chuàng)建dns服務(wù)配置文件,nameserver代表dns服務(wù)器的IP地址,默認是集群中的kube-dns地址,search代表域名拼接規(guī)則。可以看出,該地址和kube-dns的VIP是相同的。



          接下來該pod會發(fā)出請求到kube-dns的VIP


          由于是在主機上發(fā)出,會走OUTPUT鏈,進而進入到KUBE-SERVICES

          -A?OUTPUT?-m?comment?--comment?"kubernetes?service?portals"?-j?KUBE-SERVICES



          滿足KUBE-SERVICES的該條規(guī)則,繼續(xù)跳轉(zhuǎn)到KUBE-SVC-ERIFXISQEP7F7OF4,再次跳轉(zhuǎn)到KUBE-SEP-ZT5TVM6PMFDFQAMO。

          -A KUBE-SERVICES -d 10.96.0.10/32 -p tcp -m comment --comment "kube-system/kube-dns:dns-tcp cluster IP" -m tcp --dport 53 -j KUBE-SVC-ERIFXISQEP7F7OF4-A?KUBE-SVC-ERIFXISQEP7F7OF4?-m?comment?--comment?"kube-system/kube-dns:dns-tcp"?-j?KUBE-SEP-ZT5TVM6PMFDFQAMO



          最終進行DNAT目標地址轉(zhuǎn)發(fā)到dns實際的pod,最終dns返回給gateway由域名解析到的ip。

          -A KUBE-SEP-ZT5TVM6PMFDFQAMO -p tcp -m comment --comment "kube-system/kube-dns:dns-tcp" -m tcp -j DNAT --to-destination 10.32.0.4:53


          當gateway得到真實的IP,該IP就是basedao的VIP,gateway會使用該VIP發(fā)起請求,依然會對應(yīng)到相應(yīng)的iptables規(guī)則,完成VIP到IP的映射得到basedao pod的實際地址,并向?qū)嶋H地址發(fā)送數(shù)據(jù)包,這里便不再贅述。





          04

          總結(jié)? ??


          由于Pod的IP地址不是持久的,所以盡量建議采用ClusterIP或者域名的方式請求集群中的其他pod,而這兩種方式是通過Linux內(nèi)核的iptables規(guī)則實現(xiàn)的。使用iptables規(guī)則也有缺點,當集群中有過多的服務(wù)Pod,相應(yīng)的各臺宿主機iptables規(guī)則就會增加,這增加了網(wǎng)絡(luò)的復(fù)雜度與跟蹤難度,會給后期運維帶來一定的困難。






          05

          參考文章? ??



          • 《iptables詳解》http://www.zsythink.net/archives/1199

          • 《k8s中文文檔》https://v1-16.docs.kubernetes.io/zh/

          • 《深入剖析Kubernetes》極客時間



          推薦閱讀


          福利

          我為大家整理了一份從入門到進階的Go學(xué)習(xí)資料禮包,包含學(xué)習(xí)建議:入門看什么,進階看什么。關(guān)注公眾號 「polarisxu」,回復(fù)?ebook?獲取;還可以回復(fù)「進群」,和數(shù)萬 Gopher 交流學(xué)習(xí)。

          瀏覽 44
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产爆乳一区二区 | 国产精品无码一区二区三区免费 | 毛片网在线 | 日本A片在线免费观看 | 11久久|