摘要:Kubernetes 网络是集群的"任督二脉"。本文从 Pod 网络模型(Underlay/Overlay)讲起,深入 Pause 容器如何为 Pod 提供网络命名空间,再到 CNI 标准如何让 K8s 网络"可插拔",最后详解企业级首选 Calico 的 BGP、IPIP、VXLAN 三种模式及选型建议。一篇吃透 K8s 网络核心知识
1.Pod 网络模型
核心是IP-per-Pod ,即每个 Pod 分配一个独立的 IP 地址,Pod 内所有容器共享这个 IP,所有 Pod 之间可以直接用 IP 通信,不用 NAT,不用端口映射。
1.1 Underlay 网络
定义 :基于物理基础设施的底层网络,数据包不经过封装,直接通过物理设备(交换机、路由器)转发。
特点:
- 性能最高(无封装开销)
- 依赖底层网络设备支持(如 BGP 协议)
- 部署复杂,涉及物理网络配置
典型代表:Calico BGP 模式
Pod1 (10.244.42.68) → 物理网卡 → 路由器 → 物理网卡 → Pod2 (10.244.103.67)
↑ ↑
通过 BGP 协议同步路由表,直接转发

当 10.42.0.2 想去访问 10.42.1.2 时,只需要先把数据报文发给
docker,docker 再去查询路由表,就可以通过一步一步路由的方案,经过物理网络到达至我们的目标容器或者目标
Pod,在整个过程中,数据报文并没有被封装。
1.2 Overlay 网络
定义 :在物理网络之上构建的虚拟逻辑网络,通过隧道技术(VXLAN、IPIP 等)封装数据包。
特点:
- 灵活性高,不依赖底层网络
- 有一定性能损耗(封装/解封装)
- 部署简单,对物理网络无要求
典型代表:Flannel(VXLAN)、Calico(IPIP/VXLAN 模式)
Pod1 → 封装新头部 → 物理网络传输 → 解封装 → Pod2
↑ ↑
隧道技术(VXLAN/IPIP)实现跨主机通信

然假设是由 10.42.0.2 到达 10.42.1.2,在这里大家看到出现了一个 flanneld ,它是典型的封装网络,所以当第一个
Pod 发送数据包的时候,其实 flanneld 会在外面加一层数据报文,然后根据网络模式是 vxlan 还是 IPIP 进行不一样
的封装。
1.3 两种模型对比
| 对比项 | Underlay 网络 | Overlay 网络 |
|---|---|---|
| 数据传输 | 物理设备(路由器/交换机) | 虚拟链路(隧道) |
| 封装开销 | 无 | 有(额外头部) |
| 性能 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
| 部署复杂度 | 高(需配置物理网络) | 低(纯软件配置) |
| 扩展性 | 差(新增设备困难) | 强(VXLAN 支持 1600 万标识符) |
| 协议 | BGP、OSPF、VLAN | VXLAN、IPIP、GRE |
2.Pod 网络如何实现?
Pause 容器是关键!!!
1. Pause(Infra)容器的作用
- 每个 Pod 启动时,最先创建 Pause 容器。
- Pause 容器负责初始化 Pod 的 Network Namespace。
- 其他业务容器通过
--net=container:pause共享同一个网络命名空间。(不需要自己手动写)
2. 为什么要共享网络?
- 同一 Pod 内的容器(如 nginx + php-fpm)可以通过 localhost 互相访问。同一个Pod里用localhost通信 = 把分布式调用变成本地调用,省掉网络开销、配置、安全加固三部曲。适合强绑定的容器
- 避免端口冲突,统一网络策略管理。
- 简化服务发现和通信配置。
3. Pause 容器的特点
| 特性 | 说明 |
|---|---|
| 镜像极小 | 约 700KB |
| 状态 | 永远处于"暂停"状态 |
| 启动顺序 | Pod 内第一个启动 |
| 额外职责 | 回收僵尸进程(作为 1 号进程) |
3.CNI(容器网络接口)
1. 什么是 CNI?
- CNI 是 Google 和 CoreOS 联合制定的容器网络标准化接口。
- Kubernetes 不实现网络,而是通过 CNI 插件化集成各种网络方案。
2. CNI 的工作方式
- 容器运行时(如 containerd、CRI-O)通过 执行 CNI 可执行程序 来配置网络。
- 配置通过 JSON 文件 传递,结果通过标准输出返回。
3. CNI 插件分类(重点)
| 类别 | 功能 | 示例 |
|---|---|---|
| Main 插件 | 创建具体网络设备 | bridge、macvlan、ipvlan、loopback |
| IPAM 插件 | 分配 IP 地址 | host-local、dhcp、static |
| META 插件 | 附加功能 | portmap、firewall、bandwidth |
| Windows 插件 | Windows 支持 | win-bridge、win-overlay |
| 第三方插件 | 主流开源方案(具体实现) | Flannel、Calico、Cilium、Weave |
4.常见第三方网络插件对比
| 插件 | 特点 | 适用场景 |
|---|---|---|
| Flannel | 最成熟、最简单,基于 Overlay | 小型集群,入门首选 |
| Calico | 性能好、灵活,支持 BGP/Overlay | 企业级生产环境 |
| Cilium | 基于 eBPF,安全性强 | 对安全和可观测性要求高的场景 |
| Weave | 支持加密,跨云部署 | 多云/混合云环境 |
5.Calico 三种网络模式
5.1 BGP 模式(纯路由,无封装)
- 不封装数据包,直接通过路由表转发。
- 节点间通过 BGP 协议 同步路由信息。
- 性能最高,但要求底层网络支持 BGP。
直接由虚拟 eth0 到达物理网卡,所以它是非封装的网络。
5.2 IPIP 模式(隧道封装)
- 在原始 IP 包外再加一层 IP 头(外层为节点 IP)。
- 使用
tunl0隧道接口。 - 适合跨子网通信,性能略低于 BGP。

它们访问的数据包会首先发送给自己的 tunl0,也就是 IPIP 隧道,这个网卡会通过 IP 封装包的方式,将数据报文传递到另一个 tunl 里。另一个 tunl 在获取到包以后解封三层头部放到 pod2 中,这样就实现了数据的传递。
5.3 VXLAN 模式(基于 UDP 的 Overlay)
- 将二层帧封装在 UDP 包 中传输。
- 使用
vxlan.calico设备。 - 灵活性最强,对底层网络要求最低。

首先两台机器上都有一个叫
vxlan.calico的设备。当 Node1 的 Pod 要访问 Node2 的 Pod 时,数据包先交给本机的vxlan.calico,这个设备在原始报文外面层层封装------VXLAN头、UDP头、IP头、MAC头,外层IP指向对端物理机,然后丢到物理网络里。包到达 Node2 后,vxlan.calico拆掉封装还原原始报文,再根据本地路由表,通过 Pod 对应的虚拟网卡把包送进 Pod 内部。这样就完成了跨节点通信。
所以实际情况根据性能要求自行选择。但是企业一般选择BGP模式,性能损耗少!!!
不知道大家还有没有印象,之前的文章搭建k8s集群(K8s集群搭建)就用到的是Calico的BGP模式。但是几乎0配置。只是改了 Calico 的部署文件:
bash
# Enable IPIP
- name: CALICO_IPV4POOL_IPIP
value: "Off"
# Enable or Disable VXLAN on the default IP pool.
- name: CALICO_IPV4POOL_VXLAN
value: "Never"
# Enable or Disable VXLAN on the default IPv6 IP pool.
- name: CALICO_IPV6POOL_VXLAN
value: "Never"
。。。。。。
- name: CALICO_IPV4POOL_CIDR
value: "10.244.0.0/16"
是因为: Calico 默认就启用了 BGP 协议,在节点位于同一二层网络的小规模集群中,BGP 邻居会自动建立,无需额外配置。你只需要关闭 IPIP 和 VXLAN 隧道,即可切换到高性能的 BGP 路由模式。
但是要是跨网段/大规模集群比较麻烦
1.跨网段
textNode1: 192.168.10.12/24 ←→ Node2: 10.0.1.13/24 不同网段,无法自动发现配置:
ymlapiVersion: projectcalico.org/v3 kind: BGPPeer metadata: name: peer-to-node2 spec: peerIP: 10.0.1.13 node: node1
2.大规模集群
全互联模式会导致连接数爆炸(100 节点需要 4950 条连接),需要配置 BGP Route Reflecto.
不配置 RR:每个节点连接所有其他节点 = N-1 条连接
配置 RR:每个节点只连接 RR 节点 = 1 条连接
1.安装calicoctl工具在Master节点
2.配置 calicoctl 连接 K8s API
bash
export CALICO_DATASTORE_TYPE=kubernetes
export CALICO_KUBECONFIG=~/.kube/config
3.关闭全互联模式
bash
apiVersion: projectcalico.org/v3
kind: BGPConfiguration
metadata:
name: default
spec:
# 关闭全互联模式
nodeToNodeMeshDisabled: true
4.配置 Route Reflector 节点
bash
cat <<EOF | calicoctl apply -f -
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: rr-cluster
spec:
# 配置为 Route Reflector 集群
peerIP: 192.168.10.10 # RR 节点的 IP
nodeSelector: all() # 所有节点都连接这个 RR
peerSelector: route-reflector == "true"
EOF
5.给 RR 节点打标签
bash
kubectl label node master route-reflector=true
6.每个非 RR 节点需要配置连接到 RR 节点。
bash
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: peer-with-rr
spec:
# RR 节点的 IP 地址
peerIP: 192.168.10.10
# 哪些节点连接到这个 RR
nodeSelector: has(kubernetes.io/hostname)
