K8S中常用的網路外掛程式之Flannel

2021-10-11 08:01:03 字數 3312 閱讀 9661

kubernetes中解決網路跨主機通訊的乙個經典外掛程式就是flannel。flannel實質上只是乙個框架,真正為我們提供網路功能的是後端的flannel實現,目前flannel後端實現的方式有三種:

1、udp

2、vxlan

3、host-gw

udp是最早的實現方式,但是由於其效能原因,現已經被廢棄,但是udp模式是最直接,也最容易理解的跨主機實現方式。

假設有兩台node

node01上有容器nginx01,其ip為172.20.1.107,其docker0的位址為172.20.1.1/24;

node02上有容器nginx02,其ip為172.20.2.133,其docker0的位址為172.20.2.1/24;

那麼現在nginx01要訪問nginx02,其流程應該是怎麼樣的呢?

1)首先從nginx01傳送ip包,源ip是172.20.1.107,目的ip是172.20.2.133。

2)由於目的ip並不在node01上的docker0網橋裡,所以會將包通過預設路由**到docker0網橋所在的宿主機上;

3)通過本地的路由規則,**到下乙個目的ip,我們可以通過ip route檢視本地的路由資訊,通過路由資訊可以看到它被**到乙個flannel0的裝置中;

4)flannel0裝置會把這個ip包交給建立這個裝置的應用程式,也就是flannel程序(從核心狀態向使用者狀態切換);

5)flannel程序收到ip包後,將這個包封裝在udp中,就根據其目的位址將其**給node02(通過每個宿主機上監聽的8285埠),這時候的源位址是node01的位址,目的位址是node02的位址;

6)node02收到包後,就會直接將其**給flannel0裝置,然後進行解包,匹配本地路由規則**給docker0網橋,然後docker0網橋就扮演二層交換機的功能,將包**到最終的目的地;

流程圖如下:

注意:1)flannel0是乙個tun裝置,它的作用是在作業系統和應用程式之間傳遞ip包;

2)flannel是根據子網(subnet)來檢視ip位址對應的容器是執行在那個node上;

3)這些子網和node的對應關係,是儲存在etcd中(僅限udp模式);

4)udp模式其實是乙個三層的overlay網路;它首先對發出的ip包進行udp封裝,然後接收端對包進行解封拿到原始ip,進而把這個包**給目標容器。這就好比flannel在不同的宿主機上的兩容器之間打通了一條隧道,使得這個兩個ip可以通訊,而無需關心容器和宿主機的分布情況;

udp之所以被廢棄是主要是由於其僅在發包的過程中就在使用者態和核心態進行來回的資料交換,這樣的效能代價是很高的。如下:

vxlan:virtual extensible lan(虛擬可擴充套件區域網),是linux核心本身就支援的一種虛擬化網路技術,它可以完全在核心態實現上述的封裝和解封裝過程,減少使用者態到核心態的切換次數,把核心的處理邏輯都放到核心態,其通過與前面相似的隧道技術,構建出覆蓋網路或者疊加網路(overlay network)。

其設計思想為在現有的三層網路下,疊加一層虛擬的並由核心vxlan維護的二層網路,使得連線在這個二層網路上的主機可以像在區域網一樣通訊。

為了能夠在二層網路中打通隧道,vxlan會在宿主機上設定乙個特殊的網路裝置作為隧道的兩端,這個隧道就叫vtep(virtual tunnel end point 虛擬隧道端點)。而vtep的作用跟上面的flanneld程序非常相似,只不過它進行封裝和解封的物件是二層的資料幀,而且這個工作的執行流程全部在核心中完成。

其流程如下:

我們可以看到每台node上都有乙個flannel.1的網絡卡,它就是vxlan所需要的vtep裝置,它既有ip位址,也有mac位址。

現在我們nginx01要訪問nginx02,其流程如下:

1)nginx01傳送請求包會被**到docker0;

2)然後會通過路由**到本機的flannel,1;

3)flannel.1收到包後通過arp記錄找到目的mac位址,並將其加原始包上,封裝成二層資料幀(將源mac位址和目的mac位址封裝在它們對應的ip頭外部);

4)linux核心把這個資料幀封裝成普通的可傳輸的資料幀,通過宿主機的eth0進行傳輸(也就是在原有的資料幀上面加乙個vxlan頭vni,它是識別某個資料幀是不是歸自己處理的的重要標識,而在flannel中,vni的預設值就是1,這是由於宿主機上的vtep裝置名稱叫flannel.1,這裡的1就是vni的值);

5)然後linux核心會把這個資料幀封裝到udp包裡發出去;

6)node02收到包後發現vni為 1,linux核心會對其進行解包,拿到裡面的資料幀,然後根據vni的值把它交給node02上的flannel.1裝置,然後繼續進行接下來的處理;

在這種場景下,flannel.1裝置實際扮演的是乙個網橋的角色,在二層網路進行udp包的**,在linux核心中,網橋裝置進行**的依據是乙個叫做fdb(foewarding database)的**資料庫,它的內容可以通過bridge fdb命令可以檢視。

前面的兩種模式都是二層網路的解決方案,對於三層網路,flannel提供host-gw解決方案。

以下是host-gw示意圖:

如上所示,如果我nginx01要訪問nginx02,流程如下:

1)**請求包會被**到cni0;

2)到達本機後會匹配本機的路由,如上的路由資訊,然後發現要到172.20.2.0/24的請求要經過eth0出去,並且嚇一跳位址為172.16.1.130;

3)到達node2過後,通過路由規則到node02的cni0,再**到nginx02;

其工作流程比較簡單,主要是會在節點上生成許多路由規則。

host-gw的工作原理就是將flannel的所有子網的下一跳設定成該子網對應的宿主機的ip位址,也就是說host會充當這條容器通訊路徑的閘道器,當然,flannel子網和主機的資訊會儲存在etcd中,flanneld程序只需要watch這個資料的變化,然後實時更新路由表。

在這種模式下,就免除了額外的封包解包的效能損耗,在這種模式下,效能損耗大約在10%左右,而xvlan隧道的機制,效能損耗大約在20%~30%。

從上面可以知道,host-gw的工作核心為ip包在封裝成幀傳送出去的時候會在使用路由表中寫下一跳來設定目的的mac位址,這樣它就會經過二層**到達目的宿主機。這就要求集群宿主機必須是二層連通的。

要修改flannel模式就修改如下配置:

n

et-conf.json: |

} net-conf.json: |

}

k8s中常用的命令

1 刪除改資料夾所有yaml檔案的啟動的k8s服務 kubectl delete f 2 啟動改路徑下的所有yaml檔案的k8s服務 3 檢視乙個命名空間下的所有pod的啟動運 況 kubectl get pods n 命令空間4 檢視乙個命名空間下所有的服務情況 kubectl get svc n...

k8s 安裝flannel網路外掛程式

master node01節點 同樣安裝步驟 mkdir p etc cni net.d cat name cbr0 type flannel delegate isdefaultgateway true eofmkdir usr share oci umount oci umount.d p mk...

k8s網路之cilium網路

cilium是一種開源網路實現方案,與其他網路方案不同的是,cilium著重強調了其在網路安全上的優勢,可以透明的對kubernetes等容器管理平台上的應用程式服務之間的網路連線進行安全防護。cilium在設計和實現上,基於linux的一種新的核心技術ebpf,可以在linux內部動態插入強大的安...