2. NetworkPolicy 核心概念

NetworkPolicy 是 Kubernetes 原生的网络安全资源对象,用于定义 Pod 之间以及 Pod 与外部网络之间的流量访问规则。在多租户场景下,它是实现租户隔离、微服务安全边界和最小权限原则的核心手段。本章将深入解析 NetworkPolicy 的资源定义结构、Pod 选择器机制以及 Ingress/Egress 策略类型。

2.1 NetworkPolicy 资源定义结构

一个完整的 NetworkPolicy 资源由 API 版本、元数据、规格三部分组成。规格(spec)中包含了策略的核心控制逻辑:podSelector、policyTypes、ingress 和 egress。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: demo-policy
  namespace: tenant-a
spec:
  podSelector:
    matchLabels:
      app: frontend
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: backend
    ports:
    - protocol: TCP
      port: 8080
  egress:
  - to:
    - ipBlock:
        cidr: 10.0.0.0/16
        except:
        - 10.0.1.0/24
    ports:
    - protocol: TCP
      port: 443
关键字段说明:
  • podSelector:必填字段,通过标签选择器指定该策略作用于哪些 Pod。
  • policyTypes:声明策略类型,可选 Ingress、Egress 或两者都选。若不指定,默认只启用 Ingress。
  • ingress/egress:规则数组,每个规则包含 from/to 和 ports 子字段。
  • from/to:支持 podSelector、namespaceSelector、ipBlock 三种匹配方式。

2.2 Pod 选择器机制

Pod 选择器是 NetworkPolicy 的入口,决定了策略的生效范围。它基于 Kubernetes 标准的标签选择器(Label Selector)工作,支持两种匹配模式:

选择器类型 语法示例 匹配逻辑 典型场景
matchLabels app: frontend 精确匹配所有指定标签 选择单一微服务
matchExpressions In / NotIn / Exists / DoesNotExist 基于表达式集合匹配 多条件组合筛选
最佳实践:在多租户环境中,建议为每个租户的 Pod 打上 tenant: <tenant-id> 和 app: <service-name> 两层标签。NetworkPolicy 的 podSelector 优先使用 app 标签,而租户隔离通过 namespace 或 namespaceSelector 实现,避免策略跨租户泄漏。

2.3 策略类型:Ingress 与 Egress

NetworkPolicy 定义了两种流量方向的控制策略:

  • Ingress(入站流量):控制哪些来源可以访问目标 Pod。来源可以是同一命名空间内的 Pod、其他命名空间的 Pod 或外部 IP 段。
  • Egress(出站流量):控制目标 Pod 可以访问哪些目的地。目的地同样支持 Pod、命名空间和 IP 段三种模式。

当 policyTypes 中只声明 Ingress 时,Egress 流量默认全部放行;反之亦然。若两者都声明,则未匹配规则的流量将被拒绝。这是 Kubernetes 网络策略的白名单机制:未显式允许的流量一律拒绝。

常见陷阱:如果只定义了 Ingress 规则而未定义 Egress 规则,但 policyTypes 中包含了 Egress,则所有出站流量都会被拒绝。这会导致 Pod 无法访问 DNS、API Server 等基础服务。建议始终在 policyTypes 中明确声明需要控制的类型,避免意外阻断。

2.4 策略类型与流量方向关系图

下图展示了 NetworkPolicy 中 Ingress 和 Egress 策略的流量控制方向,以及三种匹配源/目的地的组合方式:

NetworkPolicy 策略类型与流量方向 目标 Pod app: frontend tenant: tenant-a Ingress 来源 podSelector / namespaceSelector / ipBlock Egress 目的地 podSelector / namespaceSelector / ipBlock 入站 出站 策略类型组合行为 • 仅 Ingress:入站流量受控,出站流量全部放行 • 仅 Egress:出站流量受控,入站流量全部放行 • Ingress + Egress:双向流量均受控,未匹配规则即拒绝 • 未指定 policyTypes:默认仅启用 Ingress 控制

2.5 多租户场景下的策略组合示例

以下是一个典型的多租户隔离策略配置,展示了如何结合 namespaceSelector 和 podSelector 实现租户间的严格隔离:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: tenant-isolation
  namespace: tenant-a
spec:
  podSelector:
    matchLabels:
      tenant: tenant-a
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          tenant: tenant-a
    - podSelector:
        matchLabels:
          app: monitoring
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          tenant: tenant-a
    - ipBlock:
        cidr: 0.0.0.0/0
        except:
        - 10.0.0.0/8
        - 172.16.0.0/12
        - 192.168.0.0/16
策略解读:
  • Ingress:只允许来自同一租户(tenant-a)命名空间的 Pod 访问,以及监控服务(app: monitoring)的访问。
  • Egress:只允许访问同一租户命名空间的 Pod,以及外部公网(排除私有 IP 段),防止数据泄露到其他租户的内网。
  • podSelector:通过 tenant: tenant-a 标签确保策略只作用于本租户的 Pod。

2.6 核心概念对比表

概念 作用范围 匹配方式 默认行为 多租户关键点
podSelector 本命名空间 标签选择器 空选择器匹配所有 Pod 使用租户标签精确限定
namespaceSelector 跨命名空间 命名空间标签 不匹配任何命名空间 通过租户标签实现隔离
ipBlock 集群内外 IP CIDR + except 不匹配任何 IP 用于控制外部访问
policyTypes 策略级别 Ingress / Egress 仅 Ingress 明确声明避免意外阻断

2.7 多租户 Pod 选择器设计模式

下图展示了在多租户环境中,如何通过分层标签设计实现精细化的 Pod 选择器策略:

多租户 Pod 选择器分层设计 租户层标签:tenant: tenant-a 用于 namespaceSelector 跨命名空间隔离 应用层标签:app: frontend / backend / database 用于 podSelector 微服务间精确匹配 版本层标签:version: v1 / v2 / canary 用于灰度发布和金丝雀部署时的策略控制
设计建议:在多租户 NetworkPolicy 配置中,建议将租户隔离放在 namespace 层面(通过 namespaceSelector),将服务间访问控制放在 podSelector 层面。这样既保证了租户间的强隔离,又保留了微服务间灵活通信的能力。版本层标签可用于实现蓝绿部署和金丝雀发布时的精细化流量控制。