calico和flannel的优缺点
1.Kubernetes通信问题
1.容器间通信:即同一个Pod内多个容器间通信,通常使用loopback来实现。
2.Pod间通信:K8s要求,Pod和Pod之间通信必须使用Pod-IP 直接访问另一个Pod-IP
3.Pod与Service通信:即PodIP去访问ClusterIP,当然,clusterIP实际上是IPVS或iptables规则的虚拟IP,是没有TCP/IP协议栈支持的。但不影响Pod访问它.
4.Service与集群外部Client的通信,即K8s中Pod提供的服务必须能被互联网上的用户所访问到。
需要注意的是,k8s集群初始化时的service网段,pod网段,网络插件的网段,以及真实服务器的网段,都不能相同,如果相同就会出各种各样奇怪的问题,而且这些问题在集群做好之后是不方便改的,改会导致更多的问题,所以,就在搭建前将其规划好。
CNI(容器网络接口):
这是K8s中提供的一种通用网络标准规范,因为k8s本身不提供网络解决方案。
目前比较知名的网络解决方案有:
- Flannel
- calico
- canel
- kube-router
- .......
等等,目前比较常用的时flannel和calico,flannel的功能比较简单,不具备复杂网络的配置能力,calico是比较出色的网络管理插件,单具备复杂网络配置能力的同时,往往意味着本身的配置比较复杂,所以相对而言,比较小而简单的集群使用flannel,考虑到日后扩容,未来网络可能需要加入更多设备,配置更多策略,则使用calico更好
所有的网络解决方案,它们的共通性:
1.虚拟网桥
2.多路复用:MacVLAN
3.硬件交换:SR-IOV(单根-I/O虚拟网络):它是一种物理网卡的硬件虚拟化技术,它通过输出VF(虚拟功能)来将网卡虚拟为多个虚拟子接口,每个VF绑定给一个VM后,该VM就可以直接操纵该物理网卡。
kubelet来调CNI插件时,会到/etc/cni/net.d/
目录下去找插件的配置文件,并读取它,来加载该插件,并让该网络插件来为Pod提供网络服务。
2.Calico
2.1 Calico简介
Calico是一个纯三层的网络插件,calico的bgp模式类似于flannel的host-gw。
Calico方便集成OpenStack这种 IaaS云架构,为openstack虚拟机、容器、裸机提供多主机间通信。
2.2 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 来完成集中式的路由分发;
2.3 calico 原理
calico是一个纯三层的虚拟网络,它没有复用docker的docker0网桥,而是自己实现的,calico网络不对数据包进行额外封装,不需要NAT和端口映射,扩展性和性能都很好。Calico网络提供了DockerDNS服务,容器之间可以通过hostname访问,Calico在每一个计算节点利用Linux Kernel实现了一个高效的vRouter(虚拟路由)来负责数据转发,它会为每个容器分配一个ip,每个节点都是路由,把不同host的容器连接起来,从而实现跨主机间容器通信。而每个vRouter通过BGP协议(边界网关协议)负责把自己节点的路由信息向整个Calico网络内传播——小规模部署可以直接互联,大规模下可通过指定的BGProute reflector来完成;Calico基于iptables还提供了丰富而灵活的网络策略,保证通过各个节点上的ACLs来提供多租户隔离、安全组以及其他可达性限制等功能。
Calico是一种非常复杂的网络组件,它需要自己的etcd数据库集群来存储自己通过BGP协议获取的路由等各种所需要持久保存的网络数据信息,因此在部署Calico时,早期是需要单独为Calico部署etcd集群的,因为在k8s中,访问etcd集群只有APIServer可以对etcd进行读写,其它所有组件都必须通过APIServer作为入口,将请求发给APIServer,由APIServer来从etcd获取必要信息来返回给请求者,但Caclico需要自己写,因此就有两种部署Calico网络插件的方式,一种是部署两套etcd,另一种就是Calico不直接写,而是通过APIServer做为代理,来存储自己需要存储的数据。通常第二种使用的较多,这样可降低系统复杂度。
当然由于Calico本身很复杂,但由于很多k8s系统可能存在的问题是,早期由于各种原因使用了flannel来作为网络插件(flannel会讲解原因)。
2.4 calico网络模式
1.ipip模式
把一个IP数据包又套在一个IP包里,即把IP层封装到IP层的一个tunnel,它的作用其实基本上就相当于一个基于IP层的网桥,一般来说,普通的网桥是基于mac层的,根本不需要IP,而这个ipip则是通过两端的路由做一个tunnel,把两个本来不通的网络通过点对点连接起来;
calico以ipip模式部署完毕后,node上会有一个tunl0的网卡设备,这是ipip做隧道封装用的,也是一种overlay模式的网络。当我们把节点下线,calico容器都停止后,这个设备依然还在,执行 modprobe -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@centos7 ~]# 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隧道技术。
2.BGP模式
边界网关协议(BorderGateway Protocol, BGP)是互联网上一个核心的去中心化的自治路由协议。它通过维护IP路由表或‘前缀’表来实现自治系统(AS)之间的可达性,属于矢量路由协议。BGP不使用传统的内部网关协议(IGP)的指标,而是基于路径、网络策略或规则集来决定路由。因此,它更适合被称为矢量性协议,而不是路由协议,通俗的说就是将接入到机房的多条线路(如电信、联通、移动等)融合为一体,实现多线单IP;
BGP机房的优点:服务器只需要设置一个IP地址,最佳访问路由是由网络上的骨干路由器根据路由跳数与其它技术指标来确定的,不会占用服务器的任何系统。
3.Flannel
3.1 flannel架构
flannel的udp模式和vxlan模式都是属于隧道方式,也就是在udp的基础之上,构建虚拟网络,然后通过一个封包解包的过程来实现数据的传输。
3.2 flannel的几种模式
通过在每一个节点上启动一个叫flannel的进程,负责为每一个节点上的子网划分,并将相关配置信息(如各节点的子网网段、外部IP等)保存到etcd中,而具体的网络报文转发交给backend实现。
flanneld可以在启动时通过配置文件指定不同的backend进行网络通信,目前比较成熟的backend有UDP、VXLAN和host-gateway三种。目前,VXLAN是官方比较推崇的一种backend实现方式。
UDP模式和VXLAN模式基于三层网络层即可实现,而host-gateway模式就必须要求集群所有机器在同一个广播域,也就是需要在二层网络同一个交换机下才能实现。
host-gatewa一般用于对网络性能要求比较高的场景,但需要基础网络架构的支持;UDP则用于测试及一般比较老的不支持VXLAN的Linux内核。
1.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进行进行封包/解包的,从而导致了比较大的性能损耗,这也是为什么生产基本不会用这个方案,因为性能实在非常差。
2.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是直接对二层数据帧进行封包。
3.host-gateway模式
同上需要在Backend.Type修改为host-gw。
由于host-gw是纯路由模式,flannel需要通过etcd维护所有的静态路由,核心是IP包在封装成桢的时候,使用路由表的"下一跳"设置上的MAC地址,这样可以经过二层网络到达目的宿主机。这就要求所有的服务器在同一个二层网络下,这就使host-gw模式无法适用于集群规模较大且需要对节点进行网段划分的场景。
host-gw另外一个限制则是随着集群中节点规模的增大,flanneld维护主机上成千上万条路由表的动态更新也是一个不小的压力,因此在路由方式下,路由表规则的数量是限制网络规模的一个重要因素。
工作流程图:
在性能上,host-gw由于没有封包/解包,故性能最好
calico和flannel的优缺点的更多相关文章
- 使用multus实现管理网和业务网分离——calico和flannel共存
多个网络层面的需求 一开始为k8s集群搭建了calico网络,所有的容器都用calico对应的网卡进行通信.为了实现网络监控的清爽,想把管理组件,例如日志.统计.监控等组件挪到另外一个网络.于是产生一 ...
- 042.集群网络-flannel及calico
一 Flannel组件 1.1 flannel介绍 Kubernetes的网络模型假定了所有Pod都在一个可以直接连通的扁平网络空间中.若需要实现这个网络假设,需要实现不同节点上的Docker容器之间 ...
- Flannel和Calico网络插件对比
1.Kubernetes通信问题 1.容器间通信:即同一个Pod内多个容器间通信,通常使用loopback来实现. 2.Pod间通信:K8s要求,Pod和Pod之间通信必须使用Pod-IP 直接访问另 ...
- Docker网络解决方案 - Calico部署记录
简单来说,实现docker跨主机容器间通信,常用的第三方网络方案是Flannel,Weave,Calico:Flannel会为每个host分配一个subnet,容器从这个subnet中分配ip,这些i ...
- 搞定 Kubernetes 基于flannel 的集群网络
.Docker网络模式 在讨论Kubernetes网络之前,让我们先来看一下Docker网络.Docker采用插件化的网络模式,默认提供bridge.host.none.overlay.maclan和 ...
- 容器网络——从CNI到Calico
从容器诞生开始,存储和网络这两个话题就一直为大家津津乐道.我们今天这个环境下讲网络这个问题,其实是因为容器对网络的需求,和传统物理.虚拟环境对网络环境需求是有差别的,主要面临以下两个问题: 过去Iaa ...
- 使用flannel+canal实现k8s的NetworkPolicy
目录 1.NetworkPolicy概述 2.NetworkPolicy策略模型 3.NetworkPolicy默认策略 4.NetworkPolicy的实现 5.使用flannel+canal实现k ...
- 使用kubeadm搭建Kubernetes(1.10.2)集群(国内环境)
目录 目标 准备 主机 软件 步骤 (1/4)安装 kubeadm, kubelet and kubectl (2/4)初始化master节点 (3/4) 安装网络插件 (4/4)加入其他节点 (可选 ...
- Kubernetes 在生产环境中常用架构
Kubernetes 在生产环境中常用架构 首先,我们来梳理下Kubernetes生产架构,其设计适用于绝大多数环境.如下图所示 在该架构中,我们可以将其分为四层,如下: Client层:即Kuber ...
随机推荐
- ZOJ 3537 (凸包 + 区间DP)(UNFINISHED)
#include "Head.cpp" const int N = 10007; int n, m; struct Point{ int x,y; bool operator &l ...
- Blazor和Vue对比学习(知识点杂锦3.04):Blazor中C#和JS互操作(超长文)
C#和JS互操作的基本语法是比较简单的,但小知识点特别多,同时,受应用加载顺序.组件生命周期以及参数类型的影响,会有比较多坑,需要耐心的学习.在C#中调用JS的场景会比较多,特别是在WASM模式下,由 ...
- java-Servlet-cookie and session
1 状态管理 a) 什么是状态管理?将浏览器与web服务器之间多次交互当做一个整体处理,并且将多次交互涉及的数据(即状态)保存下来. b) 如何进行状态管理? 可以将状态保存在客户端将状态保存到浏览器 ...
- 线性代数 | Jordan 标准型的笔记
内容概述: 把方阵 A 的特征多项式 \(c(λ)=|λE-A|\) 展开成 \(c(λ)=\sum_ia_i\lambda^i\) 的形式,然后使用神乎其技的证明,得到 \(c(A)=O\),特征多 ...
- IPV6属于自己专属公网IP
有了公网IP就可以搭建网站 简单理解公网IP就是私人的服务器 搭建之前一定要注意!没有网络安全意识的不要随便搭建 如何搭建? 材料如下 支持IPV6的光猫 支持IPV6的路由器 支持IPV6的设备 方 ...
- 【MySQL】从入门到精通7-设计多对多数据库
上期:[MySQL]从入门到精通6-MySQL数据类型与官方文档 第一章:理解 和一对多不一样,多对多意思是,一个数据可以被不同的数据关联. 如果是一对多,我们还可以用外键来达成. 但是现在我们是多对 ...
- Android序列化的几种实现方式
一.Serializable序列化 Serializable是java提供的一种序列化方式,其使用方式非常简单,只需要实现Serializable接口就可以实现序列化. public interfac ...
- Haproxy部署及控制台使用手册
一.介绍 1.简介 HAProxy是一个使用C语言编写开源软件,提供高可用,负载均衡,以及基于TCP(四层)和HTTP(七层)的应用程序代理: HAProxy特别适用于那些负载特大的web站点,这些站 ...
- KingbaseES R6 集群 recovery 参数对切换的影响
案例说明:在KingbaseES R6集群中,主库节点出现宕机(如重启或关机),会产生主备切换,但是当主库节点系统恢复正常后,如何对原主库节点进行处理,保证集群数据的一致性和安全,可以通过对repmg ...
- python脚本将json文件生成C语言结构体
1.引言 以前用过python脚本根据excel生成相关C语言代码,其实本质就是文件的读写,主要是逻辑问题,这次尝试将json文件生成C语言的结构体. 2.代码 这是一个json文件,生成这个结构体的 ...