flanneld,flannel和cni逐步深刻

這個問題,如今慢慢搞定。html

把這二者的關係搞清楚了。node

還有kubeadm join和手工安裝Node的故事,git

也沒那麼玄乎~github

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~docker

https://www.cnblogs.com/xzkzzz/p/9936467.html
https://segmentfault.com/a/1190000017182169
https://segmentfault.com/a/1190000017182169json


Flannel自己是一個框架,真正提供網絡功能是他的後端實現。目前支持三種後端實現:segmentfault

VXLAN
host-gw
UDP後端

kubernetes是經過一個叫CNI接口維護一個單獨網橋來代替docker0,這個網橋CNI網橋,默認叫作cni0.
過程也是和VXLAN是同樣的。須要注意的是,CNI網橋只是接管全部CNI插件負責的,既只是kubernetes建立的容器。服務器

kubernetes之因此要設置這樣一個與docker0網橋功能同樣的CNI網橋,主要緣由有兩點:網絡

kubernetes項目並無使用Docker的網絡模型,因此它不但願,也不具有配置docker0的能力。
還與kubernetes如何配置Pod,也就是infra容器Network Namespace相關。
咱們在部署kubernetes的時候,有一個步驟是安裝kubernetes-cni包,他的目的就是宿主機上安裝CNI插件所須要的基礎可執行文件。

ls /opt/cni/bin/
bridge dhcp flannel host-local ipvlan loopback macvlan portmap ptp sample tuning vlan
CNI的基礎可執行文件,按照功能分三類:

Main插件 他是用來建立具體網絡設備的二進制文件。例如:birdge(網橋設備)、ipvlan、lookback(lo 設備)、ptp(Veth Pair設備)、macvlan、vlan
IPAM插件 他是負責分配IP地址的二進制文件。例如:dhcp,這個文件會向dhcp服務器發起請求;host-local,則會使用預先配置的IP地址來進行分配。
CNI社區維護的內置CNI插件。例如 flannel,就是專門爲Flannel項目提供的CNI插件。
從二進制文件來看,若是實現一個kubernetes用的容器網絡方案,其實須要兩部分工做,以Flannel下項目爲例。

首先實現這個網絡自己,其實就是flanneld進程裏主要邏輯,例如:建立和配置flannel.1設備,配置宿主機路由、配置ARP和FDB表。
實現該網絡方案對應的CNI插件,就是配置infra容器裏的網絡棧,並把他鏈接在CNI網橋上。
接下來進行第一步,在宿主機上安裝flannel。而這個過程當中,flanneld啓動後會在每臺宿主機上生成他對應的CNI配置文件(就是configmap),從而告訴kubernetes,這個集羣要使用Flannel做爲容器網絡方案。

 

當kubelet組件須要建立pod時,他一個建立的必定是infra容器,因此這一步,dockershim 就會先調用Docker API建立並啓動infra容器,緊着執行一個叫作SetUpPod的方法,這個方法的做用是:爲CNI插件準備構建參數,而後調用CNI插件爲infra容器配置網絡。這裏要調用CNI插件是/opt/cni/bin/flannel;而調用它所需的參數,分兩部分:

第一部分,是由dockershim設置的一組CNI環境變量。其中,最重要的環境變量參數叫作:CNI_COMMAND。他的取值只有兩種ADD和DEL。這個ADD和DEL操做,就是CNI插件惟一實現的兩種方法。

ADD 把容器添加CNI網絡裏
DEL 把容器從CNI網絡裏移除
在網橋類型的CNI裏,這兩個操做說明把容器以「Veth Pair」方式插在CNI網橋上,或者從網橋上拔掉。

第二部分,是dockershim從CNI配置文件里加載到的默認插件的配置信息。這個配置信息在CNI中被叫做Network Configuration,dockershim會把Network Configuration 經過JSON數據的方式,經過標準輸入的方式傳遞給Flannel CNI插件。

建立容器網絡的流程就是:kubelet ——> flannel ——> flanneld。

工做原理
很容易混淆幾個東西。咱們一般說的Flannel(coreos/flannel),其實說的是flanneld。你們都知道Kubernetes是經過CNI標準對接網絡插件的,可是當你去看Flannel(coreos/flannel)的代碼時,並無發現它實現了CNI的接口。若是你玩過其餘CNI插件,你會知道還有一個二進制文件用來供kubele調用,而且會調用後端的網絡插件。對於Flannel(coreos/flannel)來講,這個二進制文件是什麼呢?git repo在哪裏呢?

這個二進制文件就對應宿主機的/etc/cni/net.d/flannel,它的代碼地址是https://github.com/containernetworking/plugins,最可恨的它的名字就叫作flannel,爲啥不相似contiv netplugin對應的contivk8s同樣,取名flannelk8s之類的。

上面的Flannel Pod中還有一個容器叫作install-cni,它對應的腳本在https://github.com/coreos/flannel-cni。

/opt/bin/flanneld --> https://github.com/coreos/flannel
/etc/cni/net.d/flannel --> https://github.com/containernetworking/plugins
/install-cni.sh --> https://github.com/coreos/flannel-cni


flannel for kubernetes
flannel在對kubernets進行支持時,flanneld啓動參數中會增長--kube-subnet-mgr參數,flanneld會初始化一個kubernetes client,獲取本地node的pod-cidr,這個pod-cidr將會做爲flannel爲node本地容器規劃的ip網段。記錄到/run/flannel/subnet.env。(flannel_cni組件會讀取這個文件並寫入到net-conf.json中,供cni使用)。

若是說flanneld爲Pod打通了一張跨node的大網,那麼CNI就是將各個終端Pod掛載到這張大網上的安裝工人。所以,如今咱們能夠將整個流程連起來了:flannel CNI插件首先讀取netconf配置和subnet.env信息,生成適用於bridge CNI插件的netconf文件和ipam(host-local)配置,並設置其delegate爲bridge CNI插件。而後調用走bridge CNI插件掛載容器到bridge的流程。因爲各個Pod的IP地址分配是基於host-local的Ipam,所以整個流程徹底是分佈式的,不會對API-Server形成太大的負擔。

相關文章
相關標籤/搜索