数据平面的网络

Kubernetes 中的网络要解决的核心问题就是每台主机的 IP 地址网段划分,以及单个容器的 IP 地址分配。概括为:

  • 保证每个 Pod 拥有一个集群内唯一的 IP 地址
  • 保证不同节点的 IP 地址划分不会重复
  • 保证跨节点的 Pod 可以互相通信
  • 保证不同节点的 Pod 可以与跨节点的主机互相通信

为了解决该问题,出现了一系列开源的 Kubernetes 中的网络插件与方案,如:flannel、calico、weave、cilium


容器网络的实现方式有以下几种

image-20220221220406268

Flannel

Flannel是CoreOS团队针对Kubernetes设计的一个网络规划服务,简单来说,它的功能是让集群中的不同节点主机创建的Docker容器都具有全集群唯一的虚拟IP地址。

Flannel 实质上是一种overlay network,也就是将 TCP 数据包报封装在另一种网络包里面进行路由转发和通信

它的原理如下:

image-20210114154720661

  1. 数据从源容器中发出后,经由所在主机的docker0虚拟网卡转发到flannel0虚拟网卡。
  2. Flannel通过Etcd服务维护了一张节点间的路由表。
  3. 源主机的flanneld服务将原本的数据内容UDP封装后根据自己的路由表投递给目的节点的flanneld服务,数据到达以后被解包,然后直接进入目的节点的flannel0虚拟网卡,然后被转发到目的主机的docker0虚拟网卡,最后就像本机容器通信一下的有docker0路由到达目标容器。

这种虚拟化网络,会带来性能的损失

Calico

Calico 是一个纯三层的数据中心网络方案, 不需要额外的NAT、隧道或者Overlay Network。由于通信时不需要解包和封包,网络性能损耗小,易于排查,且易于水平扩展。

此外,Calico基于iptables还提供了丰富而灵活的网络Policy,保证通过各个节点上的ACLs来提供Workload的多租户隔离、安全组以及其他可达性限制等功能。

Calico 项目提供的 BGP 网络解决方案,与 Flannelhost-gw 模式几乎一样。也就是说,Calico也是基于路由表实现容器数据包转发,但不同于Flannel使用flanneld进程来维护路由信息的做法,而Calico项目使用BGP协议来自动维护整个集群的路由信息。Calico 项目实际上将集群里的所有节点,都当作是边界路由器来处理,它们一起组成了一个全连通的网络,互相之间通过 BGP 协议交换路由规则。

img

Calico主要由Felix、etcd、BGP client以及BGP Route Reflector组成

  1. Felix,Calico Agent,跑在每台需要运行Workload的节点上,主要负责配置路由及ACLs等信息来确保Endpoint的连通状态;
  2. etcd,分布式键值存储,主要负责网络元数据一致性,确保Calico网络状态的准确性;
  3. BGP Client(BIRD), 主要负责把Felix写入Kernel的路由信息分发到当前Calico网络,确保Workload间的通信的有效性;
  4. BGP Route Reflector(BIRD),大规模部署时使用,摒弃所有节点互联的 mesh 模式,通过一个或者多个BGP Route Reflector来完成集中式的路由分发。

Amazon VPC CNI

通过Amazon VPC CNI插件的使用,Pod可以分配到在 VPC 网络上的 IP 地址。用户可以实现同一个K8S集群部署在:

  • 一个VPC内,主机与Pod使用相同子网及安全组
  • 一个VPC内,主机与Pod使用不同子网及安全组
  • 多个VPC内,主机与Pod使用相同子网及安全组
  • 多个VPC内,主机与Pod使用不同子网及安全组

每一个Pod上都是VPC内真实的IP地址,即网卡上分配的Secondary IP

img

这种方式相对于flannel等方案更加简单直接,这样做带来的优点是:

  1. 实现集群内外ip直接互通网络——在k8s的落地过程当中,不少企业每每都有强烈的需求保证k8s集群内外网络的直连互通

  2. 减小了overlay方案中数据包的封包和拆包的网络损耗,可以提高性能

原理:

image-20220221222103626

  • L-IPAM(Local IP Address Manager)运行在每一个worker 节点上(其实就是aws-node daemonset),将全部ENI的全部secondary ip 加入到本地ip地址池中。那么,问题来了, ip地址池中的数据是从哪里来的呢?其实,aws ec2中有一个 ec2metadata 的概念,保存着关于该实例的全部信息,包括绑定到ec2的全部ENI, 以及ENI上的全部ip, 而且有相应的接口获取。默认情况下,CNI会预热相当于一个满ENI的IP。
  • 当CNI接受到建立pod事件请求时,就会经过gRPC请求IPAMD拿到ip并设置pod网络;反之,当接收到删除pod请求时就会通知IPAMD释放ip并同时删除pod网络。为什么需要预热而不是直接申请呢,这是因为申请IP的过程要花几秒钟,如果所有pod每次创建都要走几秒钟的申请IP过程,创建过程会显得非常慢。