一、基本概念
网络命名空间(Network Namespace)
作用是隔离网络资源,每个网络命名空间包含独立的网络栈,它包括:网卡、回环设备、路由表、iptables规则。
虚拟网卡设备(Veth)
Veth能够连接容器和宿主机的网络资源。Veth设备是一对虚拟网卡,其中一个用于容器,另一个用于宿主机。
容器网络接口 Container Network Interface(CNI)
CNI是Kubernetes和其他容器编排系统用来配置容器网络的标准化接口。
当Pod在Kubernetes集群中创建时,CNI发挥着至关重要的作用,主要体现在以下几个方面:
1、网络插件选择与加载:CNI允许用户选择不同的网络插件(如Flannel、Calico、Weave Net、Cilium等)来满足特定的网络需求。在Pod创建前,Kubernetes会读取配置好的CNI插件配置文件,这些配置文件指定了应该使用哪个网络插件及其相关参数。
2、网络环境配置:当kubelet接收到创建Pod的指令后,它会通过CRI(Container Runtime Interface)与容器运行时交互。在创建Pod的实际容器之前,kubelet会调用CNI插件来为Pod配置网络环境。这包括为Pod分配IP地址、设置网络路由规则、创建虚拟网络设备(例如veth pair或macvlan)等,确保Pod在网络层面与其他Pod及外部世界隔离且可通信。
3、网络连接与隔离:CNI插件负责在节点的网络命名空间中为Pod创建网络接口,并将其与Pod内的容器网络栈相连。这样每个Pod都有独立的网络栈,实现了网络隔离,同时确保Pod间及Pod与外部网络的连通性。
4、资源分配与释放:在Pod创建时,CNI插件分配必要的网络资源(如IP地址、端口等);而在Pod被删除时,CNI插件负责清理这些网络资源,确保资源的有效管理和重用。
二、k8s集群的不同网络通信方式
1、pod内部容器之间的通信
pod内部的容器相当于在一台宿主机上,可以直接使用localhost通信。
具体地,当Pod创建时,被调度的node上的kubelet会解析PodSpec。然后kubelet会调用CRI接口创建容器,为容器创建一个网络命名空间,并调用CNI插件为容器分配网络资源。
k8s会先创建一个pause容器(也有教程讲infra容器),由它拥有这个网络资源,然后创建其他容器。
2、同一node下pod之间的通信
由于网络命名空间的隔离,不同pod之间需要通过veth设备通信。创建Pod时,CNI插件利用veth设备将相互隔离的Pod容器连接在宿主机的网桥上。
这相当于一个二层连通的网络,同一node下的不同pod通过子网网段通信,宿主机上的网桥完成子网IP的映射。
3、不同node下pod之间的通信
针对不同的底层网络的连通性,二层或三层(多数是讨论仅三层)连通条件下,有多种节点网络的配置方式。
一种典型的网络模式是overlay网络。pod之间通过某种机制(依靠CNI插件)实现一个跨子网的隧道。
四种常见网络方案:
1、Flannel VXLAN
VXLAN在每个node上安装了特殊的隧道端设备VTEP,它完成以下的工作:
根据目标容器IP,查询对应的VTEP设备mac地址,打上一层封包;
为了通过宿主机实现二层网络转发,还需要打上一个特殊的VXLAN header,打上一层封包;
根据目标VTEP设备mac地址,从FDB转发数据库中查找目标主机的IP地址,打上一层封包;
连通性要求:Flannel VXLAN不要求宿主机网络二层连通。
2、Flannel host-gw
host-gw模式下,flanneld监听Flannel子网和主机信息,然后实时更新主机上的路由表。
连通性要求:要求宿主机网络二层连通,即宿主机在同一子网。
3、Calico BGP
Node-to-Node Mesh模式:集群需要维护每个节点的下一跳路由信息,设节点数是N,则路由连接数的规模是 $ N^2 $ 。
Route Reflector模式:这种模式下Calico仅指定若干节点负责跟所有节点建立BGP连接,学习全部路由规则,控制集群路由连接数的规模是 $ N $ 。
连通性要求:同样要求宿主机网络二层连通。
4、Calico IPIP
可以实现跨子网的容器间访问。但是多了一层IP封包,性能会降低。
宿主机内的路由转发变成了IP隧道设备————tunl0,本机发出的数据包会被转发到tunl0,由tunl0修改IP头,再转发到下一跳。
连通性要求:不要求宿主机网络二层连通。
领取专属 10元无门槛券
私享最新 技术干货