点击蓝字 关注我们

CloudTech TEAM
本文深入探讨Kubernets集群中如何构建网络与连接。文章介绍Node网络和Pod网络,分析CNI插件的作用,并对比了Calico和Flannel两种常用网络插件的特点和工作原理,为技术人员提供了容器网络的全面解析。
CloudTech TEAM 文 孙连辰 段晓宇
01 引言
在之前的章节中,我们了解了容器网络的基本工作方式,容器的网络基于更轻量的虚拟化网络,而网络之间的隔离基于Linux定义的全局变量Namespace(Net),同时结合NetworkStack,网桥,veth等虚拟设备构建了容器网络的连接。那么在接下来的章节中,我们将继续了解,在Kubernets集群中是如何构建网络与连接的。
02 Node节点网络

节点之间的网络不需要过多复杂的设计,每个节点既可以是公有云或私有云虚拟SDN网络,同时也可以是数据中心下的物理网络,保证“物理上”可达。承载节点之间服务的网络流量。所有Pod之间的网络均需要通过节点的物理网络承载。物理网络的搭建与K8s的网络并没有关系,但节点网络的搭建,可能会影响后续CNI插件的选型,如使用二层或使用三层通讯。
03 Pod节点网络
同节点Pod通讯

当Pod1与Pod2的通讯过程会分以下几个步骤:
Pod1向Pod2发送请求
Node1会检查本地路由表并发现Pod2在本地路由(均通过cnixxxx虚拟设备连接)
节点内的虚拟网桥(或CNI0)直接将请求转发到Pod2
Pod2收到请求并处理,将数据包响应原路径返回Pod1
上溯过程可以发现,同一个节点的上的Pod通讯流转,流量时没有出主机的。经过我们直接的分析,我们知道。这次的访问仅仅是在网络内核协议栈中直接完成,请求速度是非常快的,也不需要通过CNI插件去创建隧道或层三通讯。但这种通讯,仍然可以通过NetworkPolicy 达到隔离的目的。可以看出,同一节点的通讯与虚拟机或者容器网络是一致都是直接通过本地虚拟交换机或者网桥完成的通讯,流量都不会在主机外部流转。
跨节点Pod通讯
由于Pod本身并不具备夸节点通讯的能力,想要实现Pod得跨节点之间的网络访问,需要通过CNI插件或节点网络的能力,保证通讯,那么在介绍跨节点Pod通讯之前,我们先了解回顾Pod网络的创建过程以及CNI的简介。

首先,通过上面一组流程,我们可以看到调度的几个关键步骤。当部署一个Pod网络资源对象的时候,API-server会收到这个请求,根据特定的调度算法通知集群某一个节点的Kubelet进程,在本节点完成Pod的创建过程,接下来会由CRI(容器运行时接口)会收到这个请求去创建Pod的namespace。那么一个Pod可能会有多个容器。所以网络命名空间创建好之后,Pod内的容器会共享同一个网络命名空间,包括“Networkstack”和“IP”那么这些资源会由CRI规范中的一环-Sandbox进行网络以及存储资源的整合。Sandbox最大的作用是维护Pod网络协议栈,当Pod沙箱(Pod Sandbox)建立起来后,Kubelet 就可以在里面创建用户容器。当到删除Pod时,Kubelet 会先移除Pod Sandbox然后再停止里面的所有容器。对于Linux容器,Pod Sandbox就是Linux Namespace。完成Pod初始化后,CRI则会调用CNI plugin用于更详细资源配置,包括:1.创建虚拟网络接口、分配IP地址、配置本地路由表、以及连接网桥至虚拟设备。完成这些工作后,至此,容器网络与节点之间的网络则会打通。接下来会根据不同CNI特点实现Pod之间跨节点的访问。
CNI(contanier network interface)
CNI是CNCF项目,提供规范来创建配置容器网络(不仅仅应用于kubernets、包括Mesos、CloudFondry,Podman、CRI- O)。CNI的主要功能包括:
创建网络接口,连接Pod之间的网络。通过overlay、route&underlay etc,(不通过Nat)
进行IP地址管理
提供网络安全策略
那么根据不同的网络插件类型,我们将介绍两种常用的插件做进一步了解;接下来将主要介绍Calico以及Flannel以及各自的特点便于大家进行区分理解。
Calico

上图为calico BGP模式部署工作方式。Calico的组网模式是纯三层的结构。适合大型数据中心使用,并且由于BGP的特性与大多数平台底座均能够正常兼容。我们可以把每一个Node节点(worker)充当路由器(vRouter)的角色,他们为本地运行的容器或者VM提供路由,通过BGP控制路由的分发,Felix来管理路由信息。从而打通整个Pod网络的互联,同时在大型数据中上我们可以使用RR的模式,使集群IP全互联(Full mesh)。
etcd,分布式键值存储,主要负责网络元数据一致性,确保Calico网络状态的准确性;
Felix 跑在每个节点上,负责配置路由、ACL、向etcd宣告状态等
BGP Client(BIRD), 主要负责把Felix写入Kernel的路由信息分发到当前Calico网络,确保Workload间的通信的有效性;
BGP Route Reflector(RR),大规模部署时使用,摒弃所有节点互联的 mesh 模式,通过一个或者多个BGP Route Reflector来完成集中式的路由分发。
但由于Caclio的特性,作为运维人员,我们通常希望限制这种流通性,比如通过多租户的隔离,如果想要实在安全的隔离,Networkpolicy是一种方式,同样还可以操作主机上的iptables的条目,但这样的缺点是,需要维护的条目以及种类过于庞大。路由条目的数量与节点的集群的规模成正比,运维难度较大,那么有没有一种相对简单的配置方式呢。无需维护过于复杂的路由表呢。
Flannel
在介绍Flannel之前,我们先简单了解一下Vxlan。

Vxlan(virtual Extensible LAN)虚拟可扩展局域网,是一种Overlay技术,将原始的2层以太网帧进行UDP封装(Mac in UDP),同时由于Vxlan更好的扩展性和更大的局域网划分可以很好解决在大型网络环境中Vlan 数量不够的问题,同时Vxlan的特性也更好可以与租户隔离绑定,实现网络租户管理、隔离等功能。我们可以简单看一下Vxlan的封装以及通讯过程,这里拿虚拟机举例

当VM1向VM2通讯请求时ARP报文转发过程:
向VM1向VM2发出ARP Request,Src MAC为MAC-A(VM1),Dst MAC为全f(广播);
ARP Request报文到达vtep-1后,vtep-1对其封装VXLAN包头,其中外层的Src MAC为vtep-1的MAC-1,Dst MAC为组播mac地址, Src ip为vtep-1的IP-1,Dst ip为组播ip地址,并且打上了VXLAN VNID:5001 由于vtep之间是三层网络互联的,广播包无法穿越三层网络,所以只能借助组播来实现arp报文的泛洪。通常情况下一个组播地址对应一个VNID(5001),同时可能会对应一个租户或者对应一个vrf网络,通过VNID进行租户之间的隔离。
打了VXLAN头的报文转发到了其他的vtep上,进行VXLAN头解封装,原始的ARP Request报文被转发给了vtep下面的VM2,并且在vtep上生成一条MAC-A(VM1的mac)、VXLAN ID、IP-1(vtep-1的ip)的对应表项;
VM2收到ARP请求,回复ARP Response,Src MAC:MAC-B(VM2)、Dst MAC:MAC-A(VM1);
ARP Response报文到达vtep-2后,被打上VXLAN的包头,此时外层的源目mac和ip以及VXLAN ID是根据之前在vtep-2上的MAC-A、VXLAN ID、IP-1对应表项来封装的,所以ARP Response是以单播的方式回复给VM1;
打了VXLAN头的报文转发到vtep-1后,进行VXLAN头的解封装,原始的ARP Response报文被转发给了VM1;
VM1收到VM2返回的ARP Response报文,整个ARP请求完成。
那么我们了解了Vxlan的封装与解封装原理后,再看一下Flannel的处理过程

Flannel创建一个类似vtep的隧道终结点(flannel.1)用于封装与解封装vxlan的数据包,每个节点分配一个子网,所有Pod才能够本地子网中分配Ip。Pod在本地使用birdge的L2通讯,跨节点Pod之间通讯物理上仍然依赖于主机网络节点之间的通讯,但逻辑上建立了一条udp随道,这与VM的通讯过程是完全一致的,每个Pod的Ip 在集群网络级别不可见,同时又能保证Pod之间互通。除了vxlan的方式。Flannel也支持IP IP 和Host gw 两种后端。但是,由于vxlan的封装与解封装需要大量消耗主机CPu资源,可能在一些高性能的网络需求下会有较大延迟。
以上,两种CNi插件基本比较常用的两种方式。后续,我们可以在后续的技术选型中,结合自己的需要,进一步明确。
04 总结与展望
那么,本次容器网络集群中的通讯就介绍完了,将会在下一章节继续讨论,关于Service网络以及外部接入网络是如何工作的。
END
欢迎转发、点赞或点击在看,让更多同行看到
点击公众号名片阅读更多内容
# 往期推荐 #




