摘要:即配置網(wǎng)絡(luò)和解除網(wǎng)絡(luò)配置。類類型的插件,在執(zhí)行命令時(shí)會(huì)分配一個(gè)給調(diào)用者。執(zhí)行命令時(shí)會(huì)將調(diào)用者指定的放回池。向刪除時(shí),同樣通過請(qǐng)求,解除該的租約。組件通常在組件執(zhí)行完畢后執(zhí)行
目前不論是個(gè)人還是企業(yè),在使用k8s時(shí),都會(huì)采用CNI作為集群網(wǎng)絡(luò)方案實(shí)現(xiàn)的規(guī)范。
在早先的k8s版本中,kubelet代碼里提供了networkPlugin,networkPlugin是一組接口,實(shí)現(xiàn)了pod的網(wǎng)絡(luò)配置、解除、獲取,當(dāng)時(shí)kubelet的代碼中有個(gè)一個(gè)docker_manager,負(fù)責(zé)容器的創(chuàng)建和銷毀,亦會(huì)負(fù)責(zé)容器網(wǎng)絡(luò)的操作。而如今我們可以看到基本上kubelet的啟動(dòng)參數(shù)中,networkPlugin的值都會(huì)設(shè)置為cni。
cni插件的使用方式使用CNI插件時(shí),需要做三個(gè)配置:
kubelet啟動(dòng)參數(shù)中networkPlugin設(shè)置為cni
在/etc/cni/net.d中增加cni的配置文件,配置文件中可以指定需要使用的cni組件及參數(shù)
將需要用到的cni組件(二進(jìn)制可執(zhí)行文件)放到/opt/cni/bin目錄下
所有的cni組件都支持兩個(gè)命令:add和del。即配置網(wǎng)絡(luò)和解除網(wǎng)絡(luò)配置。
cni插件的配置文件是一個(gè)json文件,不同版本的接口、以及不同的cni組件,有著不同的配置內(nèi)容結(jié)構(gòu),目前比較通用的接口版本是0.3.1的版本。
在配置文件中我們可以填入多個(gè)cni組件,當(dāng)這些cni組件的配置以數(shù)組形式記錄時(shí),kubelet會(huì)對(duì)所有的組件進(jìn)行按序鏈?zhǔn)秸{(diào)用,所有組件調(diào)用成功后,視為網(wǎng)絡(luò)配置完成,過程中任何一步出現(xiàn)error,都會(huì)進(jìn)行回滾的del操作。以保證操作流上的原子性。
幾種基本的cni插件cni插件按照代碼中的存放目錄可以分為三種:ipam、main、meta。
ipam cni用于管理ip和相關(guān)網(wǎng)絡(luò)數(shù)據(jù),配置網(wǎng)卡、ip、路由等。
main cni用于進(jìn)行網(wǎng)絡(luò)配置,比如創(chuàng)建網(wǎng)橋,vethpair、macvlan等。
meta cni有的是用于和第三方CNI插件進(jìn)行適配,如flannel,也有的用于配置內(nèi)核參數(shù),如tuning
由于官方提供的cni組件就有很多,這里我們?cè)敿?xì)介紹一些使用率較高的組件。
ipam類CNIipam類型的cni插件,在執(zhí)行add命令時(shí)會(huì)分配一個(gè)IP給調(diào)用者。執(zhí)行del命令時(shí)會(huì)將調(diào)用者指定的ip放回ip池。社區(qū)開源的ipam有host-local、dhcp。
host-local我們可以通過host-local的配置文件的數(shù)據(jù)結(jié)構(gòu)來搞懂這個(gè)組件是如何管理ip的。
type IPAMConfig struct { *Range Name string Type string `json:"type"` Routes []*types.Route `json:"routes"`//交付的ip對(duì)應(yīng)的路由 DataDir string `json:"dataDir"`//本地ip池的數(shù)據(jù)庫(kù)目錄 ResolvConf string `json:"resolvConf"`//交付的ip對(duì)應(yīng)的dns Ranges []RangeSet `json:"ranges"`//交付的ip所屬的網(wǎng)段,網(wǎng)關(guān)信息 IPArgs []net.IP `json:"-"` // Requested IPs from CNI_ARGS and args } #配置文件范例: { "cniVersion": "0.3.1", "name": "mynet", "type": "ipvlan", "master": "foo0", "ipam": { "type": "host-local", "resolvConf": "/home/here.resolv", "dataDir": "/home/cni/network", "ranges": [ [ { "subnet": "10.1.2.0/24", "rangeStart": "10.1.2.9", "rangeEnd": "10.1.2.20", "gateway": "10.1.2.30" }, { "subnet": "10.1.4.0/24" } ], [{ "subnet": "11.1.2.0/24", "rangeStart": "11.1.2.9", "rangeEnd": "11.1.2.20", "gateway": "11.1.2.30" }] ] } }
從上面的配置我們可以清楚:
host-local組件通過在配置文件中指定的subnet進(jìn)行網(wǎng)絡(luò)劃分
host-local在本地通過指定目錄(默認(rèn)為/var/lib/cni/networks)記錄當(dāng)前的ip pool數(shù)據(jù)
host-local將IP分配并告知調(diào)用者時(shí),還可以告知dns、路由等配置信息。這些信息通過配置文件和對(duì)應(yīng)的resolv文件記錄。
host-local的應(yīng)用范圍比較廣,kubenet、bridge、ptp、ipvlan等cni network插件都被用來和host-local配合進(jìn)行ip管理。
dhcp社區(qū)的cni組件中就包含了dhcp這個(gè)ipam,但并沒有提供一個(gè)可以參考的案例,翻看了相關(guān)的源碼,大致邏輯是:
向dhcp申請(qǐng)ip時(shí),dhcp會(huì)使用rpc訪問本地的socket(/run/cni/dhcp.sock)申請(qǐng)一個(gè)ip的租約。然后將IP告知調(diào)用者。
向dhcp刪除IP時(shí),dhcp同樣通過rpc請(qǐng)求,解除該IP的租約。
main(network)類CNImain類型的cni組件做的都是一些核心功能,比如配置網(wǎng)橋、配置各種虛擬化的網(wǎng)絡(luò)接口(veth、macvlan、ipvlan等)。這里我們著重講使用率較高的bridge和ptp。
bridgebrige模式,即網(wǎng)橋模式。在node上創(chuàng)建一個(gè)linux bridge,并通過vethpair的方式在容器中設(shè)置網(wǎng)卡和IP。只要為容器配置一個(gè)二層可達(dá)的網(wǎng)關(guān):比如給網(wǎng)橋配置IP,并設(shè)置為容器ip的網(wǎng)關(guān)。容器的網(wǎng)絡(luò)就能建立起來。
如下是bridge的配置項(xiàng)數(shù)據(jù)結(jié)構(gòu):
type NetConf struct { types.NetConf BrName string `json:"bridge"` //網(wǎng)橋名 IsGW bool `json:"isGateway"` //是否將網(wǎng)橋配置為網(wǎng)關(guān) IsDefaultGW bool `json:"isDefaultGateway"` // ForceAddress bool `json:"forceAddress"`//如果網(wǎng)橋已存在且已配置了其他IP,通過此參數(shù)決定是否將其他ip除去 IPMasq bool `json:"ipMasq"`//如果true,配置私有網(wǎng)段到外部網(wǎng)段的masquerade規(guī)則 MTU int `json:"mtu"` HairpinMode bool `json:"hairpinMode"` PromiscMode bool `json:"promiscMode"` }
我們關(guān)注其中的一部分字段,結(jié)合代碼可以大致整理出bridge組件的工作內(nèi)容。首先是ADD命令:
執(zhí)行ADD命令時(shí),brdige組件創(chuàng)建一個(gè)指定名字的網(wǎng)橋,如果網(wǎng)橋已經(jīng)存在,就使用已有的網(wǎng)橋;
創(chuàng)建vethpair,將node端的veth設(shè)備連接到網(wǎng)橋上;
從ipam獲取一個(gè)給容器使用的ip數(shù)據(jù),并根據(jù)返回的數(shù)據(jù)計(jì)算出容器對(duì)應(yīng)的網(wǎng)關(guān);
進(jìn)入容器網(wǎng)絡(luò)名字空間,修改容器中網(wǎng)卡名和網(wǎng)卡ip,以及配置路由,并進(jìn)行arp廣播(注意我們只為vethpair的容器端配置ip,node端是沒有ip的);
如果IsGW=true,將網(wǎng)橋配置為網(wǎng)關(guān),具體方法是:將第三步計(jì)算得到的網(wǎng)關(guān)IP配置到網(wǎng)橋上,同時(shí)根據(jù)需要將網(wǎng)橋上其他ip刪除。最后開啟網(wǎng)橋的ip_forward內(nèi)核參數(shù);
如果IPMasq=true,使用iptables增加容器私有網(wǎng)網(wǎng)段到外部網(wǎng)段的masquerade規(guī)則,這樣容器內(nèi)部訪問外部網(wǎng)絡(luò)時(shí)會(huì)進(jìn)行snat,在很多情況下配置了這條路由后容器內(nèi)部才能訪問外網(wǎng)。(這里代碼中會(huì)做exist檢查,防止生成重復(fù)的iptables規(guī)則);
配置結(jié)束,整理當(dāng)前網(wǎng)橋的信息,并返回給調(diào)用者。
其次是DEL命令:
根據(jù)命令執(zhí)行的參數(shù),確認(rèn)要?jiǎng)h除的容器ip,調(diào)用ipam的del命令,將IP還回IP pool;
進(jìn)入容器的網(wǎng)絡(luò)名字空間,根據(jù)容器IP將對(duì)應(yīng)的網(wǎng)卡刪除;
如果IPMasq=true,在node上刪除創(chuàng)建網(wǎng)絡(luò)時(shí)配置的幾條iptables規(guī)則。
ptpptp其實(shí)是bridge的簡(jiǎn)化版。但是它做的網(wǎng)絡(luò)配置其實(shí)看上去倒是更復(fù)雜了點(diǎn)。并且有一些配置在自測(cè)過程中發(fā)現(xiàn)并沒有太大用處。它只創(chuàng)建vethpair,但是會(huì)同時(shí)給容器端和node端都配置一個(gè)ip。容器端配置的是容器IP,node端配置的是容器IP的網(wǎng)關(guān)(/32),同時(shí),容器里做了一些特殊配置的路由,以滿足讓容器發(fā)出的arp請(qǐng)求能被vethpair的node端響應(yīng)。實(shí)現(xiàn)內(nèi)外的二層連通。
ptp的網(wǎng)絡(luò)配置步驟如下:
從ipam獲取IP,根據(jù)ip類型(ipv4或ipv6)配置響應(yīng)的內(nèi)核ip_forward參數(shù);
創(chuàng)建一對(duì)vethpair;一端放到容器中;
進(jìn)入容器的網(wǎng)絡(luò)namespace,配置容器端的網(wǎng)卡,修改網(wǎng)卡名,配置IP,并配置一些路由。假如容器ip是10.18.192.37/20,所屬網(wǎng)段是10.18.192.0/20,網(wǎng)關(guān)是10.18.192.1,我們這里將進(jìn)行這樣的配置:
配置IP后,內(nèi)核會(huì)自動(dòng)生成一條路由,形如:10.18.192.0/20 dev eth0 scope link,我們將它刪掉:ip r d ****
配置一條私有網(wǎng)到網(wǎng)關(guān)的真實(shí)路由:ip r a 10.18.192.0/20 via 10.18.192.1 dev eth0
配置一條到網(wǎng)關(guān)的路由:10.18.192.1/32 dev eth0 scope link
退出到容器外,將vethpair的node端配置一個(gè)IP(ip為容器ip的網(wǎng)關(guān),mask=32);
配置外部的路由:訪問容器ip的請(qǐng)求都路由到vethpair的node端設(shè)備去。
如果IPMasq=true,配置iptables
獲取完整的網(wǎng)卡信息(vethpair的兩端),返回給調(diào)用者。
與bridge不同主要的不同是:ptp不使用網(wǎng)橋,而是直接使用vethpair+路由配置,這個(gè)地方其實(shí)有很多其他的路由配置可以選擇,一樣可以實(shí)現(xiàn)網(wǎng)絡(luò)的連通性,ptp配置的方式只是其中之一。萬變不離其宗的是:
只要容器內(nèi)網(wǎng)卡發(fā)出的arp請(qǐng)求,能被node回復(fù)或被node轉(zhuǎn)發(fā)并由更上層的設(shè)備回復(fù),形成一個(gè)二層網(wǎng)絡(luò),容器里的數(shù)據(jù)報(bào)文就能被發(fā)往node上;然后通過node上的路由,進(jìn)行三層轉(zhuǎn)發(fā),將數(shù)據(jù)報(bào)文發(fā)到正確的地方,就可以實(shí)現(xiàn)網(wǎng)絡(luò)的互聯(lián)。
bridge和ptp其實(shí)是用了不同方式實(shí)現(xiàn)了這個(gè)原則中的“二層網(wǎng)絡(luò)”:
bridge組件給網(wǎng)橋配置了網(wǎng)關(guān)的IP,并給容器配置了到網(wǎng)關(guān)的路由。實(shí)現(xiàn)二層網(wǎng)絡(luò)
ptp組件給vethpair的對(duì)端配置了網(wǎng)關(guān)的IP,并給容器配置了多帶帶到網(wǎng)關(guān)IP的路由,實(shí)現(xiàn)二層網(wǎng)絡(luò)
ptp模式的路由還存在一個(gè)問題:沒有配置default路由,因此容器不能訪問外部網(wǎng)絡(luò),要實(shí)現(xiàn)也很簡(jiǎn)單,以上面的例子,在容器里增加一條路由:default via 10.18.192.1 dev eth0
host-device相比前面兩種cni main組件,host-device顯得十分簡(jiǎn)單因?yàn)樗椭粫?huì)做兩件事情:
收到ADD命令時(shí),host-device根據(jù)命令參數(shù),將網(wǎng)卡移入到指定的網(wǎng)絡(luò)namespace(即容器中)。
收到DEL命令時(shí),host-device根據(jù)命令參數(shù),將網(wǎng)卡從指定的網(wǎng)絡(luò)namespace移出到root namespace。
細(xì)心的你肯定會(huì)注意到,在bridge和ptp組件中,就已經(jīng)有“將vethpair的一端移入到容器的網(wǎng)絡(luò)namespace”的操作。那這個(gè)host-device不是多此一舉嗎?
并不是。host-device組件有其特定的使用場(chǎng)景。假設(shè)集群中的每個(gè)node上有多個(gè)網(wǎng)卡,其中一個(gè)網(wǎng)卡配置了node的IP。而其他網(wǎng)卡都是屬于一個(gè)網(wǎng)絡(luò)的,可以用來做容器的網(wǎng)絡(luò),我們只需要使用host-device,將其他網(wǎng)卡中的某一個(gè)丟到容器里面就行。
host-device模式的使用場(chǎng)景并不多。它的好處是:bridge、ptp等方案中,node上所有容器的網(wǎng)絡(luò)報(bào)文都是通過node上的一塊網(wǎng)卡出入的,host-device方案中每個(gè)容器獨(dú)占一個(gè)網(wǎng)卡,網(wǎng)絡(luò)流量不會(huì)經(jīng)過node的網(wǎng)絡(luò)協(xié)議棧,隔離性更強(qiáng)。缺點(diǎn)是:在node上配置數(shù)十個(gè)網(wǎng)卡,可能并不好管理;另外由于不經(jīng)過node上的協(xié)議棧,所以kube-proxy直接廢掉。k8s集群內(nèi)的負(fù)載均衡只能另尋他法了。
macvlan有關(guān)macvlan的實(shí)踐可以參考這篇文章。這里做一個(gè)簡(jiǎn)單的介紹:macvlan是linux kernal的特性,用于給一個(gè)物理網(wǎng)絡(luò)接口(parent)配置虛擬化接口,虛擬化接口與parent網(wǎng)絡(luò)接口擁有不同的mac地址,但parent接口上收到發(fā)給其對(duì)應(yīng)的虛擬化接口的mac的包時(shí),會(huì)分發(fā)給對(duì)應(yīng)的虛擬化接口,有點(diǎn)像是將虛擬化接口和parent接口進(jìn)行了"橋接"。給虛擬化網(wǎng)絡(luò)接口配置了IP和路由后就能互相訪問。
macvlan省去了linux bridge,但是配置macvlan后,容器不能訪問parent接口的IP。
ipvlanipvlan與macvlan有點(diǎn)類似,但對(duì)于內(nèi)核要求更高(3.19),ipvlan也會(huì)從一個(gè)網(wǎng)絡(luò)接口創(chuàng)建出多個(gè)虛擬網(wǎng)絡(luò)接口,但他們的mac地址是一樣的, 只是IP不一樣。通過路由可以實(shí)現(xiàn)不同虛擬網(wǎng)絡(luò)接口之間的互聯(lián)。
使用ipvlan也不需要linux bridge,但容器一樣不能訪問parent接口的IP。
關(guān)于ipvlan的內(nèi)容可以參考這篇文章
關(guān)于macvlan和ipvlan,還可以參考這篇文章
meta 類CNImeta組件通常進(jìn)行一些額外的網(wǎng)絡(luò)配置(tuning),或者二次調(diào)用(flannel)。
tuning用于進(jìn)行內(nèi)核網(wǎng)絡(luò)參數(shù)的配置。并將調(diào)用者的數(shù)據(jù)和配置后的內(nèi)核參數(shù)返回給調(diào)用者。
有時(shí)候我們需要配置一些虛擬網(wǎng)絡(luò)接口的內(nèi)核參數(shù),比如:網(wǎng)易云在早期經(jīng)典網(wǎng)絡(luò)方案中曾修改vethpair的proxy_arp參數(shù)(后面會(huì)介紹)??梢酝ㄟ^這個(gè)組件進(jìn)行配置。
另外一些可能會(huì)改動(dòng)的網(wǎng)絡(luò)參數(shù)比如:
accept_redirects
send_redirects
proxy_delay
accept_local
arp_filter
可以在這里查看可配置的網(wǎng)絡(luò)參數(shù)和釋義。
portmap用于在node上配置iptables規(guī)則,進(jìn)行SNAT,DNAT和端口轉(zhuǎn)發(fā)。
portmap組件通常在main組件執(zhí)行完畢后執(zhí)行,因?yàn)樗膱?zhí)行參數(shù)仰賴之前的組件提供
flannelcni plugins中的flannel是開源網(wǎng)絡(luò)方案flannel的“調(diào)用器”。這也是flannel網(wǎng)絡(luò)方案適配CNI架構(gòu)的一個(gè)產(chǎn)物。為了便于區(qū)分,以下我們稱cni plugins中的flannel 為flanenl cni。
我們知道flannel是一個(gè)容器的網(wǎng)絡(luò)方案,通常使用flannel時(shí),node上會(huì)運(yùn)行一個(gè)daemon進(jìn)程:flanneld,這個(gè)進(jìn)程會(huì)返回該node上的flannel網(wǎng)絡(luò)、subnet,MTU等信息。并保存到本地文件中。
如果對(duì)flannel網(wǎng)絡(luò)方案有一定的了解,會(huì)知道他在做網(wǎng)絡(luò)接口配置時(shí),其實(shí)干的事情和bridge組件差不多。只不過flannel網(wǎng)絡(luò)下的bridge會(huì)跟flannel0網(wǎng)卡互聯(lián),而flannel0網(wǎng)卡上的數(shù)據(jù)會(huì)被封包(udp、vxlan下)或直接轉(zhuǎn)發(fā)(host-gw)。
而flannel cni做的事情就是:
執(zhí)行ADD命令時(shí),flannel cni會(huì)從本地文件中讀取到flanneld的配置。然后根據(jù)命令的參數(shù)和文件的配置,生成一個(gè)新的cni配置文件(保存在本地,文件名包含容器id以作區(qū)分)。新的cni配置文件中會(huì)使用其他cni組件,并注入相關(guān)的配置信息。之后,flannel cni根據(jù)這個(gè)新的cni配置文件執(zhí)行ADD命令。
執(zhí)行DEL命令時(shí),flannel cni從本地根據(jù)容器id找到之前創(chuàng)建的cni配置文件,根據(jù)該配置文件執(zhí)行DEL命令。
也就是說flannel cni此處是一個(gè)flannel網(wǎng)絡(luò)模型的委托者,falnnel網(wǎng)絡(luò)模型委托它去調(diào)用其他cni組件,進(jìn)行網(wǎng)絡(luò)配置。通常調(diào)用的是bridge和host-local。
幾種常見的網(wǎng)絡(luò)方案上述所有的cni組件,能完成的事情就是建立容器到虛擬機(jī)上的網(wǎng)絡(luò)。而要實(shí)現(xiàn)跨虛擬機(jī)的容器之間的網(wǎng)絡(luò),有幾種可能的辦法:
容器的IP就是二層網(wǎng)絡(luò)里分配的IP,這樣容器相當(dāng)于二層網(wǎng)絡(luò)里的節(jié)點(diǎn),那么就可以天然互訪;
容器的IP與node的IP不屬于同一個(gè)網(wǎng)段,node上配置個(gè)到各個(gè)網(wǎng)段的路由(指向?qū)?yīng)容器網(wǎng)段所部屬的node IP),通過路由實(shí)現(xiàn)互訪[flannel host-gw, calico bgp均是通過此方案實(shí)現(xiàn)];
容器的IP與node的IP不屬于同一個(gè)網(wǎng)段,node上有服務(wù)對(duì)容器發(fā)出的包進(jìn)行封裝,對(duì)發(fā)給容器的包進(jìn)行解封。封裝后的包通過node所在的網(wǎng)絡(luò)進(jìn)行傳輸。解封后的包通過網(wǎng)橋或路由直接發(fā)給容器,即overlay網(wǎng)絡(luò)。[flannel udp/vxlan,calico ipip,openshift-sdn均通過此方案實(shí)現(xiàn)]
kubenet了解常用的網(wǎng)絡(luò)方案前,我們先了解一下kubenet,kubenet其實(shí)是k8s代碼中內(nèi)置的一個(gè)cni組件。如果我們要使用kubenet,就得在kubelet的啟動(dòng)參數(shù)中指定networkPlugin值為kubenet而不是cni。
如果你閱讀了kubernetes的源碼,你就可以在一個(gè)名為kubenet_linux.go的文件中看到kubenet做了什么事情:
身為一種networkPlugin,kubenet自然要實(shí)現(xiàn)networkPlugin的一些接口。比如SetUpPod,TearDownPod,GetPodNetworkStatus等等,kubelet通過這些接口進(jìn)行容器網(wǎng)絡(luò)的創(chuàng)建、解除、查詢。
身為一個(gè)代碼中內(nèi)置的cni,kubenet要主動(dòng)生成一個(gè)cni配置文件(字節(jié)流數(shù)據(jù)),自己按照cni的規(guī)矩去讀取配置文件,做類似ADD/DEL指令的工作。實(shí)現(xiàn)網(wǎng)絡(luò)的創(chuàng)建、解除。
設(shè)計(jì)上其實(shí)挺蠢萌的。實(shí)際上是為了省事。我們可以看下自生成的配置文件:
{ "cniVersion": "0.1.0", "name": "kubenet", "type": "bridge", "bridge": "%s", //通常這里默認(rèn)是“cbr0” "mtu": %d, //kubelet的啟動(dòng)參數(shù)中可以配置,默認(rèn)使用機(jī)器上的最小mtu "addIf": "%s", //配置到容器中的網(wǎng)卡名字 "isGateway": true, "ipMasq": false, "hairpinMode": %t, "ipam": { "type": "host-local", "subnet": "%s", //node上容器ip所屬子網(wǎng),通常是kubelet的pod-cidr參數(shù)指定 "gateway": "%s", //通過subnet可以確定gateway "routes": [ { "dst": "0.0.0.0/0" } ] } }
配置文件中明確了要使用的其他cni組件:bridge、host-local(這里代碼中還會(huì)調(diào)用lo組件,通常lo組件會(huì)被k8s代碼直接調(diào)用,所以不需要寫到cni配置文件中)。之后的事情就是執(zhí)行二進(jìn)制而已。
為什么我們要學(xué)習(xí)kubenet?因?yàn)閗ubenet可以讓用戶以最簡(jiǎn)單的成本(配置networkPlugin和pod-cidr兩個(gè)啟動(dòng)kubelet啟動(dòng)參數(shù)),配置出一個(gè)簡(jiǎn)單的、虛擬機(jī)本地的容器網(wǎng)絡(luò)。結(jié)合上面提到的幾種“跨虛擬機(jī)的容器之間的網(wǎng)絡(luò)方案”,就是一個(gè)完整的k8s集群網(wǎng)絡(luò)方案了。
通常kubenet不適合用于overlay網(wǎng)絡(luò)方案,因?yàn)閛verlay網(wǎng)絡(luò)方案定制化要求會(huì)比較高。
許多企業(yè)使用vpc網(wǎng)絡(luò)時(shí),使用自定義路由實(shí)現(xiàn)不同pod-cidr之間的路由,他們的網(wǎng)絡(luò)方案里就會(huì)用到kubenet,比如azure AKS(基礎(chǔ)網(wǎng)絡(luò))。
flannel關(guān)于flannel,上面的文章也提到了一下。網(wǎng)上flannel的文章也是一搜一大把。這里簡(jiǎn)單介紹下flannel對(duì)k8s的支持,以及通用的幾個(gè)flannel backend(后端網(wǎng)絡(luò)配置方案)。
flannel for kubernetesflannel在對(duì)kubernets進(jìn)行支持時(shí),flanneld啟動(dòng)參數(shù)中會(huì)增加--kube-subnet-mgr參數(shù),flanneld會(huì)初始化一個(gè)kubernetes client,獲取本地node的pod-cidr,這個(gè)pod-cidr將會(huì)作為flannel為node本地容器規(guī)劃的ip網(wǎng)段。記錄到/run/flannel/subnet.env。(flannel_cni組件會(huì)讀取這個(gè)文件并寫入到net-conf.json中,供cni使用)。
udp/vxlanflannel的overlay方案。每個(gè)node節(jié)點(diǎn)上都有一個(gè)flanneld進(jìn)程,和flannel0網(wǎng)橋,容器網(wǎng)絡(luò)會(huì)與flannel0網(wǎng)橋互聯(lián),并經(jīng)由flannel0發(fā)出,所以flanneld可以捕獲到容器發(fā)出的報(bào)文,進(jìn)行封裝。udp方案下會(huì)給報(bào)文包裝一個(gè)udp的頭部,vxlan下會(huì)給報(bào)文包裝一個(gè)vxlan協(xié)議的頭部(配置了相同VNI的node,就能進(jìn)行互聯(lián))。 目前flannel社區(qū)還提供了更多實(shí)驗(yàn)性的封裝協(xié)議選擇,比如ipip,但仍舊將vxlan作為默認(rèn)的backend。
host-gwflannel的三層路由方案。每個(gè)node節(jié)點(diǎn)上都會(huì)記錄其他節(jié)點(diǎn)容器ip段的路由,通過路由,node A上的容器發(fā)給node B上的容器的數(shù)據(jù),就能在node A上進(jìn)行轉(zhuǎn)發(fā)。
alloc類似kubenet,只分配子網(wǎng),不做其他任何事情。
支持云廠商的vpcflannel支持了aliVPC、gce、aws等云廠商的vpc網(wǎng)絡(luò)。原理都是一樣的,就是當(dāng)flanneld在某云廠商的機(jī)器上運(yùn)行時(shí),根據(jù)機(jī)器自身的vpc網(wǎng)絡(luò)IP,和flanneld分配在該機(jī)器上的subnet,調(diào)用云廠商的api創(chuàng)建對(duì)應(yīng)的自定義路由。
calicocalico是基于BGP路由實(shí)現(xiàn)的容器集群網(wǎng)絡(luò)方案,對(duì)于使用者來說,基礎(chǔ)的calico使用體驗(yàn)可能和flannel host-gw是基本一樣的:node節(jié)點(diǎn)上做好對(duì)容器arp的響應(yīng)。然后通過node上的路由將容器發(fā)出的包轉(zhuǎn)發(fā)到對(duì)端容器所在node的IP。對(duì)端節(jié)點(diǎn)上再將包轉(zhuǎn)發(fā)給對(duì)端容器。
ipip模式則如同flannel ipip模式。對(duì)報(bào)文封裝一個(gè)ipip頭部,頭部中使用node ip。發(fā)送到對(duì)端容器所在node的IP,對(duì)端的網(wǎng)絡(luò)組件再解包,并轉(zhuǎn)發(fā)給容器。
不同之處在于flannel方案下路由都是通過代碼邏輯進(jìn)行配置。而calico則在每個(gè)節(jié)點(diǎn)建立bgp peer,bgp peer彼此之間會(huì)進(jìn)行路由的共享和學(xué)習(xí),所以自動(dòng)生成并維護(hù)了路由。
一些大廠的容器服務(wù)網(wǎng)絡(luò)方案 阿里云通過上文flannel aliVPC模式可見一斑。阿里云中kubernetes服務(wù)里,k8s集群通常使用自定義路由的方案+flannel_cni組件,這個(gè)方案易于部署和管理,同時(shí)將容器IP和nodeIP區(qū)分,用戶可以自定義集群網(wǎng)絡(luò)范圍。
(比較奇怪的是這里flanenl的backend配置成alloc而非aliVPC,在集群中另外部署了一個(gè)controller進(jìn)行自定義路由的配置)
自定義路由是vpc網(wǎng)絡(luò)中的一個(gè)常用功能,在vpc范圍內(nèi)可以自定義某個(gè)網(wǎng)絡(luò)接口作為一個(gè)任意網(wǎng)段的網(wǎng)關(guān)。在flannel host-gw模式中,我們將這塊的路由配置在node上,由內(nèi)核執(zhí)行,而自定義路由則是將類似的路由記錄到vpc網(wǎng)絡(luò)的數(shù)據(jù)庫(kù)中,由vpc-router去執(zhí)行。
azureazure最近開放了kubernetes服務(wù)AKS,AKS支持兩種網(wǎng)絡(luò)方案:基礎(chǔ)和高級(jí)。
基礎(chǔ)網(wǎng)絡(luò)方案與阿里云的自定義路由方案如出一轍?;A(chǔ)網(wǎng)絡(luò)中k8s集群使用的網(wǎng)絡(luò)組件是kubenet,簡(jiǎn)單的做了網(wǎng)絡(luò)劃分和本地的網(wǎng)絡(luò)接口配置,自定義路由由其vpc實(shí)現(xiàn)。
高級(jí)網(wǎng)絡(luò)方案中,node上的網(wǎng)絡(luò)接口會(huì)創(chuàng)建并綁定多個(gè)(默認(rèn)三十個(gè))fixedIP,主FixedIP作為node IP,其余fixedIP則用于容器IP。
通過azure SDN的支持,不同node之間的容器網(wǎng)絡(luò)變成一個(gè)大二層,他們可以直接互聯(lián)。高級(jí)網(wǎng)絡(luò)方案中,k8s集群使用azure開源的cni組件:azure-container-networking。這個(gè)cni組件包括了ipam和main兩部分
azure cni的ipam負(fù)責(zé)將本地網(wǎng)絡(luò)接口上綁定著的空閑的fixedIP配置給容器使用。一旦空閑的fixedIP耗盡,除非手動(dòng)給網(wǎng)卡創(chuàng)建新的fixedIP,否則容器無法創(chuàng)建成功。
azure cni的main組件在node上創(chuàng)建了一個(gè)bridge,將node的網(wǎng)卡連接到網(wǎng)橋上,并將node網(wǎng)卡IP設(shè)置到網(wǎng)橋上,容器網(wǎng)卡均由vethpair實(shí)現(xiàn),vethpair的node端也是連在網(wǎng)橋上。由此構(gòu)成node的網(wǎng)絡(luò):網(wǎng)橋上的IP作為容器網(wǎng)絡(luò)的網(wǎng)關(guān),容器網(wǎng)絡(luò)通過網(wǎng)橋與其他節(jié)點(diǎn)形成一個(gè)大二層的網(wǎng)絡(luò)。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/32794.html
摘要:相關(guān)原理概述先來講講什么是容器網(wǎng)絡(luò)接口是一種操作容器網(wǎng)絡(luò)規(guī)范,包含方法規(guī)范,參數(shù)規(guī)范等。只關(guān)心容器的網(wǎng)絡(luò)連接,在容器創(chuàng)建時(shí)分配網(wǎng)絡(luò)資源,并在刪除容器時(shí)刪除分配的資源。容器創(chuàng)建成功后具有一個(gè)網(wǎng)絡(luò)空間,此時(shí)調(diào)用插件方法進(jìn)行網(wǎng)絡(luò)設(shè)置。 相關(guān)原理概述 先來講講什么是CNI? CNI(容器網(wǎng)絡(luò)接口)是一種操作容器網(wǎng)絡(luò)規(guī)范,包含方法規(guī)范,參數(shù)規(guī)范等。CNI只關(guān)心容器的網(wǎng)絡(luò)連接,在容器創(chuàng)建時(shí)分配網(wǎng)絡(luò)...
摘要:但考慮到該用戶在跨集群模式下的困擾,開始策劃將托管云物理機(jī)納入現(xiàn)有集群統(tǒng)一管理的方案,即在混合云架構(gòu)下僅需部署管理一套集群。托管云物理機(jī)納入U(xiǎn)K8S集群統(tǒng)一管理后,可實(shí)現(xiàn)托管云物理機(jī)保障平峰時(shí)業(yè)務(wù)正常運(yùn)行,高峰時(shí)期利用UK8S快速擴(kuò)容公有云資源的理想應(yīng)用場(chǎng)景,繼而提升混合云的可用性。 ——海豹他趣技術(shù)負(fù)責(zé)人 張嵩 混合云的業(yè)務(wù)模式 廈門海豹他趣信息技術(shù)股份有限公司于2012年4...
摘要:模版用戶可以選擇不同的基礎(chǔ)設(shè)施服務(wù)組成模版同時(shí)還是有默認(rèn)的主要模版,用戶可以快速創(chuàng)建用戶也可以把的項(xiàng)目放到模版中,來管理和部署增強(qiáng)已經(jīng)大大簡(jiǎn)化了管理和配置,在多節(jié)點(diǎn)部署中和已經(jīng)被去掉了。請(qǐng)保持關(guān)注,和一起走上偉岸光明的容器之路 開篇第一句,先為Rancher v1.2曾經(jīng)的跳票深深抱歉(鞠躬)。我們補(bǔ)償?shù)姆绞剑褪窃诖巳?、此刻,用新版功能向你證明Rancher v1.2值得你的等待。R...
摘要:今天,發(fā)布了一系列補(bǔ)丁版本,修復(fù)新近發(fā)現(xiàn)的兩個(gè)安全漏洞命令安全漏洞和端口映射插件漏洞。因?yàn)槎丝谟成洳寮乔度氲桨姹局械?,只有升?jí)至新版本的才能解決此問題?,F(xiàn)在修復(fù)之后,將端口映射插件的規(guī)則由最優(yōu)先變?yōu)楦郊?,則可以讓流量?jī)?yōu)先由規(guī)則處理。 今天,Kubernetes發(fā)布了一系列補(bǔ)丁版本,修復(fù)新近發(fā)現(xiàn)的兩個(gè)安全漏洞CVE-2019-1002101(kubectl cp命令安全漏洞)和CVE-...
摘要:不同的網(wǎng)絡(luò)實(shí)現(xiàn)原理等并不能統(tǒng)一地支持。描述信息選擇器,選定的所有的出入站流量要遵循本的約束策略類型。所有包含的中的可以與上述的端口建立連接所有下的包含的可以與上述的端口建立連接允許上述訪問網(wǎng)段為的目的的端口。但可以做到范圍的整體控制。 簡(jiǎn)介 network policy顧名思義就是對(duì)pod進(jìn)行網(wǎng)絡(luò)策略控制。 k8s本身并不支持,因?yàn)閗8s有許多種網(wǎng)絡(luò)的實(shí)現(xiàn)方式,企業(yè)內(nèi)部可以使用簡(jiǎn)單的f...
閱讀 2657·2021-09-13 10:26
閱讀 1915·2021-09-03 10:28
閱讀 1991·2019-08-30 15:44
閱讀 808·2019-08-29 14:07
閱讀 396·2019-08-29 13:12
閱讀 2154·2019-08-26 11:44
閱讀 2345·2019-08-26 11:36
閱讀 2015·2019-08-26 10:19