关于NetworkPolicy工作原理解读

 更新时间:2025年10月14日 09:44:23   作者:火星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 的插件才能生效。

常见支持的插件包括:

  • Calico(应用最广泛,支持丰富的策略规则)
  • Flannel(需配合 flannel-vxlan+policy 或第三方组件才支持)
  • Cilium(基于 eBPF,性能优异,支持 L3/L4/L7 层策略)
  • Weave Net(原生支持 NetworkPolicy)

如果使用不支持的插件(如原生 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 声明:

  • Ingress:控制 “进入目标 Pod 的流量”(即其他 Pod / 外部服务向目标 Pod 发送的请求)。
  • Egress:控制 “从目标 Pod 发出的流量”(即目标 Pod 向其他 Pod / 外部服务发送的请求)。

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

  • 若策略中定义了 ingress 规则,则自动添加 Ingress 类型;
  • 若策略中定义了 egress 规则,则自动添加 Egress 类型。

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

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

  • 若某 Namespace 下存在针对 Pod 的 Ingress 策略,默认拒绝所有入站流量,仅允许策略中显式声明的入站流量;
  • 若存在 Egress 策略,默认拒绝所有出站流量,仅允许策略中显式声明的出站流量;
  • 若某 Pod 未被任何 NetworkPolicy 匹配,则该 Pod 的流量不受限制(允许所有入站和出站)。

三、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 的哪些端口”,支持:

  • 具体端口号:如 port: 80
  • 容器端口名:如 port: http(需在 Pod 的 containers.ports.name 中定义该名称);
  • 协议指定:默认 TCP,可显式指定 protocol: UDP 或 SCTP

四、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 逻辑完全对称,支持三种目的地:

  • podSelector:同一 Namespace 下的特定 Pod;
  • namespaceSelector:特定 Namespace 下的所有 Pod;
  • ipBlock:外部 IP 段(如集群外的数据库、API 服务)。

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. 规则叠加逻辑

  • 允许规则叠加:多个 Ingress/Egress 策略中,只要有一个策略允许某类流量,该流量就会被允许(逻辑 “或”);
  • 拒绝规则不叠加:NetworkPolicy 仅支持 “显式允许”,不支持 “显式拒绝”(没有 deny 字段)。若需实现 “拒绝特定流量”,需通过 “先允许所有,再排除特定” 的方式间接实现(例如:ipBlock.cidr: 0.0.0.0/0 允许所有 IP,再通过 except 排除特定 IP 段)。

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),是生产环境中不可或缺的配置。

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

相关文章

  • Kubernetes Ingress实现细粒度IP访问控制

    Kubernetes Ingress实现细粒度IP访问控制

    这篇文章主要为大家介绍了Kubernetes Ingress实现细粒度IP访问控制,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • 带你学会k8s 更高级的对象Deployment

    带你学会k8s 更高级的对象Deployment

    这篇文章主要为大家介绍了k8s还有更高级的"对象"Deployment使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • k8s中pod不停重启问题定位原因与解决方法

    k8s中pod不停重启问题定位原因与解决方法

    这篇文章主要给大家介绍了关于k8s中pod不停重启问题定位原因与解决方法的相关资料,Kubernetes是一款高度可扩展、可靠的容器编排和管理系统,它简化了容器的部署、管理和自动化操作,需要的朋友可以参考下
    2023-08-08
  • Kubernetes存储系统数据持久化管理详解

    Kubernetes存储系统数据持久化管理详解

    这篇文章主要为大家介绍了Kubernetes存储系统数据持久化管理详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • k8s集群部署过程

    k8s集群部署过程

    本文详细介绍了如何部署Kubernetes集群,包括安装Docker、配置阿里云YUM软件源、安装kubeadm、kubelet和kubectl,以及部署Kubernetes、安装Pod网络插件和将节点加入集群的过程,感兴趣的朋友一起看看吧
    2025-03-03
  • IoT边缘集群Kubernetes Events告警通知实现示例

    IoT边缘集群Kubernetes Events告警通知实现示例

    这篇文章主要为大家介绍了IoT边缘集群Kubernetes Events告警通知实现示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-02-02
  • Prometheus Operator架构介绍

    Prometheus Operator架构介绍

    这篇文章主要为大家介绍了Prometheus Operator架构介绍,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • k8s series初级calico使用介绍

    k8s series初级calico使用介绍

    这篇文章主要为大家介绍了k8s series初级calico使用介绍,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • 使用kubeadm部署多节点集群

    使用kubeadm部署多节点集群

    这篇文章介绍了使用kubeadm部署多节点集群的方法,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-04-04
  • k8s中的NetworkPolicy使用详解

    k8s中的NetworkPolicy使用详解

    这篇文章主要介绍了k8s中的NetworkPolicy使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-10-10

最新评论