网络架构是 K8S 的一个复杂组件。Kubernetes 网络模型对特定网络功能提出了要求。业界已开发出许多针对特定环境和要求的网络解决方案。
容器网络接口(CNI)可让你在创建或销毁容器时轻松配置容器网络。本文将介绍经典网络插件的工作原理以及如何使用 CNI 插件。
1. 什么是CNI?
CNI 是 Kubernetes 中的标准网络实现接口。Kubelet 通过 CNI 调用不同的网络插件,以实现不同的网络配置方法。常见的CNI插件有Calico、Flannel、Terway、Weave Net 和 Contiv 等。
2. K8S中的CNI调用链
在群集中创建 Pod 时,API-Server会将 Pod 配置写入群集。API-Server的某些控制组件(如scheduler)被调度到特定节点。Kubelet 监听该 Pod 的创建后,会在当前节点执行一些创建操作。
创建网络时,Kubelet 会读取配置目录(/etc/cni/net.d/
)中的配置文件。配置文件声明了要使用的插件。Kubelet 执行 CNI 插件的二进制文件。
CNI 插件会进入 Pod 的网络空间,配置 Pod 网络。Pod 网络配置完成后,Kubelet 将创建 Pod 并将其上线。
上述过程中的配置文件、cni插件的可执行文件,都在cni插件安装时进行了配置和安装。
3. CNI插件选型
3.1 后端模式
CNI 插件分为三种后端模式:Overlay(覆盖)、Routing(路由)、Underlay(底层)。
Overlay模式: 容器的
CIDR
地址与主机的 IP 地址范围无关。在跨主机通信期间,主机之间会建立隧道,容器CIDR中的所有数据包都会封装为底层物理网络中主机之间交换的数据包。这种模式消除了对底层网络的依赖。Routing模式: 主机和容器属于不同的 CIDR 块。跨主机通信通过路由实现。不同主机之间不建立用于数据包封装的隧道。不过,路由互连部分取决于底层网络。例如,从底层网络到第 2 层必须有可到达的路由。
Underlay模式: 容器和主机位于同一网络层,共享同一位置。容器之间的网络互联取决于底层网络。因此,这种模式高度依赖底层能力。
3.2 环境限制
不同的环境分别会有不同的限制以及能力。
虚拟机环境:像OpenStack,施加了许多网络限制。1. 机器之间不能通过第2层协议直接访问,只能转发具有第3层特征(如 IP 地址)的数据包,主机只能使用指定的 IP 地址。因此只能选择Overlay模式下的插件,如 Flannel-VXLAN、Calico-IPIP、Weave等。
物理机环境:对底层网络的限制很少。因此,可以选择Underlay模式或Routing模式的插件。在Underlay模式模式下,可以将多个网络接口控制器(NIC)直接插入物理机,或在 NIC 上虚拟硬件。在Routing模式下,路由是通过 Linux 路由协议建立的。这避免了 VXLAN 封装造成的性能下降。在这种环境下,可以选择 Calico-BGP、Flannel-HostGW 和 Sriov 等插件。
公有云环境:是一种虚拟环境,对底层功能有许多限制。不过,每个公共云都会调整容器以提高性能,并可能提供 API 以配置额外的网卡或路由功能。公有云环境建议选择公有云供应商提供的 CNI 插件,以获得兼容性和最佳性能。
3.3 功能要求
安全要求
通过配置网络策略(NetworkPolicy)以支持是否允许节点间访问等策略。并非每个CNI插件都支持网络策略。如果需要 NetworkPolicy 支持,可以选择 Calico 或 Weave。集群内外资源互连
部署在虚拟机(VM)或物理机上的应用程序无法一次性迁移到容器化环境。因此,有必要在虚拟机或物理机和容器之间配置 IP 地址互连,将它们互连或部署在同一层。
这种情况下,可以选择 Underlay 模式下的插件。例如,Sriov 插件允许 Pod 和传统虚拟机或物理机在同一层运行。还可以使用 Calico-BGP 插件。虽然容器与传统虚拟机或物理机处于不同的 CIDR 块中,但可以使用 Calico-BGP 向原始路由器宣传 BGP 路由,从而实现虚拟机和容器之间的互联。K8S服务发现和负载均衡
服务发现和负载平衡是k8s的一种Service资源。并非所有 CNI 插件都能提供这两项功能。对于处于 Underlay 模式的许多插件来说,Pod 的网卡是 Underlay 硬件,或者是通过硬件虚拟化并插入容器的。因此,NIC 流量无法路由到主机所在的命名空间。因此,无法应用 kube-proxy 在主机上配置的规则。
在这种情况下,插件无法访问 Kubernetes 的服务发现功能。如果需要服务发现和负载平衡,请选择支持这两种功能的 Underlay 模式插件。
3.4 性能要求
设计两个方面:POD创建速度,POD网络性能
- Pod创建速度
在Pod创建时,CNI插件创建和配置相应的网络资源。Overlay与Routing模式可以快速创建Pod,插件可在机器上实现虚拟化,因此您只需调用内核接口即可创建Pod。
如果选择 Underlay 模式的插件,则需要创建底层网络资源,这会减慢Pod创建过程。因此,需要快速扩展Pod、创建许多Pod时建议选择 Overlay 或 Routing 模式的插件。
- Pod网络性能
Pod 的网络性能是通过 Pod 间网络转发、网络带宽和每秒脉冲 (PPS) 延迟等指标来衡量的。
Overlay模式下的插件性能将低于Underlay和Routing模式下的插件,因为前者在节点上实现了虚拟化并对数据包进行了封装。这种封装会导致数据包头丢失和 CPU 消耗。
因此,如果您在机器学习和大数据等场景中需要较高的网络性能,请不要选择 Overlay 模式的插件。建议选择 Underlay 或 Routing 模式的 CNI 插件。
4. 如何开发一个CNI插件
社区提供的插件可能无法满足特定要求。例如,阿里云只能使用覆盖模式下的 VXLAN 插件。该插件性能相对较差,无法满足阿里云的某些业务需求。为此,阿里云开发了 Terway 插件。
如果社区中的插件都不适合当前环境,可以开发一个 CNI 插件。
CNI 插件的实现方法如下:
- 二进制 CNI 插件用于配置 Pod 的网卡和IP地址。这相当于将一根网线连接到 Pod,而Pod有一个IP地址和网卡。
- 一个守护进程用于管理 Pod 之间的网络连接。这一步将 Pod 连接到网络,使它们能够相互通信。
4.1 为Pod配置网卡和IP
为Pod准备虚拟网卡
- 创建
veth虚拟网卡
- 一端连接到
Pod的网络空间
,另一端连接到主机的网络空间
(Pod和主机的网络命名空间就连接起来了)
- 创建
为Pod分配IP地址(为Pod分配一个集群唯中一的IP地址)
- 根据节点为Pod分配CIDR区块(创建集群时,如下图创建了
172.16.0.0/16
段,每个节点分别分配了24位掩码的172.16.0.0/24
段和172.16.1.0/24
段,从而避免了节点间的IP地址冲突) - 从节点的CIDR区块中为Pod分配IP地址(当前节点的IP地址分配既可以DHCP,也可以按序分配)
- 根据节点为Pod分配CIDR区块(创建集群时,如下图创建了
配置Pod的IP地址和路由
- 为Pod网卡配置IP地址
- 为Pod网卡配置路由(入pod流量:在host上配置流向此POD-IP的路由指向此pod在主机上的
veth1
; 出pod的流量: 在Pod内的eth0网卡配置路由,pod访问集群外部)以便将指向此 pod 的流量路由到其 NIC。此外,在此 NIC 上配置默认路由的 CIDR 块,以便将通向 Internet 的流量路由到此 NIC。
4.1.1 为Pod准备NIC
可以将veth虚拟网卡
的一端连接到Pod的网络空间
,另一端连接到主机的网络空间
。这样,pod 和主机的命名空间就连接起来了。
4.1.2 为Pod分配IP地址
4.2
5. 总结
- 在环境中部署K8S集群时,如何选择合适的 CNI 插件。
- 当社区中可用的CNI插件无法满足需求时,如何开发 CNI 插件。
术语
底层网络(underlay network):底层网络可使用传统的基于硬件的网络连接方式,或组合使用硬件和软件,将虚拟机或物理机连接起来。
叠加网络(overlay network):大多数编排系统都会包含一个软件定义的网络连接组件,称为叠加网络。它叠加于底层之上,在容器和主机的生命周期中提供网络连接能力,例如IP地址和端口。叠加还可以在使用同一物理网络的应用之间隔离通信。叠加技术包括Flannel\calico等。