k8s⽹络之Calico⽹络
Calico 是⼀种容器之间互通的⽹络⽅案。在虚拟化平台中,⽐如 OpenStack、Docker 等都需要实现 workloads 之间互连,但同时也需要对容器做隔离控制,就像在 Internet 中的服务仅开放80端⼝、公有云的多租户⼀样,提供隔离和管控机制。
⽽在多数的虚拟化平台实现中,通常都使⽤⼆层隔离技术来实现容器的⽹络,这些⼆层的技术有⼀些弊端,⽐如需要依赖 VLAN、bridge 和隧道等技术,
其中 bridge 带来了复杂性,vlan 隔离和 tunnel 隧道则消耗更多的资源并对物理环境有要求,随着⽹络规模的增⼤,整体会变得越加复杂。
我们尝试把 Host 当作 Internet 中的路由器,同样使⽤ BGP 同步路由,并使⽤ iptables 来做安全访问策略,最终设计出了 Calico ⽅案。
适⽤场景:k8s环境中的pod之间需要隔离
设计思想:Calico 不使⽤隧道或 NAT 来实现转发,⽽是巧妙的把所有⼆三层流量转换成三层流量,并通过 host 上路由配置完成跨 Host 转发。
设计优势:
1.更优的资源利⽤
⼆层⽹络通讯需要依赖⼴播消息机制,⼴播消息的开销与 host 的数量呈指数级增长,Calico 使⽤的三层路由⽅法,则完全抑制了⼆层⼴播,减少了资源开销。
另外,⼆层⽹络使⽤ VLAN 隔离技术,天⽣有 4096 个规格限制,即便可以使⽤ vxlan 解决,但 vxlan ⼜带来了隧道开销的新问题。⽽ Calico 不使⽤ vlan 或 vxlan 技术,使资源利⽤率更⾼。
2.可扩展性
Calico 使⽤与 Internet 类似的⽅案,Internet 的⽹络⽐任何数据中⼼都⼤,Calico 同样天然具有可扩展性。
3.简单⽽更容易 debug
因为没有隧道,意味着 workloads 之间路径更短更简单,配置更少,在 host 上更容易进⾏ debug 调试。
4.更少的依赖
Calico 仅依赖三层路由可达。
5.可适配性
Calico 较少的依赖性使它能适配所有 VM、Container、⽩盒或者混合环境场景。
Calico 是⼀个三层的数据中⼼⽹络⽅案,⽽且⽅便集成 OpenStack 这种 IaaS 云架构,能够提供⾼效可控的 VM、容器、裸机之间的通信。
Calico不使⽤重叠⽹络⽐如flannel和libnetwork重叠⽹络驱动,它是⼀个纯三层的⽅法,使⽤虚拟路由代替虚拟交换,每⼀台虚拟路由通过BGP协议传播可达信息(路由)到剩余数据中⼼;Calico在每⼀个计算节点利⽤Linux Kernel实现了⼀个⾼效的vRouter来负责数据转发,
⽽每个vRouter通过BGP协议负责把⾃⼰上运⾏的workload的路由信息像整个Calico⽹络内传播——⼩规模部署可以直接互联,⼤规模下可通过指定的BGP route reflector来完成。
缺陷:
从上⾯的通信过程来看,跨主机通信时,整个通信路径完全没有使⽤NAT或者UDP封装,性能上的损耗确实⽐较低。但正式由于calico的通信机制是完全基于三层的,这种机制也带来了⼀些缺陷,例如:
calico⽬前只⽀持TCP、UDP、ICMP、ICMPv6协议,如果使⽤其他四层协议(例如NetBIOS协议),建议使⽤weave、原⽣overlay等其他overlay⽹络实现。
基于三层实现通信,在⼆层上没有任何加密包装,因此只能在私有的可靠⽹络上使⽤。
流量隔离基于iptables实现,并且从etcd中获取需要⽣成的隔离规则,有⼀些性能上的隐患
结合上⾯这张图,我们来过⼀遍 Calico 的核⼼组件:
Felix:主要的Calico代理agent Calico agent,跑在每台需要运⾏ workload 的节点上,主要负责配置路由及 ACLs 等信息来确保 endpoint 的连通状态;
Felix是⼀个守护程序,它在每个提供endpoints资源的计算机上运⾏。在⼤多数情况下,这意味着它需要在托管容器或VM的宿主机节点上运⾏。 Felix 负责编制路由和ACL规则以及在该主机上所需的任何其他内容,以便为该主机上的endpoints资源正常运⾏提供所需的⽹络连接。
根据特定的编排环境,Felix负责以下任务:
管理⽹络接⼝,Felix将有关接⼝的⼀些信息编程到内核中,以使内核能够正确处理该endpoint发出的流量。特别是,它将确保主机正确响应来⾃每个⼯作负载的ARP请求,并将为其管理的接⼝启⽤IP转发⽀持。它还监视⽹络接⼝的出现和消失,以便确保针对这些接⼝的编程得到了正确的应⽤。
编写路由,Felix负责将到其主机上endpoints的路由编写到Linux内核FIB(转发信息库)中。这可以确保那些发往⽬标主机的endpoints的数据包被正确地转发。
编写ACLs,Felix还负责将ACLs编程到Linux内核中。这些ACLs⽤于确保只能在endpoints之间发送有效的⽹络流量,并确保endpoints⽆法绕过Calico的安全措施。
报告状态,Felix负责提供有关⽹络健康状况的数据。特别是,它将报告配置其主机时发⽣的错误和问题。该数据会被写⼊etcd,以使其对⽹络中的其他组件和操作才可见。Orchestrator Plugin
每个主要的云编排平台都有单独的Calico⽹络插件(例如OpenStack,Kubernetes)。这些插件的⽬的
是将Calico更紧密地绑定到编排⼯具中,允许⽤户管理Calico⽹络,就像他们管理编排⼯具中内置的⽹络⼯具⼀样。
⼀个好的Orchestrator插件⽰例是Calico Neutron ML2 驱动程序。该插件与Neutron的ML2插件集成,允许⽤户通过Neutron API调⽤来配置Calico⽹络,实现了与Neutron的⽆缝集成。
Orchestrator插件负责以下任务:
API Translation,每个云编排⼯具都不可避免地拥有⾃⼰的⼀套⽤于管理⽹络的API接⼝规范, Orchestrator插件的主要⼯作就是将这些API转换为Calico的数据模型,然后将其存储在Calico的数据存储区中。这种转换中的⼀些⼯作将⾮常简单,其他⼀部分可能更复杂,以便将单个复杂操作(例如,实时迁移)转换为Calico⽹络期望的⼀系列更简单的操作。
Feedback,如有需要,orchestrator插件将从Calico⽹络向编排器提供管理命令的反馈信息。包括提供有关Felix存活的信息,以及如果⽹络配置失败则将某些endpoints标记为失败。
ETCD: 分布式键值存储,主要负责⽹络元数据⼀致性,确保 Calico ⽹络状态的准确性
etcd是⼀个分布式键值存储数据库,专注于实现数据存储⼀致性。 Calico使⽤etcd提供组件之间的数据通信,并作为可以保证⼀致性的数据存储,以确保Calico始终可以构建出⼀个准确的⽹络。
根据orchestrator插件的不同,etcd既可以是作为主数据存储使⽤,也可以是⼀个单独数据存储的轻量级镜像。例如,在OpenStack部署中,OpenStack数据库被认为是“真实配置信息的来源”,⽽etcd⽤于镜像其中有关⽹络配置的信息,并⽤于服务其他Calico组件。
etcd组件穿插在整个部署中。它可以被分为两组主机节点:核⼼集和代理。
对于⼩型部署,核⼼集可以是⼀个节点的etcd集(通常与orchestrator插件组件位于同⼀节点上)。这种部署模型很简单但没有为etcd提供冗余。在etcd失败的情况
下,orchstrator插件必须重建数据库,例如OpenStack,它需要插件从OpenStack数据库重新同步状态到etcd。
在较⼤的部署中,核⼼集可以根据etcd管理指南进⾏扩展。
此外,在运⾏Felix或orchstrator插件的每台计算机上,会运⾏⼀个etcd代理服务。这减少了etcd核⼼集上的负载,并为主机节点屏蔽了etcd服务集的细节。在etcd集与orchstrator插件在同⼀台机器上都有成员的情况下,可以放弃在该机器上使⽤etcd代理。
etcd负责执⾏以下任务:
Data Storage,etcd以分布式、⼀致和容错的⽅式存储Calico⽹络的数据(对于⾄少三个etcd节点的cluster⼤⼩)。这确保Calico⽹络始终处于已知良好状态,同时允许运⾏etcd 的个别机器节点失败或⽆法访问。Calico⽹络数据的这种分布式存储提⾼了Calico组件从数据库读取的能⼒。
Communication,etcd也⽤作组件之间的通信服务。我们通过让⾮etcd组件监视键值空间中的某些点来确保他们看到已经做出的任何更改,从⽽允许他们及时响应这些更改。该功能允许将状态信息提交到数据库,然后触发基于该状态数据的进⼀步⽹络配置管理。
BIRD是什么
BIRD是布拉格查理⼤学数学与物理学院的⼀个学校项⽬,项⽬名是BIRD Internet Routing Daemon的缩写。⽬前,它由CZ.NIC实验室开发和⽀持。
作为⼀个开源的⽹络路由守护进程项⽬,BRID设计并⽀持了以下功能:
both IPv4 and IPv6 protocols
multiple routing tables
the Border Gateway Protocol (BGPv4)
the Routing Information Protocol (RIPv2, RIPng)
the Open Shortest Path First protocol (OSPFv2, OSPFv3)
the Babel Routing Protocol
the Router Advertisements for IPv6 hosts
a virtual protocol for exchange of routes between different routing tables on a single host
a command-line interface allowing on-line control and inspection of status of the daemon
soft reconfiguration (no need to use complex online commands to change the configuration, just edit the configuration file and notify BIRD to re-read it and it will smoothly switch itself to the new configuration, not disturbing routing protocols unless they are affected by the configuration changes)
a powerful language for route filtering
BGP Client (BIRD): 主要负责把 Felix 写⼊ kernel 的路由信息分发到当前 Calico ⽹络,确保 workload 间的通信的有效性;
Calico在每个运⾏Felix服务的节点上都部署⼀个BGP客户端。 BGP客户端的作⽤是读取Felix程序编写到内核中并在数据中⼼内分发的路由信息。
BGP客户端负责执⾏以下任务:
路由信息分发,当Felix将路由插⼊Linux内核FIB时,BGP客户端将接收它们并将它们分发到集中的其他⼯作节点。
BGP Route Reflector (BIRD) : ⼤规模部署时使⽤,摒弃所有节点互联的 mesh 模式,通过⼀个或者多个BGP Route Reflector来完成集中式的路由分发
对于较⼤规模的部署,简单的BGP可能成为限制因素,因为它要求每个BGP客户端连接到⽹状拓扑中的每⼀个其他BGP客户端。这需要越来越多的连接,迅速变得难以维护,甚⾄会让⼀些设备的路由表撑满。
因此,在较⼤规模的部署中,Calico建议部署BGP Route Reflector。通常是在Internet中使⽤这样的组件充当BGP客户端连接的中⼼点,从⽽防⽌它们需要与集中的每个BGP 客户端进⾏通信。为了实现冗余,也可以同时部署多个BGP Route Reflector服务。Route Reflector仅仅是协助管理BGP⽹络,并没有endpoint数据会通过它们。
在Calico中,此BGP组件也是使⽤的最常见的BIRD,配置为Route Reflector运⾏,⽽不是标准BGP客户端。
BGP Route Reflector负责以下任务:
集中式的路由信息分发,当Calico BGP客户端将路由从其FIB通告到Route Reflector时,Route Reflector会将这些路由通告给部署集中的其他节点。
总结:
利⽤了Linux内核原⽣的路由和iptables防⽕墙功能。进出各个容器、虚拟机和物理主机的所有流量都会在路由到⽬标之前遍历这些内核规则。
Felix:主要的Calico代理agent,运⾏每台计算机上管理endpoints资源。
calicoctl:允许从命令⾏界⾯配置实现⾼级策略和⽹络。
orchestrator plugins:提供与各种流⾏的云计算编排⼯具的紧密集成和同步⽀持。
key/value store:存储Calico的策略配置和⽹络状态信息,⽬前主要使⽤etcdv3或k8s api。
calico/node:在每个主机上运⾏,从key/value存储中读取相关的策略和⽹络配置信息,并在Linux内核中实现它。
Dikastes/Envoy:可选的Kubernetes sidecars,可以通过相互TLS⾝份验证保护⼯作负载到⼯作负载的通信,并增加应⽤层控制策略。
通过将整个互联⽹的可扩展 IP ⽹络原则压缩到数据中⼼级别,Calico 在每⼀个计算节点利⽤Linux kernel实现了⼀个⾼效的vRouter来负责数据转发⽽每个vRouter通过BGP
协议负责把⾃⼰上运⾏的 workload 的路由信息像整个 Calico ⽹络内传播-⼩规模部署可以直接互联,⼤规模下可通过指定的BGP route reflector 来完成。这样保证最终所有的workload 之间的数据流量都是通过 IP 包的⽅式完成互联的
Calico原理
Calico把每个操作系统的协议栈认为是⼀个路由器,然后把所有的容器认为是连在这个路由器上的⽹络终端,在路由器之间跑标准的路由协议——BGP的协议,然后让它们⾃⼰去学习这个⽹络拓扑该如何转发。
所以Calico⽅案其实是⼀个纯三层的⽅案,也就是说让每台机器的协议栈的三层去确保两个容器,跨主
机容器之间的三层连通性。
对于控制平⾯,它每个节点上会运⾏两个主要的程序,⼀个是Felix,它会监听ECTD中⼼的存储,从它获取事件,⽐如说⽤户在这台机器上加了⼀个IP,或者是分配了⼀个容器等。接着会在这台机器上创建出⼀个容器,并将其⽹卡、IP、MAC都设置好,然后在内核的路由表⾥⾯写⼀条,注明这个IP应该到这张⽹卡。
绿⾊部分是⼀个标准的路由程序,
它会从内核⾥⾯获取哪⼀些IP的路由发⽣了变化,然后通过标准BGP的路由协议扩散到整个其他的宿主机上,让外界都知道这个IP在这⾥,你们路由的时候得到这⾥来。
由于Calico是⼀种纯三层的实现,因此可以避免与⼆层⽅案相关的数据包封装的操作,中间没有任何的NAT,没有任何的overlay,所以它的转发效率可能是所有⽅案中最⾼的,因为它的包直接⾛原⽣TCP/IP的协议栈,它的隔离也因为这个栈⽽变得好做
因为TCP/IP的协议栈提供了⼀整套的防⽕墙的规则,所以它可以通过IPTABLES的规则达到⽐较复杂的隔离逻辑。
Calico 节点组⽹可以直接利⽤数据中⼼的⽹络结构(⽀持 L2 或者 L3),不需要额外的 NAT,隧道或者 VXLAN overlay network。
如上图所⽰,这样保证这个⽅案的简单可控,⽽且没有封包解包,节约 CPU 计算资源的同时,提⾼了
整个⽹络的性能。tcpip协议中tcp协议负责接入互联网
此外,Calico 基于 iptables 还提供了丰富⽽灵活的⽹络 policy, 保证通过各个节点上的 ACLs 来提供 workload 的多租户隔离、安全组以及其他可达性限制等功能。
在主机⽹络拓扑的组织上,calico的理念与weave类似,都是在主机上启动虚拟机路由器,将每个主机作为路由器使⽤,组成互联互通的⽹络拓扑。当安装了calico的主机组成集后
其拓扑如下图所⽰
每个主机上都部署了calico/node作为虚拟路由器,并且可以通过calico将宿主机组织成任意的拓扑集。当集中的容器需要与外界通信时,就可以通过BGP协议将⽹关物理路由器加⼊到集中,使外界可以直接访问容器IP,⽽不需要做任何NAT之类的复杂操作。
当容器通过calico进⾏跨主机通信时,其⽹络通信模型如下图所⽰:
从上图可以看出,当容器创建时,calico为容器⽣成veth pair,⼀端作为容器⽹卡加⼊到容器的⽹络命名
空间,并设置IP和掩码,⼀端直接暴露在宿主机上,并通过设置路由规则,将容器IP暴露到宿主机的通信路由上。
于此同时,calico为每个主机分配了⼀段⼦⽹作为容器可分配的IP范围,这样就可以根据⼦⽹的CIDR为每个主机⽣成⽐较固定的路由规则。
当容器需要跨主机通信时,主要经过下⾯的简单步骤:
容器流量通过veth pair到达宿主机的⽹络命名空间上。
根据容器要访问的IP所在的⼦⽹CIDR和主机上的路由规则,到下⼀跳要到达的宿主机IP。
流量到达下⼀跳的宿主机后,根据当前宿主机上的路由规则,直接到达对端容器的veth pair插在宿主机的⼀端,最终进⼊容器。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论