Flannel MAC 地址沖突導致 Pod 跨節點通信異常
問題背景
客戶在擴容 Kubernetes 節點后,發現部分服務 Pod 跨節點通信異常,表現為:
- Pod 間通信間歇性失敗;
- 某些業務服務異常或響應慢;
- 懷疑是網絡問題引起的。
問題排查
1?? 初步排查網絡路由信息
我們先檢查 flannel 的路由信息是否完整,執行如下命令查看:
# 查看所有節點上的 flannel 路由信息
kubectl get node -o yaml | grep -A3 flannel.alpha.coreos.com/backend-data
結果發現 多個節點的 flannel.1 接口的 VtepMAC 完全相同:
flannel.alpha.coreos.com/backend-data: '{"VtepMAC":"fe:22:77:eb:2f:a1"}'
?? 問題浮現 —— MAC 地址沖突!
2?? 查看物理網卡 MAC 地址是否一致
ip link show enp1s0
不同節點的物理網卡 MAC 地址是不同的,說明沖突不在物理網卡層面。
3?? 進一步查看 flannel.1 接口 MAC
ip -d link show flannel.1
可以看到 flannel.1 接口在多個節點上的 MAC 地址是一致的。
問題原因
?? 客戶的節點是通過 KVM 克隆創建的虛擬機,未對系統級唯一標識(如 /etc/machine-id)做處理,導致 MAC 地址生成邏輯一致,flannel 默認使用靜態策略(非隨機)生成 MAC 地址,從而出現沖突。
由于 flannel 使用 VXLAN 建立 overlay 網絡,VTEP MAC 地址用于 VXLAN 建隧道,一旦多個節點的 MAC 相同,會導致 FDB 表異常,轉發路徑錯誤,從而出現通信失敗。
解決方案
方式一:讓 flannel 接口 MAC 地址隨機生成
使用 systemd
的 .link
文件強制設置接口 MAC 策略為隨機:
# /etc/systemd/network/10-flannel.1.link
[Match]
OriginalName=flannel.1
[Link]
MACAddressPolicy=random
然后執行以下操作使配置生效:
# 重啟 systemd-networkd,或重啟節點
systemctl restart systemd-networkd
# 或重啟 flannel 容器
docker restart flannel-xxxx
這樣每次啟動都會為 flannel.1 分配一個不同的隨機 MAC,避免沖突。
問題延申:FDB 表未同步導致通信異常
由于MAC地址相同,還會導致fdb表異常,發現某節點無法訪問新增節點的 Pod 網絡,進一步排查:
/sbin/bridge fdb show flannel.1 | grep <mac地址>
發現 FDB 表存在舊的 MAC -> IP
映射,且未及時更新,導致節點pod網絡通過異常
此時執行:
# 重啟 flannel 容器或服務,重新注冊 FDB
docker restart flannel-xxxx
問題解決
總結思路
檢查項 | 內容 |
MAC 沖突 | 多節點 flannel.1 接口 MAC 是否一致 |
FDB 表 | 本地 FDB 映射是否含有錯誤記錄 |
flannel 狀態 | 是否在 VXLAN 模式、路由是否同步 |
節點創建方式 | 是否通過 VM 克隆,是否處理 machine-id |
快速修復 | 重啟 flannel 服務或容器 |
?? 建議
- 虛擬機克隆后建議清理
machine-id
并重新生成; - 使用
MACAddressPolicy=random
保證 overlay 網絡接口唯一; - 定期巡檢 flannel 路由表、FDB 表等底層數據;
- 可使用 CNI 替代方案(如 Calico)更強的網絡控制策略。