在K8S中,网络策略原理是什么?
Kubernetes 网络策略(NetworkPolicy)的原理是为集群内部的 Pod 提供一种基于标签选择器的、声明式防火墙规则,用来控制 Pod 之间以及 Pod 与外部实体之间的网络流量(主要是入站流量,也支持出站流量)。其核心思想是默认拒绝,显式允许。
以下是其工作原理的关键点:
-
核心目标:Pod 级别的防火墙
- 传统防火墙通常在节点边界或网络边界工作。
- 网络策略将防火墙规则细化到 Pod 级别,提供更精细的微隔离(Micro-segmentation),符合云原生应用的安全需求(零信任网络模型的一部分)。
-
默认行为:
- 没有 NetworkPolicy 时: Kubernetes 集群默认允许所有 Pod 之间可以自由通信(所有入站/出站流量都允许)。这方便了部署,但安全性较低。
- 一旦某个 Namespace 或 Pod 定义了 NetworkPolicy:
- 入站流量 (Ingress): 对于匹配了
podSelector
的 Pod,默认拒绝所有入站流量(除非规则显式允许)。 - 出站流量 (Egress): 对于匹配了
podSelector
的 Pod,默认允许所有出站流量(除非在策略中显式指定了egress
规则进行限制)。egress
规则是可选的,主要用于限制出站流量。
- 入站流量 (Ingress): 对于匹配了
-
核心组件:
podSelector
: 定义此策略作用于哪些 Pod。使用标签选择器(Label Selector)来匹配目标 Pod。例如,matchLabels: { role: db }
会选择所有带有role=db
标签的 Pod。- 策略类型 (
policyTypes
): 指定策略是管理入站 (Ingress
)、出站 (Egress
) 还是两者。默认通常是Ingress
。 ingress
规则: 定义允许哪些入站流量到达podSelector
选中的 Pod。每条ingress
规则包含:from
: 指定允许流量的来源。来源可以是以下一种或多种组合:podSelector
: 同一 Namespace 内匹配标签的 Pod。namespaceSelector
: 匹配标签的 Namespace 中的所有 Pod(可跨 Namespace)。ipBlock
: 允许特定的 IP CIDR 块(可以是集群外部 IP 或集群内的其他 IP,但通常用于外部)。
ports
: 指定允许访问的协议和端口号(如TCP 6379
)。省略ports
表示允许该来源访问所有端口。
egress
规则 (可选): 定义podSelector
选中的 Pod 允许向哪些目的地发送出站流量。结构类似ingress
:to
: 指定允许流量的目的地(podSelector
,namespaceSelector
,ipBlock
)。ports
: 指定允许访问的协议和端口号。
-
工作原理 (以 Ingress 为例):
- 用户定义 NetworkPolicy YAML 文件: 用户创建一个 NetworkPolicy 资源,指定
podSelector
(选择受保护的 Pod),并定义ingress
规则 (允许哪些来源访问哪些端口)。 - API Server 存储策略: Kubernetes API Server 接收并存储该策略定义。
- 网络插件监听并实施: 实现了 Kubernetes NetworkPolicy API 的 CNI 网络插件(如 Calico, Cilium, Weave Net, Antrea 等)会监听 NetworkPolicy 资源的变化。
- 插件转换规则: 网络插件将抽象的 NetworkPolicy 规则(基于标签和 Namespace)转换为其底层网络技术(如 iptables, eBPF, OVS flows)能够理解和执行的具体规则。
- 规则下发到节点: 网络插件将这些具体的防火墙规则分发并配置到运行着目标 Pod 的各个工作节点上。
- 流量过滤:
- 当有流量试图进入节点上的某个 Pod 时(该 Pod 被某个 NetworkPolicy 的
podSelector
选中)。 - 节点上的网络组件(由 CNI 插件配置)会检查流量:
- 源 IP / Pod 身份(通常通过标签映射)。
- 目标端口。
- 将流量特征与配置的 NetworkPolicy 规则进行匹配。
- 如果流量匹配任何一条
ingress
规则中的from
和ports
,则允许通过。 - 如果没有任何规则匹配,则拒绝该流量(默认拒绝)。
- 当有流量试图进入节点上的某个 Pod 时(该 Pod 被某个 NetworkPolicy 的
- 用户定义 NetworkPolicy YAML 文件: 用户创建一个 NetworkPolicy 资源,指定
-
叠加(Additive)特性:
- 多个 NetworkPolicy 可以同时作用于同一个 Pod。
- 最终的允许规则是所有匹配该 Pod 的策略的
ingress
/egress
规则的并集(OR 关系)。 - 只要有一个策略的规则允许了某条流量,该流量就被允许。策略之间是叠加生效的,不是覆盖。
-
依赖 CNI 插件:
- 关键点: Kubernetes 本身只定义了 NetworkPolicy API。实际的策略执行完全依赖于你选择的 CNI 网络插件是否支持并实现了 NetworkPolicy。
- 像 Flannel 这样的基础网络插件通常不支持 NetworkPolicy。你必须使用 Calico, Cilium, Weave Net (带防火墙功能), Antrea 等支持策略的插件。
总结流程:
- 定义策略: 用户通过 YAML 声明“哪些 Pod(
podSelector
)允许从哪些来源(from
)访问哪些端口(ports
)”。 - API 存储: API Server 存储策略。
- 插件监听: CNI 插件监听策略变化。
- 规则转换: 插件将抽象策略转换为具体网络规则(iptables/eBPF 等)。
- 规则下发: 规则被配置到相关工作节点上。
- 流量过滤: 节点网络栈根据规则检查进出 Pod 的流量,仅允许匹配显式规则的流量,默认拒绝其他所有流量。
简单来说,Kubernetes 网络策略的工作原理就是通过声明式配置,借助支持策略的 CNI 插件,在 Pod 所在的宿主机节点上动态设置防火墙规则,实现基于标签的、细粒度的 Pod 网络隔离(白名单机制)。 它解决了默认“全通”带来的安全隐患,是实现服务网格安全和服务间最小权限访问的基础。