【Kubernetes】兩篇文章 搞懂 K8s 的 fannel 網絡原理


近期公司的flannel網絡很不穩定,花時間研究了下並且保證雲端自動部署的網絡能夠正常work。

1.網絡拓撲

拓撲如下:(點開看大圖) 輸入圖片說明

  1. 容器網卡通過docker0橋接到flannel0網卡,而每個host對應的flannel0網段為 10.1.x.[1-255]/24,而flannel所組成的一個跨host的網段為10.1.x.x/16,而flannel0則為flanneld進程虛擬出來的網卡。
  2. docker0的地址是由 /run/flannel/subnet.env 的 FLANNEL_SUBNET 參數決定的。

2.HostA的Container1和HostB的Container2如何通信

host A的container1請求host B的container2的的數據時,流程如下:

  1. 根據host A的路由規則 "10.1.15.0 0.0.0.0 255.255.255.0 U 0 0 0 docker0“ 數據交給docker0處理。
  2. docker0會收到數據,然后根據路由規則 ”10.1.0.0 0.0.0.0 255.255.0.0 U 0 0 0 flannel0" 數據被交由給flannel0網卡處理。 flanneld會把數據封包然后送給eth0,用udp協議發送到對方host的eth0網卡。
  3. host B的 eth0網卡收到后,根據路由規則 10.1.0.0 0.0.0.0 255.255.0.0 U 0 0 0 flannel0" 則交給flannel0網卡處理。
  4. flanneld會把數據解包,根據路由規則 “10.1.20.0 0.0.0.0 255.255.255.0 U 0 0 0 docker0" 交給docker0處理。
  5. 則host B的container 2 將會收到數據。
    至此網路通信解釋完畢。

3.自動部署程序中添加物理機需要注意的地方

基於上,故而:

    1. 網卡docker0、flannel0網卡的正確建立。
    2. 路由被正確配置!10.1.x.[1-255]/24 和 10.1.x.x/16 兩個網段的正確路由配置。
    3. 我們的網絡環境檢查都基於此。通常情況下,以上兩者可以自動正確建立成功,但有時候會出現異常。
    4. 添加物理機時候檢查網絡環境 ifconfig docker0 和 flannel0並且需要正確配置路由規則。
    5. flanneld的udp端口2375需要添加到iptables例外。

 

 

一篇文章帶你了解Flannel

摘要:Flannel是 CoreOS 團隊針對 Kubernetes 設計的一個覆蓋網絡(Overlay Network)工具,其目的在於幫助每一個使用 Kuberentes 的 CoreOS 主機擁有一個完整的子網。這次的分享內容將從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頁面有如下的一張原理圖: 
一篇文章帶你了解Flannel

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

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

Flannel通過Etcd服務維護了一張節點間的路由表,在稍后的配置部分我們會介紹其中的內容。 

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

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

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

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

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

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

這個事情看起來很詭異,但真相十分簡單。其實只是單純的因為Flannel通過Etcd分配了每個節點可用的IP地址段后,偷偷的修改了Docker的啟動參數,見下圖。 
一篇文章帶你了解Flannel

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

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

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

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

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

這個是數據接收節點的路由表: 
一篇文章帶你了解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網卡。 

第三部分:Flannel的安裝和配置

Flannel是Golang編寫的程序,因此的安裝十分簡單。 

從  https://github.com/coreos/flannel/releases和  https://github.com/coreos/etcd/releases分別下載Flannel和Etcd的最新版本二進制包。 

解壓后將Flannel的二進制文件“flanneld”和腳本文件“mk-docker-opts.sh”、以及Etcd的二進制文件“etcd”和“etcdctl”放到系統的PATH目錄下面安裝就算完成了。 

配置部分要復雜一些。 

首先啟動Etcd,參考  https://github.com/coreos/etcd ... overy。 

訪問這個地址:  https://discovery.etcd.io/new?size=3 獲得一個“Discovery地址” 

在每個節點上運行以下啟動命令: 
1 etcd -initial-advertise-peer-urls http://<當前節點IP>:2380 -listen-peer-urls http://<當前節點IP>:2380 -listen-client-urls http://<當前節點IP>:2379,http://<當前節點IP>:2379 -advertise-client-urls http://<當前節點IP>:2379  -discovery <剛剛獲得的Discovery地址> &

啟動完Etcd以后,就可以配置Flannel了。 

Flannel的配置信息全部在Etcd里面記錄,往Etcd里面寫入下面這個最簡單的配置,只指定Flannel能用來分配給每個Docker節點的擬IP地址段: 
etcdctl set /coreos.com/network/config '{ "Network": "172.17.0.0/16" }'

然后在每個節點分別啟動Flannel: 
flanneld &

最后需要給Docker動一點手腳,修改它的啟動參數和docker0地址。 

在每個節點上執行: 
sudo mk-docker-opts.sh -i
source /run/flannel/subnet.env
sudo rm /var/run/docker.pid
sudo ifconfig docker0 ${FLANNEL_SUBNET} 


重啟動一次Docker,這樣配置就完成了。 

現在在兩個節點分別啟動一個Docker容器,它們之間已經通過IP地址直接相互ping通了。 

到此,整個Flannel集群也就正常運行了。 

最后,前面反復提到過Flannel有一個保存在Etcd的路由表,可以在Etcd數據中找到這些路由記錄,如下圖。 
一篇文章帶你了解Flannel
 
 
 
參考資料:
docker下基於flannel的overlay網絡分析:  https://my.oschina.net/xue777hua/blog/488345

一篇文章帶你了解Flannel:  http://www.open-open.com/news/view/1aa473a/

DockOne技術分享(十八):一篇文章帶你了解Flannel:  http://dockone.io/article/618

成為Docker Commiter需要具備哪些技術能力?:  http://dockone.io/question/196

強烈推薦系列文章:  http://dockone.io/topic/%E5%BE%AE%E4%BF%A1%E5%88%86%E4%BA%AB

etcd的簡單使用:  http://www.cnblogs.com/opama/p/5836674.html

 
二層交換、路由和三層交換:  http://blog.sina.com.cn/s/blog_43c625f101012euf.html

二層交換與三層交換本質區別:  http://bbs.51cto.com/thread-724918-1.html

二層交換、三層交換和路由的原理及區別:  http://blog.csdn.net/chenfei_5201213/article/details/7879438

二層和三層轉發:  http://blog.csdn.net/blueoceanindream/article/details/6413262

二層交換與三層IP轉發:  http://blog.csdn.net/muaxi8/article/details/51953082

常說的二層跟三層有什么區別?:  http://bbs.c114.net/asktech/question.php?qid=17795

 
 
https://github.com/coreos/flannel
圖解:  https://raw.githubusercontent.com/coreos/flannel/master/packet-01.png

Pipework、Weave、Flannel各自的優勢和區別:  http://dockone.io/question/259

Kubernets,Flannel,Docker網絡性能深度測試:  http://www.tuicool.com/articles/JNNFz2f

Docker網絡詳解及pipework源碼解讀與實踐:  http://www.infoq.com/cn/articles/docker-network-and-pipework-open-source-explanation-practice/#anch142208

圖解:  http://cdn2.infoqstatic.com/statics_s1_20161214-0550/resource/articles/docker-network-and-pipework-open-source-explanation-practice/zh/resources/1419560200174.png

尷尬的VXLAN:  http://www.c114.net/news/211/a876004.html

【華為悅讀匯】技術發燒友:認識VXLAN:  http://support.huawei.com/huaweiconnect/enterprise/thread-334207.html

隧道和網絡虛擬化:NVGRE vs VXLAN:  http://www.sdnlab.com/11819.html

 

 

 


免責聲明!

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



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