k8s網絡原理之flannel


首先當你創建一個k8s集群后一般會存在三種IP分別是,Pod IP,Node IP,Cluster IP

其中一個Cluster IP之下包含多個Node IP,而一個Node IP之下又包含多個Pod IP,同一個Pod包含多個容器,這些容器的網絡都在同一個命名空間,因此它們可以自由的通信,同一個Node包含多個Pod,這些Pod又通過veth pair技術與同一個cni網橋進行連接,通常這個cni網橋就是我們熟知的docker0網卡,這個是在你安裝docker后就會創建在宿主機上的一個虛擬網卡,因此相同Node節點下的Pod又可以通過cni網橋進行通信。(這部分的知識我們在docker網絡當中有詳細的講解,不了解的同學可以查看之前的微博。)

那么不同Node節點下的Pod又是如何進行通信的呢?本文重點要講的flannel網絡插件就是用來解決這個問題的。

一.在這里有必要先介紹一下flannel

Flannel是CoreOS團隊針對Kubernetes設計的一個網絡規划服務,他的作用就是實現Pod資源跨主機進行網絡通信。
我們知道在默認的Docker配置中,每個節點上的Docker服務會分別負責所在節點容器的IP分配。這樣導致的一個問題是,不同節點上容器可能獲得相同的內外IP地址。
那么flannel可以讓集群中的不同節點主機創建的Docker容器都具有全集群唯一的虛擬IP地址,使得不同節點上的容器能夠獲得“同屬一個內網”且”不重復的”IP地址,並讓屬於不同節點上的容器能夠直接通過內網IP通信。

二.那么簡單總結下flannel的作用有以下幾點:

1.使集群中的不同Node主機創建的Docker容器都具有全集群唯一的虛擬IP地址。
2.建立一個覆蓋網絡(overlay network),通過這個覆蓋網絡,將數據包原封不動的傳遞到目標容器。覆蓋網絡是建立在另一個網絡之上並由其基礎設施支持的虛擬網絡。覆蓋網絡通過將一個分組封裝在另一個分組內來將網絡服務與底層基礎設施分離。在將封裝的數據包轉發到端點后,將其解封裝。
3.創建一個新的虛擬網卡flannel0接收docker網橋的數據,通過維護路由表,對接收到的數據進行封包和轉發(vxlan)。
4.etcd保證了所有node上flanned所看到的配置是一致的。同時每個node上的flanned監聽etcd上的數據變化,實時感知集群中node的變化。

三.flannel網絡架構的IP地址規划

flannel在每個主機中運行flanneld作為agent,它會為所在主機從集群的網絡地址空間中,獲取一個小的網段subnet,本主機內所有容器的IP地址都將從中分配。
如測試環境中ip分配:
1.master節點

2.node1

3.node2


在flannel network中,因為每個K8s node節點的subnet各不重疊,沒有交集,因此各節點下的每個pod也都會被分配唯一的ip地址。

四.flannel網絡架構原理圖

這里借用官網的原理圖講解下各組件的功能:
1.Cni0:網橋設備,每創建一個pod都會創建一對 veth pair。其中一端是pod中的eth0,另一端是Cni0網橋中的端口(網卡)。Pod中從網卡eth0發出的流量都會發送到Cni0網橋設備的端口(網卡)上。

Cni0 設備獲得的ip地址是該節點分配到的網段的第一個地址。

2.Flannel.1: overlay網絡的設備,用來進行 vxlan 報文的處理(封包和解包)。不同node之間的pod數據流量都從overlay設備以隧道的形式發送到對端。

3.Flanneld:flannel在每個主機中運行flanneld作為agent,它會為所在主機從集群的網絡地址空間中,獲取一個小的網段subnet,本主機內所有容器的IP地址都將從中分配。同時Flanneld監聽K8s集群數據庫,為flannel.1設備提供封裝數據時必要的mac,ip等網絡數據信息。

不同node上的pod的通信流程:

pod中產生數據,根據pod的路由信息,將數據發送到Cni0虛擬網橋設備(docker0)
Cni0虛擬網橋設備根據node節點的路由表,將數據發送到隧道設備flannel.1
Flannel.1查看數據包的目的ip,從flanneld獲得對端隧道設備的必要信息(node節點對應的Mac地址),並對數據包進行封裝。
Flannel.1將數據包發送到對端設備。對端節點的網卡接收到數據包,發現數據包為overlay數據包,解開外層封裝,並發送內層封裝到flannel.1設備。
Flannel.1設備查看數據包,根據目的node節點的路由表匹配規則,將數據發送給Cni0虛擬網橋設備。
Cni0虛擬網橋匹配Node節點路由表,將數據發送給網橋上對應的端口從而將數據傳輸給對應的目的pod。

不同node節點的pod的通信流程詳解:

以不同node節點的Pod1 ping Pod3為例
1.pod1到cni0
首先Pod1與Pod3能夠互相ping通

Ping包的dst ip 為192.20.1.43,根據路由匹配到最后一條路由表項,去往192.20.0.0/12的包都轉發給192.20.0.1

192.20.0.1為cni0的ip地址

2.cni0到flannel1

根據最長匹配原則,匹配到圖上的一條路由表項。去往192.20.1.0/24 網段的包,發送192.20.1.0網關,網關設備是flannel.1
3.源node節點flannel1對數據包進行封裝處理並發到遠端node節點的flannel1網絡接口

flannel.1為vxlan設備,當數據包來到flannel.1時,需要將數據包封裝起來。此時的dst ip 為192.20.1.43,src ip為192.20.0.51。數據包繼續封裝需要知道192.20.1.43 ip地址對應的mac地址。此時,flannel.1不會發送arp請求去獲得192.20.1.42的mac地址,而是由Linux kernel將一個“L3 Miss”事件請求發送給用戶空間的flanned程序。Flanned程序收到內核的請求事件之后,從etcd查找能夠匹配該目的地址的子網的flannel.1設備的mac地址,即發往的pod所在host中flannel.1設備的mac地址。Flannel在為Node節點分配ip網段時記錄了所有的網段和mac等信息,所以能夠知道。交互流程如下圖所示:

flanned將查詢到的信息放入master node host的arp cache表中:

到這里,vxlan的內層數據包就完成了封裝。格式是這樣的:

4.目的node節點flannel1接收到數據包之后
Node節點的eth0網卡接收到vxlan設備包,kernal將識別出這是一個vxlan包,將包拆開之后轉給節點上的flannel.1設備。這樣數據包就從發送節點到達目的節點,flannel.1設備將接收到一個如下的數據包:

目的地址為192.20.1.43,flannel.1查找自己的路由表,根據路由表完成轉發。

根據最長匹配原則,flannel.1將去往192.20.1.0/24的流量轉發到cni0上去。
5.cni0到pod
cni0是一個虛擬網橋設備。當cni0拿到數據包之后,通過veth pair,將數據包發送給pod。
在node節點上通過arp解析可以開出,192.20.1.43的mac地址為 66:57:8e:3d:00:85

該地址為pod的網卡eth0的地址

在獲知目的pod mac地址后,cni0會通過veth pair將數據包發到pod eth0網卡veth pair接口,至此不同node 節點的通信圓滿結束。

總結:本文詳細介紹了K8s如何通過cni網絡插件flannel完成了不同node節點也就是跨主機pod的通信,這部分的知識對於k8s集群來說十分重要,希望可以方便大家的理解,並在今后的使用和運維當中游刃有余。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM