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

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

相关文章

  • Minikube极速搭建单机k8s集群全过程

    Minikube极速搭建单机k8s集群全过程

    本篇教程分享了如何在Ubuntu上安装和配置Minikube,一个用于运行单机Kubernetes集群的工具,文章详细介绍了安装Docker、Kubectl和Minikube的步骤,并指导如何启动集群、验证安装以及部署一个简单的Nginx服务
    2025-12-12
  • k8s的架构组成操作代码

    k8s的架构组成操作代码

    k8s是一个轻便的和可扩展的开源平台,用于管理容器化应用和服务,通过k8s能够进行应用的自动化部署和扩缩容,这篇文章主要介绍了k8s的架构组成,需要的朋友可以参考下
    2024-05-05
  • 阿里云oss对象存储使用详细步骤

    阿里云oss对象存储使用详细步骤

    本文主要介绍了阿里云oss对象存储使用详细步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • Ansible部署K8s集群的方法

    Ansible部署K8s集群的方法

    这篇文章主要介绍了Ansible部署K8s集群,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-02-02
  • k8s部署dashboard ui管理平台全过程

    k8s部署dashboard ui管理平台全过程

    Kubernetes仪表盘是一个用于管理和监控Kubernetes集群的Web界面,它是一个容器化应用,可以通过Kubernetes的API进行部署和管理,仪表盘提供了一个用户友好的界面,可以查看和管理集群中的资源,包括Pod、Deployment、Service等
    2026-01-01
  • Kubernetes Gateway API TLS路由使用及说明

    Kubernetes Gateway API TLS路由使用及说明

    TLSRoute是GatewayAPI中的一个资源类型,用于处理TLS流量,可以根据主机名等TLS元数据将流量定向到不同的Kubernetes后端服务,通过配置Gateway和TLSRoute,可以实现TLS流量的透传和终止处理,满足不同的安全和管理需求
    2026-03-03
  • kubernetes中pod的调度亲和性affinity详解

    kubernetes中pod的调度亲和性affinity详解

    本文简要介绍了Kubernetes中的三种亲和性机制:节点亲和性(控制Pod调度到指定节点)、Pod亲和性(与特定Pod共处同一节点)和Pod反亲和性(避免与特定Pod共处同一节点),并通过示例说明了其配置方式及实际调度效果
    2025-09-09
  • 安装ingress-nginx遇到的一些坑实战记录

    安装ingress-nginx遇到的一些坑实战记录

    ingress是kubernetes集群对外暴露服务的一种方式,下面这篇文章主要给大家介绍了关于安装ingress-nginx遇到的一些坑,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-09-09
  • Podman开机自启容器实现过程及与Docker对比

    Podman开机自启容器实现过程及与Docker对比

    这篇文章主要为大家介绍了Podman开机自启容器实现过程,通过示例代码的形式进行演绎过程,有需要的朋友可以参考下,希望可以有所帮助
    2021-09-09
  • Spark三种属性配置方式详解

    Spark三种属性配置方式详解

    有时间还是多学习知识比较好,这篇文章主要介绍了Spark三种属性配置方式详解,具有一定参考价值,需要的朋友可以了解下。
    2017-10-10

最新评论