Kubernetes網絡插件詳解 - Flannel篇
Kubernetes網絡插件詳解 - Flannel篇
Kubernetes本身并沒有自己實現容器網絡,而是借助CNI標準,通過插件化的方式來集成各種網絡插件,實現集群內部網絡相互通信。Kubernetes集群設計了Cluster IP、Node IP、Pod IP三種類型的通信IP:Cluster IP是Service對象的IP地址,實現Pod服務的負載均衡,外部網絡無法ping通,只在集群內部可以訪問使用,是一個虛擬的IP;Node IP是集群節點Node的IP地址,可以是物理機的IP(也可能是虛擬機IP);Pod IP是容器組Pod的IP地址,是在容器組初始化過程由Pause容器申請的IP地址。其中Pod IP是容器網絡接口CNI與具體的網絡插件來實現IP的申請及數據包的轉發。

Flannel是CoreOS開源的,Overlay模式的CNI網絡插件,Flannel在每個集群節點上運行一個flanneld的代理守護服務,為每個集群節點(HOST)分配一個子網(SUBNET),同時為節點上的容器組(POD)分配IP,在整個集群節點間構建一個虛擬的網絡,實現集群內部跨節點通信。Flannel的數據包在集群節點間轉發是由backend實現的,目前,已經支持核心官方推薦的模式有UDP、VXLAN、HOST-GW,以及擴展試用實驗的模式有IPIP,AWS VPC、GCE、Ali VPC、Tencent VPC等路由,其中VXLAN模式在實際的生產中使用最多。
核心模式
UDP模式
UDP模式簡單來說,就是數據報文在發送實際物理網絡之前,通過flanneld進行一層UDP封裝,將數據報文作為payload發送給對端,對端收到UDP報文之后,flanneld通過解包得到真正的數據報文后,再轉發至最終的服務端,如圖一所示。
UDP模式的核心點是虛擬網絡設備tun/tap,該設備一端連接協議棧,另外一端連接用戶程序,允許用戶程序像讀寫文件一樣進行收發數據包。tun/tap工作原理基本一致,tun模擬是三層網絡設備,收發的是IP層數據包;tap模擬是二層網絡設備,收發以太網數據幀。

在UDP模式,Flannel通過DaemonSet控制器,在每個節點啟動一個kube-flannel的Pod,同時會創建兩個虛擬網絡設備,cni0與flannel0,如圖二所示,其中cni0是linux bridge設備,而flannel0則是Tun設備。

在同一個Kubernetes集群中,Pod通信有同節點Pod通信及跨節點Pod通信兩種場景,其中同節點Pod通信,由于cni0是類二層轉發設備,可以直接實現數據包的轉發,所以同節點的Pod間通信,直接通過Linux bridge cni0來實現。跨節點Pod通信則是三層虛擬網絡設備Tun,也就是flannel0。當Pod數據包通過路由發送到flannel0上,節點主機上的flanneld進程就會收到IP包,并將IP包封裝在一個UDP包,通過物理網絡發送給目的宿主機。同理目的主機就會有UDP解包及轉發至Pod服務。
UDP模式比較簡單,但是由于flanneld運行在用戶態,而數據的交互和傳遞則在內核態完成,會經歷兩次的內核態和用戶態數據拷貝,性能損耗巨大,所以UDP模式已經逐漸廢棄。如圖四所示,是一個完成UDP模式數據包轉發過程及路由表。

VXLAN模式
VXLAN (Virtual Extensible LAN)是一種網絡虛擬化技術,它使用一種隧道協議將二層以太網幀封裝在四層UDP報文中,通過三層網絡傳輸,組成一個虛擬大二層網絡。VXLAN使用VTEP(VXLAN Tunnel Endpoint)來進行封包和解包:在發送端,源VTEP將原始報文封裝成VXLAN報文,通過UDP發送到對端VTEP;在接收端,VTEP將解開VXLAN報文,將原始的二層數據幀轉發給目的的接收方。VTEP可以是獨立的網絡設備,例如交換機,也可以是部署在服務器上的虛擬設備。例如使用置頂交換機(TOR)作為VTEP時,VXLAN的網絡模型如下圖:

Flannel默認和推薦的模式就是VXLAN,當使用默認配置安裝Flannel時,會為每個節點分配一個24位子網,并在每個節點上創建兩張虛機網卡cni0和flannel.1:其中cni0是一個網橋設備,節點上所有的Pod都通過veth pair的形式與cni0相連;而flannel.1則是一個VXLAN類型的設備,充當VTEP的角色實現對VXLAN報文的封包解包。
同節點Pod通信,與UDP模式一樣,通過cni0網橋完成,不涉及VXLAN報文的封包解包操作;跨節點Pod通信則是通過靜態配置路由表,ARP(address resolution protocol 地址解析協議)表和FDB表(Forwarding database二層設備中MAC地址和端口的關聯關系)的信息,通過VXLAN虛擬網卡flannel.1,實現了集群內所有Pod在同一個大二層網絡相互通信。還有VXLAN模式支持DirectRouting配置,DirectRouting=true是支持在相同子網情況下數據包直接通過路由轉發,與HOST-GW模式相同。

UDP模式和VXLAN模式都是屬于隧道方式,也就是在UDP的基礎之上,構建虛擬網絡,VXLAN模式只是將UDP模式的flanneld進程換成了VTEP設備,通過VTEP設備完成封包和解包的過程;另外一個關鍵點是VXLAN模式全過程全部在內核態完成,flannel.1充當網橋的角色,進行UDP數據包的轉發,所以性能要比UDP模式好很多。
HOST-GW模式
與UDP模式和VXLAN模式不同,HOST-GW模式屬于路由的方式,無需經過任何封包和解包,純路由機制實現,因此性能比較高。但是HOST-GW模式只支持宿主機之間二層連接,要求集群中所以節點必須處于同一個網絡中。如果不在一個網絡中,三層設備路由器缺少Pod 網絡的路由規則,無法轉發數據包。
HOST-GW模式將目的主機當作網關,直接路由原始的數據包。flanneld會在集群節點上創建并維護路由表,當數據包到達集群節點的時,就會根據路由表直接發送到下一跳,也就是同網段的節點IP,直接通過二層網絡將數據轉發到目的節點上;目的節點再根據路由表規則轉發到cni網橋,網橋根據路由規則轉發到容器里面。
HOST-GW模式通過路由轉發實現高性能網絡通信,但是這種模式局限性很大,節點之間都要相互有點對點的路由覆蓋,每個節點上有n-1個路由,而n個節點共有n(n-1)/2個路由,才能保證flannel的flat網絡能力。

擴展模式
IPIP模式
IPIP模式是一種簡單隧道方式,通過內核IPIP封裝數據包,開銷低但只能封裝ipv4單播通信,因此無法設置OSPF、RIP或任何其他基于多播的協議。
在IPIP模式,會有兩個IPIP隧道設備tunl0和flannel.ipip,其中tunl0由ipip的內核模塊,在modprobe ipip模塊的網絡命名空間(network namespace)自動創建,是命名空間默認IPIP設備,包含local=any和remote=any屬性,flannel.ipip是由flannel創建的一對多ipip設備。當接收到IPIP協議數據包時,內核在local/remote屬性中存在精確匹配src/dst的IP地址,就會解包轉到內部服務,否則會將數據包轉發到tunl0備用設備。同樣,還有IPIP模式也支持DirectRouting配置,DirectRouting=true是支持在相同子網情況下數據包直接通過路由轉發,與HOST-GW模式相同。

Cloud VPC
Kubernetes容器很多情況下都是部署在公有云之上,容器集群的網絡需要云其他產品互聯互通,Flannel支持公有云Cloud VPC模式,在AWS VPC,AliVPC,TencentCloud VPC運行容器集群,就可以直接使用VPC的路由表,將容器內部IP實時同步到路由表中,這樣容器內部IP與其他云產品相互通信,比如ELB就可以直接配置路由到容器內部,不過有的公有云要路由條數有限制,或者需要額外收費。
總結
總的來說,Kubernetes網絡比較復雜,主要是涉及到容器運行時CRI,容器網絡標準CNI,以及容器網絡插件三個方面配合及協調,同時在靈活易用及性能優化上持續演進。Flannel作為使用最廣網絡插件,主要具備兩大優勢:首先從UDP,VXLAN,HOST-GW到IPIP,不僅是場景覆蓋與性能的權衡演進,還有對底層操作核心能力的快速支持,社區一直保持活躍。其次開放與云平臺的集成,容器大部分運行環境都是在云平臺之上,與云平臺的集成直接使用底層云能力實現網絡能力,提供開箱即用且高效網絡方案,將云的能力最大化,始終貫徹云原生的理念。