kubernetes網絡之Flannel

簡介

Flannel是CoreOS團隊針對Kubernetes設計的一個網絡規劃服務,簡單來講,它的功能是讓集羣中的不一樣節點主機建立的Docker容器都具備全集羣惟一的虛擬IP地址。html

在默認的Docker配置中,每一個節點上的Docker服務會分別負責所在節點容器的IP分配。這樣致使的一個問題是,不一樣節點上容器可能得到相同的內外IP地址。並使這些容器之間可以之間經過IP地址相互找到,也就是相互ping通。node

Flannel的設計目的就是爲集羣中的全部節點從新規劃IP地址的使用規則,從而使得不一樣節點上的容器可以得到「同屬一個內網」且」不重複的」IP地址,並讓屬於不一樣節點上的容器可以直接經過內網IP通訊。docker

Flannel實質上是一種「覆蓋網絡(overlaynetwork)」,也就是將TCP數據包裝在另外一種網絡包裏面進行路由轉發和通訊,目前已經支持udp、vxlan、host-gw、aws-vpc、gce和alloc路由等數據轉發方式,默認的節點間數據通訊方式是UDP轉發。網絡

1、簡單總結flannel的特色

1.使集羣中的不一樣Node主機建立的Docker容器都具備全集羣惟一的虛擬IP地址。架構

2.創建一個覆蓋網絡(overlay network),經過這個覆蓋網絡,將數據包原封不動的傳遞到目標容器。覆蓋網絡是創建在另外一個網絡之上並由其基礎設施支持的虛擬網絡。覆蓋網絡經過將一個分組封裝在另外一個分組內來將網絡服務與底層基礎設施分離。在將封裝的數據包轉發到端點後,將其解封裝。併發

3.建立一個新的虛擬網卡flannel0接收docker網橋的數據,經過維護路由表,對接收到的數據進行封包和轉發(vxlan)。測試

4.etcd保證了全部node上flanned所看到的配置是一致的。同時每一個node上的flanned監聽etcd上的數據變化,實時感知集羣中node的變化。spa

flannel對網絡要求提出的解決方法 

1、互相不衝突的IP

1.flannel利用kubernetes Api經過ETCD存儲整個集羣的網絡配置,根據配置記錄集羣使用的網段設計

2.flannel在每一個主機上英雄flanneld做爲agent,它會爲所在主機從集羣的網絡地址空間中獲取一個小網段subnet,本主機內全部容器IP將從中分配3d

1)Node01節點

2)Node02節點

 

 

 

在flannel network中,每一個Pod都會分配一個惟一的IP地址,且每一個k8s Node的subnet不重疊

2、Pod之間互相訪問

1.flanneld將本機獲取的subnet以及主機之間通訊的public ip經過etcd存儲起來,須要時發給相應模塊

2.flanneld經過各類backend mechanism,如vxlan、udp等跨主機轉發容器之間的網絡流量,完成容器之間的跨主機通訊

Flannel架構原理

1、flannel架構圖和各組件

 

1.cni0:網橋設備,每建立一個Pod都會建立一對veth pair,其中一端是pod的eth0,另外一端是cni0網橋中的端口(網卡),Pod中從eth0的流量都會發送到cni端口(網卡)上

 

Cni0設備獲取到的地址,是分配到本機網段的第一個IP

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

 

3.flanneld:flannel會在每一個主機運營flanneld做爲agent,它會會主機在集羣網絡地址空間中獲取一個小網段,本機內全部容器的IP地址都從中分配;

                 同時flanneld會監聽etcd,爲flannel.1設備提供封裝時必要的mac、ip等網絡數據信息

2、不一樣node之間Pod通訊流程

1.pod中產生數據,根據pod的路由信息.將數據發送到cni0

2.cni0根據節點的路由表,將數據發送到隧道設備flannel.1

3.flannel.1查看數據包的目的IP,從flanneld獲取對端隧道設備的信息,封裝數據包

4.flannel.1將數據發送給對端設備,對端節點的網卡接收到數據包,發現是overlay數據包,解開外層封裝.併發送內層封裝到flannel.1設備

5.flannel.1查看數據包,根據路由表匹配,將數據發送給cni0設備

6.cni0匹配路由表,發送數據給網橋上對應的端口

具體的通訊流程

測試Node1的Pod和Node2的Pod通訊流程

Node1上的PodIP是:10.244.1.3,命名爲Pod1

Node2上的PodIP是:10.244.2.2,命名爲Pod3

1、Pod1中的容器到cni0設備

1)Pod1能Ping通Pod3

2)Ping包的dst ip爲10.244.2.2,根據路由表匹配到第二條路由表項,去往10.244.0.0/16的包都轉發給10.244.1.1

3)去宿主機Node1上查看cni0的IP地址是 10.244.1.1

2、cni0到flannel.1 (這一步在宿主機操做(Node1))

1)當icmp包到達cni0後,cni發現dst ip爲10.244.2.2,cni根據路由表來查找匹配項目

根據最小匹配原則,匹配到圖上的一條路由表,去往10.244.2.0網段的包,發送到10.244.2.0網關,網關設備是flannel.1

3、flannel.1(node1的flannel.1)

flannel .1爲vxlan設備,當數據包來到flannel.1時,須要將數據包封裝起來,此時的dest ip爲10.244.2.2,src ip爲10.244.1.3,數據包須要知道10.244.2.2的mac地址.此時flannel.1不會發送arp請求去得到10.244.2.2的mac地址,而是由Linux kernel將一個"L3 miss"事件請求發送給用戶空間的flanned程序.flanneld程序收到內核的請求事件後,從etcd查找可以匹配該地址的子網的flannel.1設備的mac地址;flannel在爲node分配ip網段時記錄了全部的網段和mac等信息,因此能知道,交互流程以下圖:↓↓↓

 

 

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

此時,vxlan的內層數據包就完成了封裝,格式以下所示

簡單總結這個流程

  1. 數據包到達flannel.1.經過查找路由表,知道數據包要經過flannel.1發往 10.244.2.0(對端flannel.1的設備地址)
  2. 經過apr cache表,知道了目的ip 10.244.2.0的mac地址(對端flannel.1的mac地址)
  3. kernel須要查看node上的fdb(forwarding database)以得到內層封裝包中目的veth設備所在的node地址.由於已經從arp table中查到目的設備mac地址爲e2:11:f0:43:33:fd,同時在fdb中存在該mac地址對應的node節點地址.若是fdb中沒有,kernel會向用戶空間的flanneld發起"L2 MISS"事件.flanneld收到該事件後,會查詢etcd,獲取該veth設備對應的node的"public ip",並將信息註冊到etcd

當內核得到了發往機器的IP地址後,arp獲得mac地址,以後就能完成vxlan的外層封裝

4、對端flannel.1(node02機器)

Node節點的eth0網卡接收到vxlan數據包,kernel將識別出這事一個vxlan數據包,將包拆開後轉給節點上的flannel.1設備,這樣數據包就從發送節點到達目的節點,flannel.1將收到這樣一個數據包

目的地址爲10. 244.2.2,flannel.1查找本身的路由表(node02上的flannel.1),根據路由表完成轉發

根據最小匹配原則,flannel.1將去往10.244.2.0的流量轉發到cni0上去

5、對端cni0到Pod(node02節點上的)

cni0是一個網橋設備.當cni0拿到數據包後,經過veth pair,將數據發送給pod.

1)查看node2節點中的網橋

 

2)在node2節點上經過arp解析能夠看出,10.244.2.2的mac地址爲:c2:33:c5:49:c0:0d 

 

3)該地址爲pod的網卡eth0的地址(node2的容器)

 

經過以上能夠看出,cni0經過veth pair把流量轉發給Pod3

簡單總結cni0轉發流量的原理

  1. 首先經過arp查找出ip地址對應的mac地址
  2. 將流量轉發給mac地址所在eth0網的對應的veth pair端口
  3. veth pair端口接收到流量,直接將流量注入到pod的eth0網卡上

 

 

 

 

 

 

 

http://www.javashuo.com/article/p-duswrgyf-cu.html參考

相關文章
相關標籤/搜索