Flannel网络方案架构方案及原理

一. Flannel 简介

flannel是CoreOS提供用于解决Dokcer集群跨主机通讯的覆盖网络工具。它的主要思路是:预先留出一个网段,每个主机使用其中一部分,然后每个容器被分配不同的ip;让所有的容器认为大家在同一个直连的网络,底层通过`UDP/VxLAN`等进行报文的封装和转发。

Flannel目前支持网络模式

UDP: 使用用户态udp封装,默认使用8285端口。由于是在用户态封装和解包,性能上有较大的损失

VXLAN: vxlan封装,需要配置VNI,Port(默认8472)和GBP;  是Linux内核本身支持的一种网络虚拟化技术,是内核的一个模块,在内核态实现封装解封装,构建出覆盖网络,其实就是一个由各宿主机上的Flannel.1设备组成的虚拟二层网络,由于VXLAN由于额外的封包解包,导致其性能较差;VXLAN Directrouting模式也支持类似host-gw的玩法,如果两个节点在同一网段时使用host-gw通信,如果不在同一网段中,即 当前pod所在节点与目标pod所在节点中间有路由器,就使用VXLAN这种方式,使用叠加网络

Host-gw: 直接路由的方式,将容器网络的路由信息直接更新到主机的路由表中,仅适用于二层直接可达的网络  推荐使用,效率极高

Flannel 工作模式及架构

flannel.png

1 UDP模式

 Udp方式是Flannel项目最早支持的,也是性能最差的一种。目前已经被弃用,不过,这种方式最直接、也是最容易理解的跨主机实现。

1.1 UDP模式架构图

image.png

1.2 UDP 数据流向

1) 容器直接使用目标容器的ip访问,默认通过容器内部的eth0发送出去。

2) 报文通过veth pair被发送到vethXXX。

3) vethXXX是直接连接到虚拟交换机docker0的,报文通过虚拟bridge docker0发送出去。

4) 由表,外部容器ip的报文都会转发到flannel0虚拟网卡,这是一个P2P的虚拟网卡,然后报文就被转发到监听在另一端的flanneld。

5) flanneld通过etcd维护了各个节点之间的路由表,把原来的报文UDP封装一层,通过配置的iface发送出去。

6)报文通过主机之间的网络找到目标主机。

7) 报文继续往上,到传输层,交给监听在8285端口的flanneld程序处理。

8) 数据被解包,然后发送给flannel0虚拟网卡。

9) 查找路由表,发现对应容器的报文要交给docker0。

10) docker0找到连到自己的容器,把报文发送过去。

2 VXLAN 模式

Vxlan(Virtual eXtensible LAN),虚拟可扩展的局域网,是一种虚拟化隧道通信技术,他是一种overlay(覆盖网络)技术,通过三层的网络搭建虚拟的二层网络

Vxlan是再底层物理网络(underlay)之上使用隧道技术,依托UDP层构建的overlay的逻辑网络,使逻辑网络与物理网络解耦,实现灵活的组网需求,不仅能使适配虚拟机环境,还用适用于容器环境

1).VXLAN 支持更多子网(VLAN支持吃2的12次方子网即为4096个子网,Vxlan支持2的24方个子网),并通过VNI(Virtual Network identifier)区分不同 的子网,相当于VLAN中的LAN ID

2).多租户网络隔离,不同用户之间需要独立地分配IP和MAC地址

3).云计算业务对业务灵活性要求很高,虚拟机可能会大规模迁移,并保证网络一直可用。解决这个问题同时保证二层的广播域不会过分扩大,这也是云计算网络的要求

2.1 VXLAN 组网模式

Network Overlay 隧道封装在物理交换机完成。这种Overlay的优势在于物理网络设备性能转发性能比较高,可以支持非虚拟化的物理服务器之间的组网互通。
Host Overlay 隧道封装在vSwitch、具备VXLAN功能的软件完成,不用增加新的网络设备即可完成Overlay部署,可以支持虚拟化的服务器之间的组网互通。
Hybrid Overlay是Network Overlay和Host Overlay的混合组网,可以支持物理服务器和虚拟服务器之间的组网互通。

2.2 VXLAN 架构图

image.png

2.3 VXLAN 数据流向

1) 源容器veth0向目标容器发送数据,根据容器内的默认路由,数据首先发送给宿主机的docker0网桥

2)宿主机docker0网桥接受到数据后,宿主机查询路由表,pod相关的路由都是交由flannel.1网卡,因此,将其转发给flannel.1虚拟网卡处理

3)flannel.1接受到数据后,查询etcd数据库,获取目标pod网段对应的目标宿主机地址、目标宿主机的flannel网卡的mac地址、vxlan vnid等信息。然后对数据进行udp封装如下:

udp头封装:

source port >1024,target port 8427

udp内部封装:

  vxlan封装:vxlan vnid等信息

  original layer 2 frame封装:source {源 flannel.1网卡mac地址} target{目标flannel.1网卡的mac地址}

完成以上udp封装后,将数据转发给物理机的eth0网卡

4)宿主机eth0接收到来自flannel.1的udp包,还需要将其封装成正常的通信用的数据包,为它加上通用的ip头、二层头,这项工作在由linux内核来完成。

Ethernet Header的信息:

source:{源宿主机机网卡的MAC地址}

target:{目标宿主机网卡的MAC地址}

IP Header的信息:

source:{源宿主机网卡的IP地址}

target:{目标宿主机网卡的IP地址}

通过此次封装,一个真正可用的数据包就封装完成,可以通过物理网络传输了。

5)目标宿主机的eth0接收到数据后,对数据包进行拆封,拆到udp层后,将其转发给8427端口的flannel进程

6)目标宿主机端flannel拆除udp头、vxlan头,获取到内部的原始数据帧,在原始数据帧内部,解析出源容器ip、目标容器ip,重新封装成通用的数据包,查询路由表,转发给docker0网桥;

7)最后,docker0网桥将数据送达目标容器内的veth0网卡,完成容器之间的数据通信

3 Host-GW方式

flannel的udp模式和vxlan模式都是属于隧道方式,也就是在udp的基础之上,构建虚拟网络,host-gw模式是个例外,host-gw模式属于路由的方式,由于没有经过任何封装,纯路由实现,数据只经过协议栈一次,因此性能比较高;
host-gw模式通过建立主机IP到主机上对应flannel子网的mapping,以直接路由的方式联通flannel的各个子网。这种互联方式没有vxlan等封装方式带来的负担,通过路由机制,实现flannel网络数据包在主机之间的转发。但是这种方式也有不足,那就是所有节点之间都要相互有点对点的路由覆盖,并且所有加入flannel网络的主机需要在同一个LAN里面;所以每个节点上有n-1个路由,而n个节点一共有n(n-1)/2个路由以保证flannel的flat网络能力
host-gw的工作原理,其实就是在宿主机上,添加一条到达每个fannel子网的路由,这条路由的下一跳即网关就是相对应的fannel子网所在的“主机”。这些路由规则是flanneld根据容器部署的场景创建和更新的

3.1 Host-GW 架构图

image.png

3.2 Host-GW 数据流向

1)源容器veth0向目标容器发送数据,根据容器内的默认路由,数据首先发送给宿主机的docker0网桥,并进入内核协议栈

2)经过netfilter的PREROUTING,再进入到路由子系统,此时由于宿主机没有任何额外的设备,**匹配到默认路由**,从宿主机的eth0发出,数据包直接发送至目的节点所在的宿主机

3)  数据帧通过宿主机的二层网络顺利到达节点目的节点

二. Flannel 安装部署:

1 部署环境

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 调整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 启动命令

#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 调整docker启动配置,增加flannel subnet.env环境变量,并重启docker进程

#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 通过etcd设置flannel管理的网段及flannel工作模式

#设置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"}}'
#设置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 }}'

#设置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" }}'
#设置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网卡及路由信息

# ifconfig flannel.1
flannel.1: flags=4163 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
 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协议共占了50)

# ifconfig docker0
docker0: flags=4163 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
 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

你可能感兴趣的:(Flannel网络方案架构方案及原理)