一. Flannel 簡(jiǎn)介
flannel是CoreOS提供用于解決Dokcer集群跨主機(jī)通訊的覆蓋網(wǎng)絡(luò)工具晤硕。它的主要思路是:預(yù)先留出一個(gè)網(wǎng)段,每個(gè)主機(jī)使用其中一部分烙博,然后每個(gè)容器被分配不同的ip霞丧;讓所有的容器認(rèn)為大家在同一個(gè)直連的網(wǎng)絡(luò)竹揍,底層通過(guò)`UDP/VxLAN`等進(jìn)行報(bào)文的封裝和轉(zhuǎn)發(fā)。
Flannel目前支持網(wǎng)絡(luò)模式
UDP: 使用用戶(hù)態(tài)udp封裝,默認(rèn)使用8285端口唬复。由于是在用戶(hù)態(tài)封裝和解包控漠,性能上有較大的損失
VXLAN: vxlan封裝蔓倍,需要配置VNI,Port(默認(rèn)8472)和GBP; 是Linux內(nèi)核本身支持的一種網(wǎng)絡(luò)虛擬化技術(shù)盐捷,是內(nèi)核的一個(gè)模塊偶翅,在內(nèi)核態(tài)實(shí)現(xiàn)封裝解封裝,構(gòu)建出覆蓋網(wǎng)絡(luò)碉渡,其實(shí)就是一個(gè)由各宿主機(jī)上的Flannel.1設(shè)備組成的虛擬二層網(wǎng)絡(luò)聚谁,由于VXLAN由于額外的封包解包,導(dǎo)致其性能較差;VXLAN Directrouting模式也支持類(lèi)似host-gw的玩法滞诺,如果兩個(gè)節(jié)點(diǎn)在同一網(wǎng)段時(shí)使用host-gw通信形导,如果不在同一網(wǎng)段中,即 當(dāng)前pod所在節(jié)點(diǎn)與目標(biāo)pod所在節(jié)點(diǎn)中間有路由器习霹,就使用VXLAN這種方式朵耕,使用疊加網(wǎng)絡(luò)
Host-gw: 直接路由的方式,將容器網(wǎng)絡(luò)的路由信息直接更新到主機(jī)的路由表中序愚,僅適用于二層直接可達(dá)的網(wǎng)絡(luò) 推薦使用憔披,效率極高
Flannel 工作模式及架構(gòu)
flannel.png
1 UDP模式
Udp方式是Flannel項(xiàng)目最早支持的,也是性能最差的一種爸吮。目前已經(jīng)被棄用芬膝,不過(guò),這種方式最直接形娇、也是最容易理解的跨主機(jī)實(shí)現(xiàn)锰霜。
1.1 UDP模式架構(gòu)圖
image.png
1.2 UDP 數(shù)據(jù)流向
1) 容器直接使用目標(biāo)容器的ip訪(fǎng)問(wèn),默認(rèn)通過(guò)容器內(nèi)部的eth0發(fā)送出去桐早。
2) 報(bào)文通過(guò)veth pair被發(fā)送到vethXXX癣缅。
3) vethXXX是直接連接到虛擬交換機(jī)docker0的,報(bào)文通過(guò)虛擬bridge docker0發(fā)送出去哄酝。
4) 由表友存,外部容器ip的報(bào)文都會(huì)轉(zhuǎn)發(fā)到flannel0虛擬網(wǎng)卡,這是一個(gè)P2P的虛擬網(wǎng)卡陶衅,然后報(bào)文就被轉(zhuǎn)發(fā)到監(jiān)聽(tīng)在另一端的flanneld屡立。
5) flanneld通過(guò)etcd維護(hù)了各個(gè)節(jié)點(diǎn)之間的路由表,把原來(lái)的報(bào)文UDP封裝一層搀军,通過(guò)配置的iface發(fā)送出去膨俐。
6)報(bào)文通過(guò)主機(jī)之間的網(wǎng)絡(luò)找到目標(biāo)主機(jī)勇皇。
7) 報(bào)文繼續(xù)往上,到傳輸層焚刺,交給監(jiān)聽(tīng)在8285端口的flanneld程序處理敛摘。
8) 數(shù)據(jù)被解包,然后發(fā)送給flannel0虛擬網(wǎng)卡乳愉。
9) 查找路由表兄淫,發(fā)現(xiàn)對(duì)應(yīng)容器的報(bào)文要交給docker0。
10) docker0找到連到自己的容器蔓姚,把報(bào)文發(fā)送過(guò)去拖叙。
2 VXLAN 模式
Vxlan(Virtual eXtensible LAN),虛擬可擴(kuò)展的局域網(wǎng),是一種虛擬化隧道通信技術(shù),他是一種overlay(覆蓋網(wǎng)絡(luò))技術(shù),通過(guò)三層的網(wǎng)絡(luò)搭建虛擬的二層網(wǎng)絡(luò)
Vxlan是再底層物理網(wǎng)絡(luò)(underlay)之上使用隧道技術(shù)赂乐,依托UDP層構(gòu)建的overlay的邏輯網(wǎng)絡(luò),使邏輯網(wǎng)絡(luò)與物理網(wǎng)絡(luò)解耦,實(shí)現(xiàn)靈活的組網(wǎng)需求,不僅能使適配虛擬機(jī)環(huán)境,還用適用于容器環(huán)境
1).VXLAN 支持更多子網(wǎng)(VLAN支持吃2的12次方子網(wǎng)即為4096個(gè)子網(wǎng),Vxlan支持2的24方個(gè)子網(wǎng)),并通過(guò)VNI(Virtual Network identifier)區(qū)分不同 的子網(wǎng),相當(dāng)于VLAN中的LAN ID
2).多租戶(hù)網(wǎng)絡(luò)隔離,不同用戶(hù)之間需要獨(dú)立地分配IP和MAC地址
3).云計(jì)算業(yè)務(wù)對(duì)業(yè)務(wù)靈活性要求很高咖气,虛擬機(jī)可能會(huì)大規(guī)模遷移挨措,并保證網(wǎng)絡(luò)一直可用。解決這個(gè)問(wèn)題同時(shí)保證二層的廣播域不會(huì)過(guò)分?jǐn)U大崩溪,這也是云計(jì)算網(wǎng)絡(luò)的要求
2.1 VXLAN 組網(wǎng)模式
Network Overlay 隧道封裝在物理交換機(jī)完成浅役。這種Overlay的優(yōu)勢(shì)在于物理網(wǎng)絡(luò)設(shè)備性能轉(zhuǎn)發(fā)性能比較高,可以支持非虛擬化的物理服務(wù)器之間的組網(wǎng)互通伶唯。
Host Overlay 隧道封裝在vSwitch觉既、具備VXLAN功能的軟件完成,不用增加新的網(wǎng)絡(luò)設(shè)備即可完成Overlay部署乳幸,可以支持虛擬化的服務(wù)器之間的組網(wǎng)互通瞪讼。
Hybrid Overlay是Network Overlay和Host Overlay的混合組網(wǎng),可以支持物理服務(wù)器和虛擬服務(wù)器之間的組網(wǎng)互通粹断。
2.2 VXLAN 架構(gòu)圖
image.png
2.3 VXLAN 數(shù)據(jù)流向
1) 源容器veth0向目標(biāo)容器發(fā)送數(shù)據(jù)符欠,根據(jù)容器內(nèi)的默認(rèn)路由,數(shù)據(jù)首先發(fā)送給宿主機(jī)的docker0網(wǎng)橋
2)宿主機(jī)docker0網(wǎng)橋接受到數(shù)據(jù)后瓶埋,宿主機(jī)查詢(xún)路由表希柿,pod相關(guān)的路由都是交由flannel.1網(wǎng)卡,因此养筒,將其轉(zhuǎn)發(fā)給flannel.1虛擬網(wǎng)卡處理
3)flannel.1接受到數(shù)據(jù)后曾撤,查詢(xún)etcd數(shù)據(jù)庫(kù),獲取目標(biāo)pod網(wǎng)段對(duì)應(yīng)的目標(biāo)宿主機(jī)地址晕粪、目標(biāo)宿主機(jī)的flannel網(wǎng)卡的mac地址挤悉、vxlan vnid等信息。然后對(duì)數(shù)據(jù)進(jìn)行udp封裝如下:
udp頭封裝:
source port >1024兵多,target port 8427
udp內(nèi)部封裝:
vxlan封裝:vxlan vnid等信息
original layer 2 frame封裝:source {源 flannel.1網(wǎng)卡mac地址} target{目標(biāo)flannel.1網(wǎng)卡的mac地址}
完成以上udp封裝后尖啡,將數(shù)據(jù)轉(zhuǎn)發(fā)給物理機(jī)的eth0網(wǎng)卡
4)宿主機(jī)eth0接收到來(lái)自flannel.1的udp包橄仆,還需要將其封裝成正常的通信用的數(shù)據(jù)包,為它加上通用的ip頭衅斩、二層頭盆顾,這項(xiàng)工作在由linux內(nèi)核來(lái)完成。
Ethernet Header的信息:
source:{源宿主機(jī)機(jī)網(wǎng)卡的MAC地址}
target:{目標(biāo)宿主機(jī)網(wǎng)卡的MAC地址}
IP Header的信息:
source:{源宿主機(jī)網(wǎng)卡的IP地址}
target:{目標(biāo)宿主機(jī)網(wǎng)卡的IP地址}
通過(guò)此次封裝畏梆,一個(gè)真正可用的數(shù)據(jù)包就封裝完成您宪,可以通過(guò)物理網(wǎng)絡(luò)傳輸了。
5)目標(biāo)宿主機(jī)的eth0接收到數(shù)據(jù)后奠涌,對(duì)數(shù)據(jù)包進(jìn)行拆封宪巨,拆到udp層后,將其轉(zhuǎn)發(fā)給8427端口的flannel進(jìn)程
6)目標(biāo)宿主機(jī)端flannel拆除udp頭溜畅、vxlan頭捏卓,獲取到內(nèi)部的原始數(shù)據(jù)幀,在原始數(shù)據(jù)幀內(nèi)部慈格,解析出源容器ip怠晴、目標(biāo)容器ip,重新封裝成通用的數(shù)據(jù)包浴捆,查詢(xún)路由表蒜田,轉(zhuǎn)發(fā)給docker0網(wǎng)橋;
7)最后选泻,docker0網(wǎng)橋?qū)?shù)據(jù)送達(dá)目標(biāo)容器內(nèi)的veth0網(wǎng)卡冲粤,完成容器之間的數(shù)據(jù)通信
3 Host-GW方式
flannel的udp模式和vxlan模式都是屬于隧道方式,也就是在udp的基礎(chǔ)之上页眯,構(gòu)建虛擬網(wǎng)絡(luò)梯捕,host-gw模式是個(gè)例外,host-gw模式屬于路由的方式餐茵,由于沒(méi)有經(jīng)過(guò)任何封裝科阎,純路由實(shí)現(xiàn),數(shù)據(jù)只經(jīng)過(guò)協(xié)議棧一次忿族,因此性能比較高;
host-gw模式通過(guò)建立主機(jī)IP到主機(jī)上對(duì)應(yīng)flannel子網(wǎng)的mapping锣笨,以直接路由的方式聯(lián)通flannel的各個(gè)子網(wǎng)。這種互聯(lián)方式?jīng)]有vxlan等封裝方式帶來(lái)的負(fù)擔(dān)道批,通過(guò)路由機(jī)制错英,實(shí)現(xiàn)flannel網(wǎng)絡(luò)數(shù)據(jù)包在主機(jī)之間的轉(zhuǎn)發(fā)。但是這種方式也有不足隆豹,那就是所有節(jié)點(diǎn)之間都要相互有點(diǎn)對(duì)點(diǎn)的路由覆蓋椭岩,并且所有加入flannel網(wǎng)絡(luò)的主機(jī)需要在同一個(gè)LAN里面;所以每個(gè)節(jié)點(diǎn)上有n-1個(gè)路由,而n個(gè)節(jié)點(diǎn)一共有n(n-1)/2個(gè)路由以保證flannel的flat網(wǎng)絡(luò)能力
host-gw的工作原理判哥,其實(shí)就是在宿主機(jī)上献雅,添加一條到達(dá)每個(gè)fannel子網(wǎng)的路由,這條路由的下一跳即網(wǎng)關(guān)就是相對(duì)應(yīng)的fannel子網(wǎng)所在的“主機(jī)”塌计。這些路由規(guī)則是flanneld根據(jù)容器部署的場(chǎng)景創(chuàng)建和更新的
3.1 Host-GW 架構(gòu)圖
image.png
3.2 Host-GW 數(shù)據(jù)流向
1)源容器veth0向目標(biāo)容器發(fā)送數(shù)據(jù)挺身,根據(jù)容器內(nèi)的默認(rèn)路由,數(shù)據(jù)首先發(fā)送給宿主機(jī)的docker0網(wǎng)橋锌仅,并進(jìn)入內(nèi)核協(xié)議棧
2)經(jīng)過(guò)netfilter的PREROUTING章钾,再進(jìn)入到路由子系統(tǒng),此時(shí)由于宿主機(jī)沒(méi)有任何額外的設(shè)備热芹,**匹配到默認(rèn)路由**,從宿主機(jī)的eth0發(fā)出,數(shù)據(jù)包直接發(fā)送至目的節(jié)點(diǎn)所在的宿主機(jī)
3) 數(shù)據(jù)幀通過(guò)宿主機(jī)的二層網(wǎng)絡(luò)順利到達(dá)節(jié)點(diǎn)目的節(jié)點(diǎn)
二. Flannel 安裝部署:
1 部署環(huán)境
image.png
2 安裝部署
#tar -xf flannel-v0.13.0.tar.gz
#mv /apps/svr/flannel-v0.13.0
#ln –svfn /apps/svr/flannel-v0.13.0 /apps/svr/flannel
2.1 調(diào)整Flannel配置文件
#cd /apps/conf/flannel
#cat flannel.cfg
# Flanneld configuration options
# etcd url location. Point this to the server where etcd runs
ETCD_ENDPOINTS="http://10.65.6.3:2379,http://10.65.6.4:2379,http://10.65.6.5:2379"
# etcd config key. This is the configuration key that flannel queries
# For address range assignment
ETCD_PREFIX="/flannel/network"
# Any additional options that you want to pass
FLANNEL_OPTIONS="-iface=bond0"
2.2 啟動(dòng)命令
#cd /usr/libs/systemd/system
#cat flannel.service
[Unit]
Description=Flanneld overlay address etcd agent
After=network.target
After=network-online.target
Wants=network-online.target
#Before=docker.service
[Service]
Type=notify
EnvironmentFile=/apps/conf/flannel/flannel.cfg
ExecStart=/apps/svr/flannel/bin/flanneld \
-etcd-endpoints=${ETCD_ENDPOINTS} \
-etcd-prefix=${ETCD_PREFIX} \
$FLANNEL_OPTIONS
ExecStartPost=/apps/svr/flannel/bin/mk-docker-opts.sh -d /run/flannel/subnet.env
Restart=on-failure
LimitNOFILE=1000000
LimitNPROC=1000000
LimitCORE=1000000
[Install]
WantedBy=multi-user.target
2.3 調(diào)整docker啟動(dòng)配置,增加flannel subnet.env環(huán)境變量,并重啟docker進(jìn)程
#vim /usr/libs/system/system/docker.service
[Service]
Type=notify
EnvironmentFile=-/run/flannel/subnet.env
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd $DOCKER_OPTS -H fd:// --containerd=/run/containerd/containerd.sock
#systemctl daemon-reload
#systemctl restart docker
2.4 通過(guò)etcd設(shè)置flannel管理的網(wǎng)段及flannel工作模式
#設(shè)置vxlan
/apps/svr/etcd/sbin/etcdctl \
--endpoints="http://10.65.6.3:2379,http://10.65.6.4:2379,http://10.65.6.5:2379" set /flannel/network/config '{"Network":"10.80.0.0/16", "SubnetLen": 24, "Backend": {"Type": "vxlan"}}'
#設(shè)置vxlan Directrouting
/apps/svr/etcd/sbin/etcdctl \
--endpoints="http://10.65.6.3:2379,http://10.65.6.4:2379,http://10.65.6.5:2379" set /flannel/network/config '{"Network":"10.80.0.0/16", "SubnetLen": 24, "Backend": {"Type": "vxlan","Directrouting": true }}'
#設(shè)置HOST-GW 模式
/apps/svr/etcd/sbin/etcdctl \
--endpoints="http://10.65.6.3:2379,http://10.65.6.4:2379,http://10.65.6.5:2379" set /flannel/network/config '{"Network":"10.80.0.0/16", "SubnetLen": 24, "Backend": {"Type": "host-gw" }}'
#設(shè)置UDP模式
/apps/svr/etcd/sbin/etcdctl \
--endpoints="http://10.65.6.3:2379,http://10.65.6.4:2379,http://10.65.6.5:2379" set /flannel/network/config '{"Network":"10.80.0.0/16", "SubnetLen": 24, "Backend": {"Type": "udp" }}'
2.5 查看flannel.1網(wǎng)卡及路由信息
# ifconfig flannel.1
flannel.1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450
inet 10.80.58.0 netmask 255.255.255.255 broadcast 10.80.58.0
inet6 fe80::74f9:1bff:fe63:37 prefixlen 64 scopeid 0x20<link>
ether 76:f9:1b:63:00:37 txqueuelen 0 (Ethernet)
RX packets 161301 bytes 34062775 (32.4 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 88102 bytes 53006628 (50.5 MiB)
TX errors 0 dropped 5 overruns 0 carrier 0 collisions 0
到mtu為1450(IP頭贱傀、UDP頭、MAC頭伊脓、vxlan協(xié)議共占了50)
# ifconfig docker0
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450
inet 10.80.58.1 netmask 255.255.255.0 broadcast 10.80.58.255
inet6 fe80::42:e0ff:fe58:276b prefixlen 64 scopeid 0x20<link>
ether 02:42:e0:58:27:6b txqueuelen 0 (Ethernet)
RX packets 51631431 bytes 5646040919 (5.2 GiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 55496509 bytes 14532143853 (13.5 GiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
2.6 查看路由
# ip route show
default via 10.65.4.254 dev bond0.100
10.65.4.0/24 dev bond0.100 proto kernel scope link src 10.65.4.1
10.80.20.0/24 via 10.80.20.0 dev flannel.1 onlink
10.80.27.0/24 via 10.80.27.0 dev flannel.1 onlink
10.80.58.0/24 dev docker0 proto kernel scope link src 10.80.58.1
169.254.0.0/16 dev bond0 scope link metric 1006
169.254.0.0/16 dev bond0.100 scope link metric 1007