為啥爭吵,吵什么?
Cloud Native
"你到底在說什么啊,我K8s的ecs節(jié)點(diǎn)要訪問clb的地址不通和本地網(wǎng)卡有什么關(guān)系..." 氣憤語氣都從電話那頭傳了過來,這時(shí)電話兩端都沉默了。過了好一會(huì)傳來地鐵小姐姐甜美的播報(bào)聲打斷了剛剛的沉寂「乘坐地鐵必須全程佩戴口罩,下一站西湖文化廣場...」。
pod需要訪問clb的443的監(jiān)聽, 但是如果是集群內(nèi)(集群內(nèi)后面都指的K8s的節(jié)點(diǎn)或者POD)訪問就會(huì)出現(xiàn)如下報(bào)錯(cuò)Connection refused:
所以就捋了一下客戶鏈路如下: ?
具體現(xiàn)象是什么
無論是節(jié)點(diǎn)node還是pod里訪問192.168.1.200:443都是不通的,但是訪問192.168.1.200:80卻是正常的。同時(shí)集群外的ECS192.168.3.100訪問192.168.1.200:443和192.168.1.200:80都是正常的。
進(jìn)一步分析看看
CLB1的IP192.168.1.200被綁定到了K8s的node節(jié)點(diǎn)的kube-ipvs0網(wǎng)卡上,這個(gè)是一張dummy 網(wǎng)卡,參考dummy interface。由于 SVC1 是LoadBalancer類型的,同時(shí)復(fù)用了這個(gè)CLB1,關(guān)聯(lián)endpoint是POD1192.168.1.101:80,那么就可以解釋為何訪問192.168.1.200:80是正常,是由于kube-proxy根據(jù)SVC1的配置創(chuàng)建ipvs規(guī)則同時(shí)掛載了可被訪問的后端服務(wù)。而集群里訪問192.168.1.200:443都是不通的,因?yàn)镮P被綁定到dummy網(wǎng)卡后,就不會(huì)再出節(jié)點(diǎn)去訪問到CLB1,同時(shí)沒有443對應(yīng)ipvs規(guī)則,所以直接是拒絕的。
這個(gè)時(shí)候如果節(jié)點(diǎn)里沒有ipvs規(guī)則(ipvs優(yōu)先于監(jiān)聽)但是又能訪問通的話, 可以檢查一下是否本地有監(jiān)聽0.0.0.0:443的服務(wù),那么這個(gè)時(shí)候所有網(wǎng)卡IP+443都能通,但是訪問的是本地服務(wù),而不是真正的CLB后端的服務(wù)。
是否有辦法解決呢
Cloud Native
最建議的方式
最好的方式拆分, 集群內(nèi)和集群外的服務(wù)分開兩個(gè)CLB使用。
阿里云svc注解的方式
SVC1使用這個(gè)注解service.beta.kubernetes.io/alibaba-cloud-loadbalancer-hostname,進(jìn)行占位,這樣就不會(huì)綁定CLB的IP到kube-ipvs0的網(wǎng)卡上,集群內(nèi)訪問CLB的IP就會(huì)出集群訪問CLB,但是需要注意如果監(jiān)聽協(xié)議為TCP或UDP,集群內(nèi)訪問CLB IP時(shí)將會(huì)存在回環(huán)訪問問題。詳細(xì)信息,請參見客戶端無法訪問負(fù)載均衡CLB[1]。
需要CCM版本在 v2.3.0及以上版本才支持這個(gè)注解, 具體參考:通過Annotation配置傳統(tǒng)型負(fù)載均衡CLB[2]
demo:
apiVersion: v1 kind: Service metadata: annotations: service.beta.kubernetes.io/alibaba-cloud-loadbalancer-hostname: "${your_service_hostname}" name: nginx-svc namespace: default spec: ports: - name: http port: 80 protocol: TCP targetPort: 80 selector: app: nginx type: LoadBalancer
集群內(nèi)訪問ExternalTrafficPolicy
策略有影響嗎?
Cloud Native
我們都知道K8s的nodeport和loadbalancer模式是可以調(diào)整外部流量策略的,那么圖中的「外部策略為Local/Cluster,所有集群節(jié)點(diǎn)創(chuàng)建IPVS規(guī)則是有區(qū)別的」該如何解釋呢, 以及集群內(nèi)訪問nodePort/CLBIP的時(shí)候會(huì)發(fā)生什么。
以下都是針對svc的internalTrafficPolicy都是Cluster或者缺省的情況,這個(gè)ServiceInternalTrafficPolicy特性在1.22的K8s中默認(rèn)開啟,具體參考service-traffic-policy[3]
具體到阿里云容器在不同網(wǎng)絡(luò)CNI情況下的數(shù)據(jù)鏈路,可以參考下面的文章。
此處我們只討論ipvs TrafficPolicy Local在Kubernetes 從1.22升級到1.24的行為變化。
Kubernetes 1.24 IPVS的變化
以下均以kube-proxy的IPVS模式為例:
當(dāng)externalTrafficPolicy為Cluster模式或缺省的時(shí)候,ipvs規(guī)則里的nodePort/CLBIP后端會(huì)掛載所有的Endpoint的IP,這時(shí)候集群內(nèi)訪問會(huì)丟失源IP,因?yàn)楣?jié)點(diǎn)會(huì)做一層SNAT。
當(dāng)externalTrafficPolicy是Local的時(shí)候
當(dāng)節(jié)點(diǎn)上有對應(yīng)service的Endpoint的時(shí)候,ipvs規(guī)則里的nodePort/CLBIP后端只掛載自己節(jié)點(diǎn)的Endpoint的IP,集群內(nèi)訪問會(huì)保留源IP。
當(dāng)節(jié)點(diǎn)上沒有對應(yīng)service的Endpoint的時(shí)候
在1.24之前的版本是會(huì)掛空的后端的,集群內(nèi)訪問會(huì)拒絕。
在1.24之后的K8s集群里,當(dāng)節(jié)點(diǎn)上沒有對應(yīng)service的Endpoint的時(shí)候,ipvs規(guī)則里的nodePort/CLB IP后端會(huì)掛載所有的Endpoint的IP,這時(shí)候集群內(nèi)訪問會(huì)丟失源IP,因?yàn)楣?jié)點(diǎn)會(huì)做一層SNAT。社區(qū)調(diào)整了Local策略后端服務(wù)的規(guī)則掛載策略,具體參考社區(qū)PR[4]。
集群外訪問SLB
集群外訪問SLB的話,CCM只會(huì)掛載Local類型的節(jié)點(diǎn),情況跟1.24 kubernetes前一樣,這里不做過多闡述,請見上面連接。
集群外訪問NodePort
1.24 Kubernetes之前版本
訪問有Endpoint的節(jié)點(diǎn)的NodePort,可以通,可以保留源IP
Nginx分布在cn-hongkong.10.0.4.174和cn-hongkong.10.0.2.84節(jié)點(diǎn)。
從外部10.0.3.72節(jié)點(diǎn)訪問有后端pod所在節(jié)點(diǎn)的cn-hongkong.10.0.2.84的30479端口,可以訪問。
cn-hongkong.10.0.0.140節(jié)點(diǎn)上是有相關(guān)的IPVS的規(guī)則的,但是只有該節(jié)點(diǎn)上后端Pod IP。
通過conntrack表可以到,這是由于在cn-hongkong.10.0.0.140節(jié)點(diǎn)上,相關(guān)的鏈路被dnat,最后是由pod cn-hongkong.10.0.2.84節(jié)點(diǎn)上的 的nginx-7d6877d777-tzbf7 10.0.2.87返回源,所有的相關(guān)轉(zhuǎn)化都在該節(jié)點(diǎn)上,所以TCP四層建連可以成功。
訪問沒有Endpoint的節(jié)點(diǎn)的NodePort,不能通,因?yàn)楣?jié)點(diǎn)上沒有相關(guān)的ipvs轉(zhuǎn)發(fā)規(guī)則
從外部10.0.3.72節(jié)點(diǎn)訪問無后端pod所在節(jié)點(diǎn)的cn-hongkong.10.0.0.140的30479端口,不可以訪問。
查看該cn-hongkong.10.0.0.140節(jié)點(diǎn),并沒有相關(guān)的ipvs轉(zhuǎn)發(fā)規(guī)則,所以無法進(jìn)行dnat,訪問會(huì)失敗。
1.24 Kubernetes版本之后(含)
訪問有Endpoint節(jié)點(diǎn)的NodePort,可以通,可以保留源IP
訪問沒有Endpoint節(jié)點(diǎn)的NodePort:
terway ENIIP or host網(wǎng)絡(luò):不通
Nginx分布在cn-hongkong.10.0.2.77和cn-hongkong.10.0.0.171 節(jié)點(diǎn)。
從外部10.0.3.72節(jié)點(diǎn)訪問無后端pod所在節(jié)點(diǎn)的cn-hongkong.10.0.5.168的30745端口,可以看到,訪問失敗。
cn-hongkong.10.0.5.168節(jié)點(diǎn)上是有相關(guān)的IPVS的規(guī)則的,并且會(huì)把所有的后端Pod IP加到IPVS規(guī)則中。
通過conntrack表可以到,這是由于在cn-hongkong.10.0.5.168節(jié)點(diǎn)上,相關(guān)的鏈路被dnat,最后是由pod cn-hongkong.10.0.2.77節(jié)點(diǎn)上的nginx-79fc6bc6d-8vctc 10.0.2.78返回源,源在接受這個(gè)鏈路后,會(huì)發(fā)現(xiàn)和自己的五元組不匹配,直接丟棄,三次握手必然失敗,所以建連失敗。
flannel網(wǎng)絡(luò):可以通,但是保留不了源IP
Nginx分布在cn-hongkong.10.0.2.86。
從外部訪問cn-hongkong.10.0.4.176的31218端口,可以訪問成功。
cn-hongkong.10.0.4.176記錄了src是10.0.3.72,并做了dnat為172.16.160.135,期望它返回給10.0.4.176的58825端口。
后端ep所在節(jié)點(diǎn)cn-hongkong.10.0.2.86,conntrack表記錄了src是10.0.4.176,sport是58825。所以可以看到應(yīng)用pod是記錄的源IP是10.0.4.176,丟失了源IP。
集群內(nèi)訪問SLB或者NodePort
1.24 Kubernetes之前版本
有Endpoint的節(jié)點(diǎn)上訪問,可以通,可以保留源IP
Nginx分布在ap-southeast-1.192.168.100.209和ap-southeast-1.192.168.100.208節(jié)點(diǎn),ap-southeast-1.192.168.100.210節(jié)點(diǎn)沒有Nginx pod。
從集群任意節(jié)點(diǎn)(本例就在209節(jié)點(diǎn))訪問有后端pod所在節(jié)點(diǎn)的ap-southeast-1.192.168.100.209的NodePort 31565端口,可以訪問。
從有后端pod所在節(jié)點(diǎn)ap-southeast-1.192.168.100.209訪問SLB 8.222.252.252 的80端口,可以訪問。
ap-southeast-1.192.168.100.209節(jié)點(diǎn)上是有NodePort 和SLB 的IPVS的規(guī)則的,但是只有該節(jié)點(diǎn)上后端Pod IP。
通過conntrack表可以到,這是由于在ap-southeast-1.192.168.100.209 節(jié)點(diǎn)上,相關(guān)的鏈路被dnat,最后是由pod 在ap-southeast-1.192.168.100.209 節(jié)點(diǎn)上的 的nginx-7d6877d777-2wh4s 192.168.100.222返回源,所有的相關(guān)轉(zhuǎn)化都在該節(jié)點(diǎn)上,所以TCP四層建連可以成功。
沒有Endpoint的節(jié)點(diǎn)上訪問,不能通,因?yàn)楣?jié)點(diǎn)上沒有相關(guān)的ipvs轉(zhuǎn)發(fā)規(guī)則
從集群任意節(jié)點(diǎn)(本例就在210節(jié)點(diǎn))訪問沒有后端pod所在節(jié)點(diǎn)的ap-southeast-1.192.168.100.210 的NodePort 31565端口或者SLB,不可以訪問。
也進(jìn)一步證實(shí),集群內(nèi)訪問關(guān)聯(lián)svc的SLB不出節(jié)點(diǎn),即使SLB有其他監(jiān)聽端口,訪問SLB其他端口也會(huì)拒絕。
查看該ap-southeast-1.192.168.100.210 節(jié)點(diǎn),并沒有相關(guān)的ipvs轉(zhuǎn)發(fā)規(guī)則,所以無法進(jìn)行dnat,訪問會(huì)失敗。
1.24 Kubernetes版本之后(含)
有Endpoint節(jié)點(diǎn)上訪問,可以通,可以保留源IP
與上文的1.24 Kubernetes之前版本集群內(nèi)訪問一致,可以參考上文描述。
沒有Endpoint節(jié)點(diǎn)上訪問:
Nginx分布在cn-hongkong.10.0.2.77和cn-hongkong.10.0.0.171節(jié)點(diǎn),所以在沒有Nginx的cn-hongkong.10.0.4.141節(jié)點(diǎn)上測試。
分別有以下幾種情況:
terway或后端為hostNetwork
節(jié)點(diǎn)訪問的通 NodePort(源 IP 是 ECS IP,不需要做 SNAT),無法保留源IP
可以看到?jīng)]有Endpoint的節(jié)點(diǎn)的NodePort 110.0.4.141:30745 的IPVS 的規(guī)則添加的Nginx的所有后端POD nginx-79fc6bc6d-8vctc 10.0.2.78 和 nginx-79fc6bc6d-j587w 10.0.0.172。
集群內(nèi)節(jié)點(diǎn)自身訪問沒有后端pod所在節(jié)點(diǎn)的cn-hongkong.10.0.4.141 的NodePort 30745/TCP端口,可以訪問。
通過conntrack表可以到,在cn-hongkong.10.0.4.141節(jié)點(diǎn)上,相關(guān)的鏈路被dnat,最后是由后盾Nginx pod nginx-79fc6bc6d-8vctc 10.0.2.78返回源。
而在nginx-79fc6bc6d-8vctc 10.0.2.78 所在的節(jié)點(diǎn)cn-hongkong.10.0.2.77上的conntrack表記錄的是10.04.141訪問10.0.2.78,并期望10.0.2.78直接返回10.0.4.141的的39530端口。
集群內(nèi)有endpoint 節(jié)點(diǎn)訪問沒有后端pod所在節(jié)點(diǎn)的ap-southeast-1.192.168.100.131 的NodePort 32292端口,不可以訪問,與上文1.24 Kubernetes版本之后(含) 集群外訪問一致,可以參考上文描述。
節(jié)點(diǎn)訪問不通 SLB IP(源 IP 是 SLB IP,沒有人做 SNAT)
可以看到?jīng)]有Endpoint的節(jié)點(diǎn)的SLB IP 的IPVS 的規(guī)則添加的Nginx的所有后端POD nginx-79fc6bc6d-8vctc 10.0.2.78 和 nginx-79fc6bc6d-j587w 10.0.0.172。
沒有Endpoint的節(jié)點(diǎn)上訪問 SLB 47.243.247.219,訪問確是超時(shí)。
通過conntrack表可以到,在沒有ep的節(jié)點(diǎn)訪問SLB的IP,可以看到期望的是后端pod返回給SLB IP。而SLB IP 在節(jié)點(diǎn)上已經(jīng)被kube-ipvs虛擬占位了,所以沒有做snat,造成無法訪問。
flannel并且后端為普通pod,可以訪問通,但是保留不了源IP
Nginx分布在cn-hongkong.10.0.2.86。
在cn-hongkong.10.0.4.176訪問SLB 47.242.86.39 是可以訪問成功的。
cn-hongkong.10.0.4.176節(jié)點(diǎn)的conntrack表可以看到是src和dst都是47.242.86.39,但是期望的是 nginx pod172.16.160.135 返回給 10.0.4.176 的54988端口,47.242.86.39 snat成10.0.4.176。
后端ep所在節(jié)點(diǎn)cn-hongkong.10.0.2.86,conntrack表記錄了src是10.0.4.176,sport是54988。所以可以看到應(yīng)用pod是記錄的源IP是10.0.4.176,丟失了源IP。
審核編輯:湯梓紅
-
網(wǎng)卡
+關(guān)注
關(guān)注
4文章
324瀏覽量
27887 -
客戶端
+關(guān)注
關(guān)注
1文章
298瀏覽量
17008 -
SVC
+關(guān)注
關(guān)注
0文章
33瀏覽量
12400 -
阿里云
+關(guān)注
關(guān)注
3文章
1006瀏覽量
43914 -
kubernetes
+關(guān)注
關(guān)注
0文章
240瀏覽量
8991
原文標(biāo)題:一次網(wǎng)絡(luò)不通"爭吵"引發(fā)的思考
文章出處:【微信號:OSC開源社區(qū),微信公眾號:OSC開源社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
STC-ISP下載失敗的原因和解決方法
BIOS錯(cuò)誤信息和解決方法
關(guān)于開關(guān)電源的電磁干擾問題研究和解決方法

采用MATLAB對SPWM進(jìn)行輔助設(shè)計(jì)與詳細(xì)分析和解決方法

51單片機(jī)用到strcmp比較字符串有的問題和解決方法說明

假焊的原因和解決方法
如何進(jìn)行MP3的簡易維修常見故障和解決方法資料免費(fèi)下載

三相電機(jī)一根線不通的原因及解決方法
GSM系統(tǒng)中干擾問題的分類、定位和解決方法

評論