关于Kubernetes的网络模型,需要具备一些二三层网络交换的基本知识。比如mac地址,ip地址,arp表,路由表等。那kubernetes内部容器间的网络通信也离不开这些基本的原理,只不过这个时候的个体不再是物理机实体,而是一个个的容器(container),在逻辑层可以说是pod间通信,本质上是不通namespace间的网络通信。
kubernetes在发展的过程中,网络功能一直都是由coreOS参与,其中Flannel就是CoreOS的网络解决方案,在15年的时候,社区才有Calico和Weave冒出来,可以说基本解决了网络问题。所以Kubernetes官方就没有自己亲历亲为去做这个事情,毕竟kubernetes是google的开源项目,如果什么都靠自己去做,也会消耗自己更多的成本。这个时候kubernetes推出了CNI,来做网络插件的标准化。可能这样也更符合开源产品的发展模式。
所以有了以上背景,我们学习k8s的网络模式,有2个CNI组件是绕不过的,一个是Flannel,一个就是Calico。
namespace间网络通信,需要解决几个场景的通信问题:
- 同一个宿主机下的不同namespace通信;
- 跨宿主机的不通namespace通信问题。
首先来看Flannel的通信模式,按照时间线(timeline)来分,经历了如下过程:
1、Flannel UDP; 这种模式提供了一个三层的Overlay网络,对发出端的IP包进行UDP封装(Encapsulation
),通过查找本地的路由表进行转发,然后接收端开始解包(Decapsulation).
该模式的缺点:用户态内核态切换过于频繁,导致性能低下。
2、VXLAN;
该模式下,所有出去的数据包都必须经过flannel.1 这个VTEP设备,数据包的内部封装目的VTEP设备的mac 地址 和 目的容器的IP地址,依赖flannel.1 虚拟设备(每个node节点都有),经历container--->docker0--->flannel.1--->eth0
以上2种模式下,容器都是连接在docker0网桥上,而网络插件(CNI)都是在宿主机上创建一个特殊的设备(UDP模式下创建的是TUN设备,VXLAN模式创建的是VTEP设备),docker0和这个设备之间,通过IP转发进行写作。
3、host-gw; --->Pure Layer3
host-gw模式是一个纯三层的网络解决方案,它的工作原理,就是讲每个Flannel子网(Flannel Subnet)的下一条设置成该子网对应的宿主机的IP地址,宿主机充当一个“网关”的角色。
这个时候就有路由的概念了,属于三层的内容,不过Flannel子网和主机的信息都保存在etcd中,flanneld只需要watch 数据的变化,就可以完成实时更新路由表。下图是host-gw模式下的数据流向,
以上内容对kubernetes Flannel网络模型做了个简要的介绍,就当是对kubernetes的网络有了个基本的认识。