2. Kubernetes 网络基础回顾:Pod网络模型、CNI插件原理、Service与Endpoint
在深入分析 NetworkPolicy 命中率与误报之前,必须牢固掌握 Kubernetes 网络的核心抽象。本章将系统回顾 Pod 网络模型、CNI 插件的工作原理,以及 Service 与 Endpoint 如何协同工作。这些基础概念是后续策略审计与优化的前提。
2.1 Pod 网络模型:IP-per-Pod 与扁平网络
Kubernetes 网络模型的核心原则是 IP-per-Pod:集群中的每个 Pod 都拥有一个独立的、集群内可路由的 IP 地址。Pod 内的所有容器共享该 IP 和网络命名空间,通过 localhost 互相通信。Pod 之间无需 NAT 转换即可直接通信,这被称为 扁平网络。
关键原则: Pod 被视为“逻辑主机”。网络策略作用于 Pod 的 IP 地址,而非容器端口。理解这一点是正确编写 NetworkPolicy 的基础。
该模型解决了端口冲突和地址规划问题,但要求底层网络基础设施必须满足以下条件:
- Pod-to-Pod 通信: 任意两个 Pod 可以直接通过 IP 通信,无论它们位于同一节点还是不同节点。
- Agent-to-Pod 通信: 集群中的 Agent(如 kube-proxy、监控组件)也能直接访问 Pod IP。
- Pod 内部通信: 同一 Pod 内的容器通过 localhost 通信,无需经过网络栈。
2.2 CNI 插件原理:从容器网络到集群网络
容器网络接口(CNI)是 Kubernetes 与网络实现之间的标准协议。CNI 插件负责在 Pod 创建时为其分配 IP 地址,并将 Pod 连接到集群网络。常见的 CNI 插件包括 Calico、Flannel、Cilium 等。
CNI 插件的工作流程通常包含以下步骤:
- 调用触发: kubelet 在创建 Pod 沙箱后,调用 CNI 插件二进制文件。
- 网络命名空间配置: 插件将 Pod 的网络命名空间(netns)挂载到宿主机。
- IP 地址管理(IPAM): 插件从 IP 池中分配一个唯一的 IP 地址给 Pod。
- 接口创建与路由: 插件在宿主机上创建 veth pair,一端连接 Pod,另一端连接网桥或路由设备,并配置路由规则。
- 策略执行(可选): 部分插件(如 Calico、Cilium)会在此阶段应用 NetworkPolicy 规则。
| CNI 插件 | 网络模式 | NetworkPolicy 支持 | 典型场景 |
|---|---|---|---|
| Flannel | Overlay(VXLAN/Host-GW) | 需配合其他组件(如 Calico policy-only) | 小型集群、快速部署 |
| Calico | 纯路由(BGP)或 Overlay(IPIP) | 原生支持,基于 iptables/eBPF | 大规模集群、安全要求高 |
| Cilium | eBPF 直接路由 | 原生支持,基于 eBPF | 高性能、高级网络策略 |
| Weave Net | Overlay(fastdp) | 原生支持 | 多云、混合环境 |
策略审计提示: 不同的 CNI 插件对 NetworkPolicy 的实现方式不同。例如,Calico 使用 iptables 规则,而 Cilium 使用 eBPF 程序。这会影响策略的命中率统计和误报排查方法。在后续章节中,我们将以 Calico 和 Cilium 为主要分析对象。
2.3 Service 与 Endpoint:服务发现与负载均衡
Service 是 Kubernetes 中用于暴露一组 Pod 的抽象。它通过标签选择器动态关联 Pod,并提供一个稳定的虚拟 IP(ClusterIP)和 DNS 名称。Endpoint 对象则记录了 Service 背后所有 Pod 的 IP 和端口列表。
Service 与 Endpoint 的协作流程如下:
- 创建 Service: 用户定义 Service,指定选择器(selector)和端口映射。
- 自动生成 Endpoint: Kubernetes 控制面根据选择器匹配 Pod,自动创建或更新 Endpoint 对象。
- kube-proxy 监听: 每个节点上的 kube-proxy 监听 Endpoint 变化,并更新节点上的 iptables/IPVS 规则。
- 流量转发: 访问 Service IP 的流量被 kube-proxy 转发到后端 Pod。
2.4 网络策略与基础模型的关联
理解上述基础模型后,可以更清晰地分析 NetworkPolicy 的命中率与误报:
- Pod 网络模型: 策略规则中的
podSelector和namespaceSelector直接作用于 Pod 的 IP 和标签。如果 Pod 的标签设计不合理,会导致策略无法正确匹配目标 Pod,造成漏报或误报。 - CNI 插件: 不同插件对策略的实现方式不同。例如,Calico 的 iptables 规则数量与 Pod 数量成正比,可能影响性能;Cilium 的 eBPF 程序则更高效。策略审计时需考虑插件特性。
- Service 与 Endpoint: 策略通常应作用于后端 Pod,而非 Service IP。常见的误报场景是:策略只放行了 Service IP,但 kube-proxy 的健康检查或监控组件直接访问 Pod IP,导致流量被拒绝。
实践建议: 在编写 NetworkPolicy 时,始终以 Pod 的标签为基准,而非 Service 的名称或 IP。使用
kubectl get pods --show-labels 验证标签是否与策略匹配。对于需要暴露给集群外部的服务,考虑使用 Ingress 或 Gateway API,并在网络策略中明确允许入口流量。