前言
CNI 网络在 Kubernetes 中起着关键作用,它负责管理容器的网络连接、通信和安全,为 K8s 集群中的容器提供了稳定、可靠的网络基础设施。在部署 K8s 集群时,选择合适的CNI(容器网络接口)插件至关重要。不同的 CNI 插件提供了各自独特的功能和性能特点,因此我们需要了解它们的作用以及如何选择、配置和使用这些插件。
部署 CNI 网络组件请参考:搭建Kubernetes v1.20二进制集群——单Master和Node组件-CSDN博客
目录
一、K8s 集群的三种接口
二、K8s 的三种网络
三、K8s 中 Pod 网络通信
1. Pod 内容器之间的通信
2. 同一个 Node 内 Pod 之间的通信
3. 不同 Node 上 Pod 之间的通信
四、网络虚拟化技术 Overlay Network
1. 概述
2. vxlan 技术
2.1 vxlan 简介
2.2 vxlan 与 vlan 区别
3. Flannel 方案
3.1 UDP 模式
3.2 VXLAN 模式
3.3 Host-getway 网关
3.4 其他插件
4. Calico 方案
4.1 k8s 组网方案对比
4.2 组成
4.3 Calico 工作原理
一、K8s 集群的三种接口
① CRI
- 容器进行时接口,连接容器引擎--docker、containerd、cri-o、podman
② CNI
- 容器网络接口,用于连接网络插件如:flannel、calico、cilium
③ CSI
- 容器存储接口,如nfs、ceph、gfs、oss、s3、minio
二、K8s 的三种网络
① Service 网络
- 是指 Kubernetes 中用于服务发现和负载均衡的虚拟网络。属于 ClusterIP(集群内部 IP),作用于四层内部网络,ClusterIP 只能 K8s 集群内部可用,对外部不可见;
② Pod 网络
- 是指 K8s 集群中各个 Pod 之间通信所使用的网络。Pod 网络通常由 CNI 插件管理,它们负责为 Pod 分配 ip 地址、创建网络命名空间以及处理 Pod 之间的网络通信。PodIP 给 Docker 容器提供 ip 地址,也是虚拟网络;
③ 节点网络
- 物理服务器的网卡 ip,是指 K8s 集群中各个节点(Node)之间通信所使用的网络。通常由底层网络设施或者 CNI 插件来管理。
三、K8s 中 Pod 网络通信
1. Pod 内容器之间的通信
在同一个 Pod 内的容器(Pod 内的容器是不会跨宿主机的)共享同一个网络命名空间,相当于它们在同一台机器上一样,可以用 localhost 地址访问彼此的端口。
2. 同一个 Node 内 Pod 之间的通信
每个 Pod 都有一个真实的全局 IP 地址,同一个 Node 内的不同 Pod 之间可以直接采用对方 Pod 的 IP 地址进行通信,Pod1 与 Pod2 都是通过 Veth 连接到同一个 docker0/cni0 网桥,网段相同,所以它们之间可以直接通信。说白了,他们之间的通信是通过网关来通信的。
3. 不同 Node 上 Pod 之间的通信
Pod 地址与 docker0 在同一网段,docker0 网段与宿主机网卡是两个不同的网段,且不同 Node 之间的通信只能通过宿主机的物理网卡进行。要想实现不同 Node 上 Pod 之间的通信,就必须想办法通过主机的物理网卡 IP 地址进行寻址和通信。
因此要满足两个条件:Pod 的 IP 不能冲突;将 Pod 的 IP 和所在的 Node 的 IP 关联起来,通过这个关联让不同 Node 上 Pod 之间直接通过内网 IP 地址通信。
四、网络虚拟化技术 Overlay Network
1. 概述
Overlay Network 是一种网络虚拟化技术,用于在物理网络之上创建逻辑网络。它通过在现有网络二层或者三层基础设施上叠加一个虚拟网络(虚拟链路隧道)来实现不同主机之间的通信。
目前 Overlay 主要采用 VXLAN,VXLAN 是一种覆盖网络技术,是 Flannel 的一种数据转发方式。
下面介绍两款虚拟化技术插件(方案):Flannel、Calico
2. vxlan 技术
2.1 vxlan 简介
VXLAN 是一种常见的 Overlay Network 技术。将源数据包封装到 UDP 中,并使用基础网络的 IP/MAC 作为外层报文头进行封装,然后在以太网上传输,到达目的地后由隧道端点解封装并将数据发送给目标地址。允许跨越物理网络边界的主机之间进行通信。
可以理解为:就是把源数据包通过 UDP协议封装,形成一个 IP/UDP 数据包。在封装过程中,会将本机的信息封装进去,使用网络 IP 地址和 MAC 地址来标识虚拟网络中的不同节点。最后根据路由表通过隧道发送给对端。
2.2 vxlan 与 vlan 区别
VLAN(虚拟局域网)是一种将单个物理局域网划分为多个逻辑上独立的虚拟局域网的技术。通过 VLAN 技术,可以实现不同设备之间的隔离和区分,即使它们连接到同一个交换机或网络中。
区别:
① 标识符范围不同
- vlan 使用12位 bit 表示 vlan ID,因此最多支持 212=4094个 vlan
- vxlan 使用的 ID 使用24位 bit,最多可以支持 2^24 个虚拟网络
② 已有的网络路径利用效率
- vlan 使用 spanning tree protocol 避免环路,会将一半的网络路径阻塞
- vxlan 的数据包封装成 UDP 通过网络层传输,可以使用所有的网络路径
③ 防止物理交换机 Mac 表耗尽
- vlan 需要在交换机的Mac表中记录Mac物理地址
- vxlan 采用隧道机制,Mac物理地址不需记录在交换机
④ 使用环境不同
- vlan 适用于在单一数据中心或局域网内实现网络隔离
- 而 vxlan 更适合用于构建大规模、跨数据中心的虚拟网络
3. Flannel 方案
Flannel 是 Overlay 网络的一种,通常与 Kubernetes 集群一起使用。它的主要作用是管理和配置容器之间的网络通信,实现跨节点的通信和网络隔离。
让集群中的不同节点主机创建的 Docker 容器都具有全集群唯一的虚拟 IP 地址。将 TCP 源数据包封装在另一种网络包里面进行路由转发和通信,目前支持 UDP、VXLAN、Host-gw 3种模式进行数据转发的方式。
3.1 UDP 模式
UDP 模式是在用户态做转发,封装 UDP 协议,是 IP 封装和解封装的过程,原理是通过 Flannel 服务进行封装,会多一次报文隧道封装。因此性能上会比在内核态做转发的 VXLAN 模式差。目前市场使用率较低。
封装和解封装的过程:
① 原始数据包(源ip:10.1.15.2,目的ip:10.1.20.3)发给 docker0/cni0 网桥,再转发给 flannel0 接口;
② flanneld 服务将原始数据封装在 udp 报文中;
③ flanneld 服务查询 etcd 路由表找到目标 pod 对应的 nodeip,在 udp 报文外封装 ip头部+mac头部,通过物理网卡转发给对应 node节点;
④ udp 报文通过 8285 端口发送到目标节点上的 flanneld 服务,解封装后,根据本地路由规则通过flannel0 接口发送到 cni0 网桥,最终转发到目标节点。
3.2 VXLAN 模式
可以理解为隧道模式,是 Flannel 的默认配置,利用内核来去封装主机 host 之间传输数据包通信的。比较好用,使用率高。
flannel 会在各节点生成一个 flannel.1 的 vxlan 网卡。
① 原始数据帧从源主机的 pod 容器发出到 cni0 网桥,再由 cni0 转发给 flannel.1 虚拟接口;
② flannel.1 接口接收数据帧以后先添加 vxlan 头部,然后在内核将原始数据帧封装在 udp 报文中;
③ flanneld 会查询 etcd 中的路由表信息获取目标 pod 的 nodeip,然后在 udp 报文外封装 nodeip 头部和 mac 头部,通过物理网卡发送给目标 node 节点;
④ 报文会通过 4789 端口到目标 node 节点的 flannel.1 接口,并在内核中解封装,最后根据本地的路由规则转发到 cni0 网桥,再发送到目标 pod 容器。
Flannel VXLAN 模式跨主机的工作原理:
- 数据帧从主机 A 上 Pod 的源容器中发出后,经由所在主机的 docker0/cni0 网络接口转发到 flannel.1 接口
- flannel.1 收到数据帧后添加 VXLAN 头部,封装在 UDP 报文中
- 主机 A 通过物理网卡发送封包到主机 B 的物理网卡中
- 主机 B 的物理网卡再通过 VXLAN 默认端口 4789 转发到 flannel.1 接口进行解封装
- 解封装以后,内核将数据帧发送到 cni0,最后由 cni0 发送到桥接到此接口的容器 B 中。
3.3 Host-getway 网关
通过二层网络配置,不支持云环境。通过主机的路由表中直接创建路由信息(subnet 路由条目)到达目标,性能好,但是配置麻烦。
3.4 其他插件
- Antree
- Kube-OVN
- Weave-Net
4. Calico 方案
4.1 k8s 组网方案对比
flannel 方案
- 需要在每个节点上把发向容器的数据包进行封装后,再用隧道将封装后的数据包发送到运行着目标 Pod 的 node 节点上。目标 node 节点再负责去掉封装,将去除封装的数据包发送到目标 Pod 上。数据通信性能则大受影响。
calico 方案
- Calico 不使用隧道或 NAT 来实现转发,而是把 Host 当作 Internet 中的路由器,使用 BGP 同步路由,并使用 iptables 来做安全访问策略,完成跨 Host 转发。采用直接路由的方式,这种方式性能损耗最低,不需要修改报文数据,但是如果网络比较复杂场景下,路由表会很复杂,对运维同事提出了较高的要求。
4.2 组成
Calico CNI 插件:主要负责与 kubernetes 对接,供 kubelet 调用使用。
Felix:
- 负责维护宿主机上的路由规则、FIB转发信息库等。
BIRD:
- 负责分发路由规则,类似路由器。
Confd:
- 配置管理组件。
4.3 Calico 工作原理
Calico 利用路由表维护每个 pod 之间的通信。其 CNI 插件为每个容器设置了 veth pair 设备,将其一端连接到容器内部,另一端接入到宿主机网络空间。由于没有网桥,CNI 插件需要在宿主机上配置路由规则,以便接收传入的 IP 包。
通过 veth pair 设备,容器发出的 IP 包首先到达宿主机,然后根据路由规则发送给正确的网关,最终到达目标容器。这些路由规则由 Felix 维护配置,而路由信息则通过 Calico BIRD 组件基于 BGP 进行分发。
Calico 将集群中的所有节点视为边界路由器,它们共同形成一个全互联的网络,通过 BGP 交换路由信息,这些节点被称为 BGP Peer。
在当前常用的 CNI 网络组件中,flannel 功能简单,缺乏复杂的网络策略配置能力;而 Calico 是出色的网络管理插件,具备复杂网络配置能力。对于小规模简单集群,可以选择 flannel;而对于未来可能需要扩容并引入更多设备、配置更多网络策略的情况,使用 Calico 更为合适。