背景
- kubernetes:1.16.3
- Proxy mode:ipvs
問題
在同一個節點上,兩個Pod通過svc互相訪問超時
排查思路
- coredns漂移到node節點后,發現其中同節點上,dns解析會超時
- 因為dns是udp協議,抓包效果不好,隨即找到同節點內http協議的服務進行抓包驗證
- 抓包后,請求到達service vip的源地址(當前pod ip)和目的地址(vip)
- 而在回報時,卻發現通信變成了兩個pod之間直接通信

解決方法
方法一:
使用affinity調度,保證兩個存在相互調度關系的pod不會啟動在同一個節點上
方法二:
開發流量偽裝,修改kube-proxy配置文件
masqueradeAll: true
總結
kube-proxy
kube-proxy通過在每個節點上創建相同的ipvs規則(關閉rap),當pod訪問集群內svc(vip)時,請求會被當前節點vip接受,此時,ipvs會進行DNAT操作,而在回報時,兩個pod處於同一個veth-part的一面,此時流量並不會走網關,所以回報的時候源ip和目的ip都是兩個pod的ip,但是在請求發送時,目的ip為vip,此時會丟棄掉請求。
ipvs
- 當用戶請求到達 DS 時,請求報文會先經過內核空間中的 PREROUTING 鏈,此時源 IP 為CIP,目的 IP 為 VIP;
- 在 PREROUTING 規則鏈上進行檢查目的IP是否為本機,如果是的話將數據包送至 INPUT 鏈;
- 數據包到達INPUT鏈后,IPVS 會比對數據包請求的服務是否為集群服務,若是,修改數據包的目標 IP 地址為后端服務器 IP(這里需要根據各種算法計算,哪台 RS 更合適),再將數據包發至 POSTROUTING 鏈,此時報文的源 IP 為 CIP,目標 IP 為 RIP;
- POSTROUTING 鏈的作用就是選路,根據 INPUT 鏈中目標 IP,將數據包發送給 RS;
- RS 發現數據包中的目標 IP 是自己的 IP,此時它會開始構建響應報文發並回給 DS, 此時報文的源IP為RIP,目標IP為 CIP;
- DS 收到 RS 響應后,但在響應客戶端,會將源 IP 地址修改為自己的 VIP 地址,然后發送給客戶端,此時報文的源 IP 為 VIP,目標 IP 為 CIP;
參考鏈接
https://mp.weixin.qq.com/s/qIfwXpoC5odpIsQIcNxi5A
https://www.cnblogs.com/longgor/p/13588191.html
