概述
flannel是CoreOS提供用于解決Dokcer集群跨主機通訊的覆蓋網絡工具。它的主要思路是:預先留出一個網段,每個主機使用其中一部分,然后每個容器被分配不同的ip;讓所有的容器認為大家在同一個直連的網絡,底層通過UDP/VxLAN等進行報文的封裝和轉發。
架構圖
跨主機容器通信
這里涉及到一個知識點,就是底層通過UDP/VxLAN設備進行報文的封裝和轉發,以下來敘述一下這個過程,當報文從Pod1:10.1.15.2/24要去往Pod4: 10.1.20.2/24這個容器的時候,要分別經過以下步驟。
- 因為Pod1的veth0和Docker0的一段網卡相連,所以數據包會先發往docker0網橋,此時docker0會查詢自己所維護的路由表,沒有發現有10.1.20.2/24這個地址,所以會把數據包發送給默認路由,這里的默認路由即flannel網橋。
- flannel網橋是一個VxLAN設備,它收到數據包后,檢查到包中的目的地址并不是自己的地址,所以他本應該這把這個數據包重新發送出去,因為他的下一層已經是數據鏈路層,所以即將進行二層封包,即通過ARP協議來對以太網進行廣播誰是10.1.20.2/24,接受并記錄目的的mac地址。但是由于它是一個VxLAN設備,其特殊性就是并沒有真正在二層發出這個 arp 包,而是由 linux kernel 引發一個”L3 MISS”事件并將 arp 請求發到用戶空間的 Flannel 程序中。
- flannel程序接收到”L3 MISS”事件以及 arp 請求 (who is10.1.20.2/24 ) 后,并不會像以太網發送ARP請求,而是在etcd中匹配10.1.20.2/24的信息,從而找到Node2的MAC地址。Flannel 將查詢到的信息放入 Node1 host 的 arp cache 表中,flannel0 完成這項工作后,Linux kernel 就可以在 arp table 中找到 10.1.20.2/24對應的 MAC 地址并封裝二層以太包了。
- Node 上 2 的 eth0 接收到上述 VXLAN 包,內核也識別出這是一個 VXLAN 包,于是通過相反的步驟解包出來,最后傳達到POD4上去。
本文參考了大量資料,并結合作者的理解,歡迎大家討論。