Flannel原理

Flannel是 CoreOS 團隊針對 Kubernetes 設計的一個覆蓋網絡(Overlay Network)工具,其目的在於幫助每一個使用 Kuberentes 的 CoreOS 主機擁有一個完整的子網。這次的分享內容將從Flannel的介紹、工作原理及安裝和配置三方面來介紹這個工具的使用方法。 
一、Flannel介紹
Flannel是CoreOS團隊針對Kubernetes設計的一個網絡規劃服務,簡單來說,它的功能是讓集羣中的不同節點主機創建的Docker容器都具有全集羣唯一的虛擬IP地址。 

在Kubernetes的網絡模型中,假設了每個物理節點應該具備一段“屬於同一個內網IP段內”的“專用的子網IP”。例如: 
節點A:10.0.1.0/24節點B:10.0.2.0/24節點C:10.0.3.0/24
但在默認的Docker配置中,每個節點上的Docker服務會分別負責所在節點容器的IP分配。這樣導致的一個問題是,不同節點上容器可能獲得相同的內外IP地址。並使這些容器之間能夠之間通過IP地址相互找到,也就是相互ping通。 

Flannel的設計目的就是爲集羣中的所有節點重新規劃IP地址的使用規則,從而使得不同節點上的容器能夠獲得“同屬一個內網”且”不重複的”IP地址,並讓屬於不同節點上的容器能夠直接通過內網IP通信。 


二、Flannel的工作原理


Flannel實質上是一種“覆蓋網絡(overlay network)”,也就是將TCP數據包裝在另一種網絡包裏面進行路由轉發和通信,目前已經支持UDP、VxLAN、AWS VPC和GCE路由等數據轉發方式。 

默認的節點間數據通信方式是UDP轉發,在Flannel的GitHub頁面有如下的一張原理圖: 


這張圖的信息量很全,下面簡單的解讀一下。 

數據從源容器中發出後,經由所在主機的Docker0虛擬網卡轉發到flannel0虛擬網卡,這是個P2P的虛擬網卡,flanneld服務監聽在網卡的另外一端。 

Flannel通過Etcd服務維護了一張節點間的路由。 

源主機的flanneld服務將原本的數據內容UDP封裝後根據自己的路由表投遞給目的節點的flanneld服務,數據到達以後被解包,然後直 接進入目的節點的flannel0虛擬網卡,然後被轉發到目的主機的Docker0虛擬網卡,最後就像本機容器通信一下的有Docker0路由到達目標容 器。 

這樣整個數據包的傳遞就完成了,這裏需要解釋三個問題。 

第一個問題,UDP封裝是怎麼一回事? 

我們來看下面這個圖,這是在其中一個通信節點上抓取到的ping命令通信數據包。可以看到在UDP的數據內容部分其實是另一個ICMP(也就是ping命令)的數據包。 


原始數據是在起始節點的Flannel服務上進行UDP封裝的,投遞到目的節點後就被另一端的Flannel服務還原成了原始的數據包,兩邊的Docker服務都感覺不到這個過程的存在。 

第二個問題,爲什麼每個節點上的Docker會使用不同的IP地址段? 

這個事情看起來很詭異,但真相十分簡單。其實只是單純的因爲Flannel通過Etcd分配了每個節點可用的IP地址段後,偷偷的修改了Docker的啓動參數,見下圖。 


這個是在運行了Flannel服務的節點上查看到的Docker服務進程運行參數。 

注意其中的“--bip=172.17.18.1/24”這個參數,它限制了所在節點容器獲得的IP範圍。 

這個IP範圍是由Flannel自動分配的,由Flannel通過保存在Etcd服務中的記錄確保它們不會重複。 

第三個問題,爲什麼在發送節點上的數據會從Docker0路由到flannel0虛擬網卡,在目的節點會從flannel0路由到Docker0虛擬網卡? 

我們來看一眼安裝了Flannel的節點上的路由表。下面是數據發送節點的路由表: 


這個是數據接收節點的路由表: 


例如現在有一個數據包要從IP爲172.17.18.2的容器發到IP爲172.17.46.2的容器。根據數據發送節點的路由表,它只與 172.17.0.0/16匹配這條記錄匹配,因此數據從Docker0出來以後就被投遞到了flannel0。同理在目標節點,由於投遞的地址是一個容 器,因此目的地址一定會落在Docker0對於的172.17.46.0/24這個記錄上,自然的被投遞到了Docker0網卡。

轉載地址:http://udn.yyuap.com/thread-91725-1-1.html


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章