云其它

关注公众号 jb51net

关闭
首页 > 网站技巧 > 服务器 > 云和虚拟化 > 云其它 > NetworkPolicy工作原理

关于NetworkPolicy工作原理解读

作者:火星MARK

NetworkPolicy是Kubernetes中用于控制Pod间网络流量的资源对象,依赖于支持NetworkPolicy的CNI插件来实现流量控制,它通过定义入口和出口规则来允许或拒绝Pod间的通信,实现网络微分段,保障集群网络安全,NetworkPolicy遵循“默认拒绝,显式允许”的原则

NetworkPolicy 是 Kubernetes 中用于控制 Pod 间网络流量的核心资源对象,它通过定义规则来允许或拒绝 Pod 之间、Pod 与外部服务之间的网络通信。其本质是为 Kubernetes 集群提供网络微分段(Micro-segmentation) 能力,确保只有授权的流量才能在 Pod 间流动,是实现集群网络安全的关键组件。

一、NetworkPolicy 的核心定位与依赖前提

在理解工作原理前,需先明确其 “角色” 和 “运行条件”:

1. 核心定位

NetworkPolicy 本身不直接实现流量控制,而是一个 “规则定义层”—— 它仅声明 “哪些流量允许 / 拒绝”,真正执行流量过滤的是支持 NetworkPolicy 的网络插件(CNI)

2. 依赖前提:CNI 插件支持

并非所有 Kubernetes 网络插件都支持 NetworkPolicy,只有实现了 Kubernetes NetworkPolicy API 的插件才能生效。

常见支持的插件包括:

如果使用不支持的插件(如原生 Flannel),创建的 NetworkPolicy 会处于 “空转” 状态,无法对流量产生任何影响。

二、NetworkPolicy 的核心概念与规则模型

NetworkPolicy 通过 “选择目标 Pod” 和 “定义流量规则” 两个核心步骤工作,先明确控制对象,再限定流量范围。

1. 核心概念:目标 Pod 选择(Pod Selector)

NetworkPolicy 首先需要通过 podSelector 字段指定要控制的 Pod—— 只有匹配该选择器的 Pod,才会应用此策略的流量规则。

示例:通过 labels 匹配 Pod(标签为 app: nginx 的所有 Pod)

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: nginx-policy
spec:
  podSelector:  # 选择目标 Pod
    matchLabels:
      app: nginx
  policyTypes:  # 策略类型:Ingress(入站)、Egress(出站)
  - Ingress
  - Egress
  # ... 后续规则省略

特殊情况:若 podSelector 为空(podSelector: {}),则策略会应用于同一 Namespace 下的所有 Pod

2. 核心概念:策略类型(Policy Types)

NetworkPolicy 支持两种流量方向的控制,通过 policyTypes 声明:

注意:若未显式声明 policyTypes,Kubernetes 会默认规则:

3. 规则模型:“默认拒绝,显式允许”

NetworkPolicy 遵循最小权限原则,默认规则是 “拒绝所有未授权流量”:

三、Ingress 规则:控制入站流量

Ingress 规则定义 “哪些来源的流量可以进入目标 Pod”,核心是通过 from(流量来源)和 ports(目标端口)组合限制。

1. Ingress 规则结构

spec:
  ingress:
  - from:  # 允许的流量来源(可多个)
    - podSelector:  # 来源1:集群内的其他 Pod(通过标签匹配)
        matchLabels:
          app: client
    - namespaceSelector:  # 来源2:指定 Namespace 下的所有 Pod
        matchLabels:
          env: prod
    - ipBlock:  # 来源3:外部 IP 段(支持 CIDR 格式)
        cidr: 192.168.0.0/16
        except:  # 排除该段中的部分 IP
        - 192.168.1.0/24
    ports:  # 允许访问的目标 Pod 端口(可多个)
    - protocol: TCP  # 协议:TCP/UDP/SCTP
      port: 80  # 端口号(可写具体数字或容器端口名,如 "http")

2. 流量来源(from)的三种类型

from 字段用于定义 “允许哪些对象向目标 Pod 发送流量”,支持三种来源:

来源类型作用示例场景
podSelector匹配同一 Namespace下的特定 Pod允许 “前端 Pod(app: frontend)” 访问 “后端 Pod(app: backend)”
namespaceSelector匹配特定 Namespace下的所有 Pod允许 “测试环境 Namespace(env: test)” 的所有 Pod 访问 “生产环境的数据库 Pod”
ipBlock匹配外部 IP 段(集群外的流量)允许公司办公网(10.0.0.0/8)访问集群内的 Nginx Pod

组合使用:podSelector 和 namespaceSelector 可组合(逻辑 “与”),例如:

yaml

from:
- podSelector: {matchLabels: {app: client}}
  namespaceSelector: {matchLabels: {env: prod}}

含义:仅允许 “prod 命名空间下,标签为 app: client 的 Pod” 访问目标 Pod。

3. 目标端口(ports)

ports 字段定义 “允许访问目标 Pod 的哪些端口”,支持:

四、Egress 规则:控制出站流量

Egress 规则定义 “目标 Pod 可以向哪些目的地发送流量”,核心是通过 to(流量目的地)和 ports(目标端口)组合限制。

1. Egress 规则结构

spec:
  egress:
  - to:  # 允许的流量目的地(可多个)
    - podSelector:  # 目的地1:集群内的其他 Pod
        matchLabels:
          app: db
    - namespaceSelector:  # 目的地2:指定 Namespace 下的所有 Pod
        matchLabels:
          env: prod
    - ipBlock:  # 目的地3:外部 IP 段(如公网服务、数据库)
        cidr: 10.244.0.0/16
    ports:  # 允许访问的目的地端口(可多个)
    - protocol: TCP
      port: 5432  # 例如:允许目标 Pod 访问数据库的 5432 端口(PostgreSQL)

2. 流量目的地(to)的三种类型

to 字段与 Ingress 的 from 逻辑完全对称,支持三种目的地:

3. 常见场景:限制 Pod 访问外部服务

例如,限制 “应用 Pod” 仅能访问 “公网的支付 API(IP: 203.0.113.0/24,端口 443)”,则 Egress 规则如下:

egress:
- to:
  - ipBlock:
      cidr: 203.0.113.0/24
  ports:
  - protocol: TCP
    port: 443

五、NetworkPolicy 的执行逻辑与优先级

当多个 NetworkPolicy 同时匹配一个 Pod 时,流量规则的执行需遵循 “叠加允许、无拒绝叠加” 的原则。

1. 规则叠加逻辑

2. 优先级规则

Kubernetes 本身不直接支持 NetworkPolicy 的优先级声明(如 priority 字段),但部分 CNI 插件(如 Calico)扩展了优先级功能:

若使用原生 Kubernetes NetworkPolicy(无扩展),则所有匹配的策略规则平等叠加,允许规则 “取并集”。

六、NetworkPolicy 的底层执行流程(以 Calico 为例)

不同 CNI 插件的执行细节不同,但核心逻辑都是 “将 NetworkPolicy 规则转化为节点上的网络过滤规则”。以最常用的 Calico 为例,流程如下:

  1. 用户创建 NetworkPolicy:通过 kubectl apply 提交 NetworkPolicy YAML 到 Kubernetes API Server;
  2. CNI 插件监听策略变化:Calico 的 calico-kube-controllers 组件持续监听 API Server 中的 NetworkPolicy 资源,实时获取策略更新;
  3. 规则转化:Calico 将 NetworkPolicy 规则转化为 Linux iptables 规则(或 eBPF 程序,取决于 Calico 模式);
  4. 规则下发到节点:Calico 通过 calico-node 守护进程(每个节点上运行),将转化后的 iptables/eBPF 规则下发到目标 Pod 所在的节点;
  5. 流量过滤执行:当流量到达节点时,节点的内核通过 iptables/eBPF 规则检查流量的 “源 / 目的 Pod、端口、协议”,符合规则则放行,否则拒绝。

关键细节:为何基于节点执行规则?

Kubernetes Pod 的网络是 “Overlay 网络”(如 Calico 的 BGP 模式、Flannel 的 VXLAN 模式),Pod 的 IP 是虚拟 IP,流量最终需通过节点的物理网卡转发。因此,在节点上通过 iptables/eBPF 拦截流量,是最高效的执行方式。

七、常见误区与注意事项

  1. Namespace 隔离性:NetworkPolicy 是 ** Namespace 级别的资源 **,仅对同一 Namespace 下的 Pod 生效。若需跨 Namespace 控制,需通过 namespaceSelector 匹配目标 Namespace。
  2. 不影响 HostNetwork Pod:使用 hostNetwork: true 的 Pod(直接使用节点网络)不受 NetworkPolicy 控制,因为其流量不经过集群的 Overlay 网络,无法被 CNI 插件拦截。
  3. 不控制 Kubernetes 系统组件流量:默认情况下,kube-proxy、etcd、kube-apiserver 等系统组件的流量不受 NetworkPolicy 限制(需手动配置策略控制)。
  4. L7 层策略支持有限:原生 NetworkPolicy 仅支持 L3(IP)和 L4(端口、协议)层的控制;若需 L7 层(HTTP 路径、域名、请求头)的策略(如 “仅允许访问 /api/v1 路径”),需使用 Cilium(基于 eBPF)或 Istio(服务网格)等扩展方案。

八、总结

NetworkPolicy 的工作原理可归纳为三句话:

  1. 通过 podSelector 锁定目标 Pod,明确要控制的对象;
  2. 通过 Ingress/Egress 规则定义 “允许的流量方向、来源 / 目的地、端口”,遵循 “默认拒绝,显式允许”;
  3. 依赖 CNI 插件将规则转化为节点的网络过滤规则(如 iptables),在流量转发时执行过滤。

它是 Kubernetes 集群网络安全的基石,通过精细化的流量控制,可有效防范 “横向渗透攻击”(如某 Pod 被入侵后,限制其访问其他核心 Pod),是生产环境中不可或缺的配置。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文