跨主机容器网络方案

版权声明: https://blog.csdn.net/Andriy_dangli/article/details/84563710

跨主机容器网络方案

在Kubernetes体系中,Kubernetes网络模型设计的一个基本原则:每个Pod都拥有一个独立的IP地址,而且假定所有的Pod都在一个可以直接联通的、扁平的网络空间中,不管他们是否运行在同一个Node(宿主机)中,都可以直接通过对方的IP进行访问。也就是说Kubernetes默认是要求各个Node之间的容器网络能够互通,但Kubernetes本身不提供跨主机的容器网络方案。
目前,为容器设置Overlay网络是最主流的跨主机容器网络方案。在Kubernetes平台,建议通过CNI插件的方式部署容器网络。
CNI(Container Network Interface,容器网络接口)是CNCF基金会下的一个项目,有一组用于配置容器的网络接口的规范和库组成,现在已经被Kubernetes、rkt、Mesos等项目采纳,比较成熟。一个容器可以同时通过绑定多个CNI网络插件来加入到多个网络中。
下面介绍一下几种常用的网络方案:

1、Flannel

Flannel是由CoreOS公司为Kubernetes集群设计的一个Overlay网络方案,通过以下两种功能来实现Node上容器直接网络互通:

  • 为每一台Node的docker0网桥设置一个独立不冲突的IP地址池
  • 为各Node的docker0虚拟网络建立一个覆盖网络(Overlay Network),通过这个覆盖网络,将数据包原封不动地传递到目标容器中
    下图是Flanell网络模型的数据转发流程:
    在这里插入图片描述
    Flannel使用Kubernetes API或Etcd存储网络配置数据、子网分配及其他辅助信息。对于跨主机容器之间网络数据包的转发,Flannel支持一下之中模式:
  • hostgw是最简单的backend,它的原理非常简单,直接添加路由,将目的主机当做网关,直接路由原始封包。所有的主机都在同一个局域网内,保证二层网络连通。
  • udp:和hostgw不同的是,udp backend并不会将从etcd中监听到的事件里所包含的lease信息作为路由写入主机中。封包解包是在用户态和内核态交互处理,CPU性能有所损耗。
  • VxLAN:vxlan和上文提到的udp backend的封包结构是非常类似的,不同之处是多了一个vxlan header,以及原始报文中多了个二层的报头。封包解包在内核态处理,提高数据包处理速率。

2、Calico

Calico是由Tigera公司开发的基于BGP协议的网络方案,和其他虚拟网络最大的不同是,它没有采用 overlay 网络做报文的转发,提供了纯 3 层的网络模型。
Calico系统架构如图:
在这里插入图片描述
组件介绍:

  • Felix:Calico Agent,运行在每个Node节点上,负责为容器设置网络资源(IP地址、路由规则、Iptables等),保证跨主机的容器网络互通。
  • Etcd:提供后端存储。
  • BGP Client(BIRD):负责把Felix写入kernel的路由信息通过BGP协议广播到Calico网络中。
  • BGP Route Reflector(BIRD):一般在大规模部署时采用,与所有节点互联的mesh模式不同,通过一个或多个BGP Route Reflector来完成集中式的路由分发。
  • CalicoCtl:Calico的命令行管理工具。
    Calico保证所有容器之间的数据流量都是通过IP路由的方式完成互联互通的。Calico节点组网可以直接利用数据中心的网络结构(L2或L3),不需要额外的NAT、隧道或者Overlay Network,没有额外的封包解包,能够节约CPU运算且提高网络效率。

3、Macvlan

Macvlan是Linux Kernel的特性之一,通过Macvlan配置的容器网络与主机网络属于一个局域网,并且容器有自己独立的IP地址,可以直接访问整个局域网内部,无需进行地址转换,这是一种高效的虚拟网络技术。这种模式的容器网络就类似于我们的VM网络。

4、Linen(基于Open vSwitch的Overlay网络方案)

Open vSwitch是一个开源的虚拟交换机,类似传统的Linux Bridge,Kubernetes主要是建立L3到L3的隧道,即OVS的Tunnel模式。
Linen CNI插件通过Flax daemon和Linen CNI这两个组件完成OVS网络的配置:

  • Flax daemon:在每台Node上运行,有新节点加入时会自动将其加入当前的Overlay网络中。
  • Linen CNI:由Kubelet调用为容器提供网络设置。

5、直接路由

就目前Docker自身默认的网络来说,单台主机上的不同Docker容器可以借助docker0网桥直接通信,这没毛病,而不同主机上的Docker容器之间只能通过在主机上用映射端口的方法来进行通信,有时这种方式会很不方便,甚至达不到我们的要求,因此位于不同物理机上的Docker容器之间直接使用本身的IP地址进行通信很有必要。再者说,如果将Docker容器起在不同的物理主机上,我们不可避免的会遭遇到Docker容器的跨主机通信问题。因此我们可以在各Node上设置路由规则,可以将没有Node上的容器网桥和Node的匹配关系直接配置在Linux的路由表中,这样不同节点的容器就可以根据路由表直接找到目的容器所在的Node,实现通信。
在集群主机数量较多时,我们需要维护的路由表信息太多,会带来很大的工作量,并且只要由新Node加入,都需要更改所有主机的路由表。为了能够自动完成各Node之间的docker0的路由规则配置,我们通常使用动态路由发现协议来完成。常用的动态路由协议:RIP、BGP、OSPF等

6、几种方案对比

属性 Flannel Calico macvlan Open vSwitch 直接路由
方案特性 通过虚拟设备flannel0实现对docker0的管理 基于BGP协议的纯三层网络方案 基于Linux Kernel的macvlan技术 基于隧道的虚拟路由器技术 基于Linux Kernel的vRouter技术
对底层网络的要求 三层互通 三层互通 二层互通 三层互通 二层互通
配置难易程度 简单;基于etcd 简单;基于etcd 简单;直接使用宿主机网络,需要仔细规划IP地址范围 复杂;需手工配置各节点的Bridge 简单;使用宿主机vRouter功能,需要仔细规划每个Node的IP地址范围
网络性能 host-gw > VxLAN > UDP BGP性能损失小;IPIP模式较小 性能损失可忽略 性能损失较小 性能损失较小
网络联通性限制 在不支持BGP协议的网络环境下无法使用 基于macvlan的容器无法与宿主机网路通信 在无法实现大二层互通的网络环境下无法使用

猜你喜欢

转载自blog.csdn.net/Andriy_dangli/article/details/84563710