Flannel和Calico网络插件对比
Calico简介
Calico是一个纯三层的网络插件,calico的bgp模式相似于flannel的host-gw
Calico方便集成 OpenStack这种 IaaS云架构,为openstack虚拟机、容器、裸机提供多主机间通讯。
calico 架构

calico包括以下重要组件:Felix,etcd,BGP Client,BGP Route Reflector。下面分别说明一下这些组件:
- Felix:主要负责路由配置以及ACLS规则的配置以及下发,它存在在每一个node节点上。
- etcd:分布式键值存储,主要负责网络元数据一致性,确保Calico网络状态的准确性,能够与kubernetes共用;
- BGPClient(BIRD), 主要负责把 Felix写入 kernel的路由信息分发到当前 Calico网络,确保 workload间的通讯的有效性;
- BGPRoute Reflector(BIRD), 大规模部署时使用,摒弃全部节点互联的mesh模式,经过一个或者多个 BGPRoute Reflector 来完成集中式的路由分发;

calico 原理
calico是一个纯三层的虚拟网络,它没有复用docker的docker0网桥,而是本身实现的, calico网络不对数据包进行额外封装,不须要NAT和端口映射,扩展性和性能都很好。Calico网络提供了DockerDNS服务, 容器之间能够经过hostname访问,Calico在每个计算节点利用Linux Kernel实现了一个高效的vRouter(虚拟路由)来负责数据转发,它会为每一个容器分配一个ip,每一个节点都是路由,把不一样host的容器链接起来,从而实现跨主机间容器通讯。而每一个vRouter经过BGP协议(边界网关协议)负责把本身节点的路由信息向整个Calico网络内传播——小规模部署能够直接互联,大规模下可经过指定的BGProute reflector来完成;Calico基于iptables还提供了丰富而灵活的网络策略,保证经过各个节点上的ACLs来提供多租户隔离、安全组以及其余可达性限制等功能。
calico网络模式
一、ipip模式
把一个IP数据包又套在一个IP包里,即把IP层封装到IP层的一个 tunnel,它的做用其实基本上就至关于一个基于IP层的网桥,通常来讲,普通的网桥是基于mac层的,根本不须要IP,而这个ipip则是经过两端的路由作一个tunnel,把两个原本不通的网络经过点对点链接起来;

calico以ipip模式部署完毕后,node上会有一个tunl0的网卡设备,这是ipip作隧道封装用的,也是一种overlay模式的网络。当咱们把节点下线,calico容器都中止后,这个设备依然还在,执行 probe -r ipip 命令能够将它删除。
9: tunl0@NONE: <NOARP,UP,LOWER_UP> mtu 1440 qdisc noqueue state UNKNOWN qlen 1000 link/ipip 0.0.0.0 brd 0.0.0.0 inet 10.233.110.0/32 brd 10.233.110.0 scope global tunl0 valid_lft forever preferred_lft forever
官方提供的calico.yaml模板里,默认打开了ip-ip功能,该功能会在node上建立一个设备tunl0,容器的网络数据会通过该设备被封装一个ip头再转发。这里,calico.yaml中经过修改calico-node的环境变量:CALICO_IPV4POOL_IPIP来实现ipip功能的开关:默认是Always,表示开启;Off表示关闭ipip。
# kubectl get daemonsets. calico-node -n kube-system -o yaml | grep -iA 1 ipip - name: CALICO_IPV4POOL_IPIP value: "Always"
补充:
Linux支持的五种ip隧道,能够经过ip tunnel help查看
[root@yq01-aip-aikefu06e1a866 ~]# ip tunnel help Usage: ip tunnel { add | change | del | show | prl | 6rd } [ NAME ] [ mode { ipip | gre | sit | isatap | vti } ] [ remote ADDR ] [ local ADDR ]
- ipip:即 IPv4 in IPv4,在 IPv4 报文的基础上再封装一个 IPv4 报文。
- gre:即通用路由封装(Generic Routing Encapsulation),定义了在任意一种网络层协议上封装其余任意一种网络层协议的机制,IPv4 和 IPv6 都适用。
- sit:和 ipip 相似,不一样的是 sit 是用 IPv4 报文封装 IPv6 报文,即 IPv6 over IPv4。
- isatap:即站内自动隧道寻址协议(Intra-Site Automatic Tunnel Addressing Protocol),和 sit 相似,也是用于 IPv6 的隧道封装。
- vti:即虚拟隧道接口(Virtual Tunnel Interface),是 cisco 提出的一种 IPsec 隧道技术。
二、BGP模式
边界网关协议(BorderGateway Protocol, BGP)是互联网上一个核心的去中心化的自治路由协议。它经过维护IP路由表或‘前缀’表来实现自治系统(AS)之间的可达性,属于矢量路由协议。BGP不使用传统的内部网关协议(IGP)的指标,而是基于路径、网络策略或规则集来决定路由。所以,它更适合被称为矢量性协议,而不是路由协议,通俗的说就是将接入到机房的多条线路(如电信、联通、移动等)融合为一体,实现多线单IP;
BGP 机房的优势:服务器只须要设置一个IP地址,最佳访问路由是由网络上的骨干路由器根据路由跳数与其它技术指标来肯定的,不会占用服务器的任何系统。
Flannel
flannel 架构

flannel的udp模式和vxlan模式都是属于隧道方式,也就是在udp的基础之上,构建虚拟网络,而后经过一个封包解包的过程来实现数据的传输。
flannel的几种模式
flannel经过在每个节点上启动一个叫flannel的进程,负责为每个节点上的子网划分,并将相关配置信息(如各节点的子网网段、外部IP等)保存到etcd中,而具体的网络报文转发交给backend实现。
flanneld能够在启动时经过配置文件指定不一样的backend进行网络通讯,目前比较 成熟的backend有UDP、VXLAN和host-gateway三种。目前,VXLAN是官方比较推崇的一种backend实现方式。
UDP模式和VXLAN模式基于三层网络层便可实现,而host-gateway模式就必需要求集群全部机器在同一个广播域,也就是须要在二层网络同一个交换机下才能实现。
host-gateway通常用于对网络性能要求比较高的场景,但须要基础网络架构的支持;UDP则用于测试及通常比较老的不支持VXLAN的Linux内核。
一、UDP模式
采用UDP模式时,须要在flanneld的配置文件中指定Backend.Type为UDP,可经过直接修改flanneld的ConfigMap的方式实现。
# kubectl get cm kube-flannel-cfg -n kube-system -o yaml kubectl net-conf.json: | { "Network": "10.233.64.0/18", "Backend": { "Type": "udp" } }
经过ip addr 命令能够发现节点上会多出一个flannel 0的网络接口,在UDP模式中,flanneld的主要做用为:
(1)UDP包封包解包
(2)节点上路由表的动态更新
工做流程图:

熟悉Linux的应该知道,Linux频繁内核态-用户态的切换,会形成频繁的上下文切换,会引起性能问题,因此从上面能够看到container的数据包,从离开src container后,通过了屡次内核态-用户态的切换,而且,数据包是由用户态的flannel进行进行封包/解包的,从而致使了比较大的性能损耗,这也是为何生产基本不会用这个方案,由于性能实在很是差。
二、VXLAN模式
一样须要在Backend.Type修改成VXLAN
net-conf.json: | { "Network": "10.233.64.0/18", "Backend": { "Type": "vxlan" } }
VXLAN模式下,会建立一个名为flannel 1的VTEP设备,数据的转发由内核完成,并非flanned,flanned仅动态设置ARP和FDB表项
流程图:

vxlan自己就是内核特性,使用vxlan会在服务器中建立一个vtep设备(flannel 1),设备的封包/解包操做都在该设备下操做,因此直接在内核态操做,不须要CPU上下文切换,且和UDP直接三层封包不同,vxlan是直接对二层数据帧进行封包。
三、host-gateway模式
同上须要在Backend.Type修改成host-gw。
因为host-gw是纯路由模式,flannel须要经过etcd维护全部的静态路由,核心是IP包在封装成桢的时候,使用路由表的"下一跳"设置上的MAC地址,这样能够通过二层网络到达目的宿主机。这就要求全部的服务器在同一个二层网络下,这就使host-gw模式没法适用于集群规模较大且须要对节点进行网段划分的场景。
host-gw另一个限制则是随着集群中节点规模的增大,flanneld维护主机上成千上万条路由表的动态更新也是一个不小的压力,所以在路由方式下,路由表规则的数量是限制网络规模的一个重要因素。
流程图:

在性能上,host-gw因为没有封包/解包,故性能最好