3、Cilium网络策略基础:NetworkPolicy资源定义、Ingress/Egress规则、标签选择器(EndpointSelector)、策略优先级与默认拒绝

在 Kubernetes 原生网络模型中,NetworkPolicy 是控制 Pod 间通信的核心资源。Cilium 在完全兼容 Kubernetes NetworkPolicy 的基础上,通过 CiliumNetworkPolicy (CNP) 扩展了更精细的 L3/L4/L7 控制能力。本章将深入解析策略的构成要素、规则定义与执行逻辑,为后续的迁移与蓝绿发布场景奠定基础。

3.1 NetworkPolicy 资源定义结构

一个标准的 Kubernetes NetworkPolicy 资源由以下核心字段构成:

字段 类型 说明
podSelector LabelSelector 选择策略生效的目标 Pod 集合
policyTypes []PolicyType 声明策略类型:Ingress、Egress 或两者
ingress []IngressRule 入站流量规则列表
egress []EgressRule 出站流量规则列表
关键点: 当 policyTypes 未显式指定时,Kubernetes 默认仅应用 Ingress 规则;Cilium 则建议始终显式声明 policyTypes 以避免歧义。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
spec:
  podSelector: {}
  policyTypes:
  - Ingress

3.2 Ingress / Egress 规则详解

Ingress 和 Egress 规则分别控制进入和离开 Pod 的流量。每条规则由 from(Ingress)或 to(Egress)以及 ports 组成。

3.2.1 Ingress 规则

Ingress 规则通过 from 字段定义允许的源端,支持以下选择器:

  • podSelector:允许来自同一 Namespace 内特定标签的 Pod
  • namespaceSelector:允许来自特定 Namespace 的所有 Pod
  • ipBlock:允许来自特定 CIDR 范围的流量(非 Kubernetes 原生 Pod)
spec:
  ingress:
  - from:
    - podSelector:
        matchLabels:
          role: frontend
    - namespaceSelector:
        matchLabels:
          project: production
    ports:
    - protocol: TCP
      port: 8080

3.2.2 Egress 规则

Egress 规则通过 to 字段定义允许的目标端,选择器类型与 Ingress 对称:

spec:
  egress:
  - to:
    - podSelector:
        matchLabels:
          role: database
    ports:
    - protocol: TCP
      port: 5432
最佳实践: 在蓝绿发布场景中,建议为每个版本(blue/green)的 Pod 打上唯一的版本标签,然后通过 Egress 规则精确控制流量只流向同版本的依赖服务,避免跨版本数据污染。

3.3 标签选择器(EndpointSelector)

Cilium 引入的 CiliumNetworkPolicy 使用 endpointSelector 替代 Kubernetes 的 podSelector,但本质都是基于标签的匹配机制。标签选择器支持以下操作符:

操作符 示例 匹配行为
In role In [frontend, api] 标签值属于集合中的任意一个
NotIn version NotIn [v1] 标签值不属于集合
Exists app Exists 标签键存在(无论值是什么)
DoesNotExist tier DoesNotExist 标签键不存在
注意: 标签选择器是 AND 逻辑——当在同一个 matchLabels 中指定多个键值对时,Pod 必须同时满足所有条件。如需 OR 逻辑,需在规则中列出多个 from 或 to 条目。

3.4 策略优先级与默认拒绝

Kubernetes 和 Cilium 的策略模型遵循 白名单机制:

  • 默认拒绝:一旦任何 NetworkPolicy 选中了一个 Pod,该 Pod 的所有未显式允许的流量都会被拒绝。
  • 策略叠加:多个 NetworkPolicy 作用于同一个 Pod 时,规则是 OR 关系——只要任意一个策略允许,流量即被放行。
  • 优先级:原生 Kubernetes NetworkPolicy 没有优先级概念,所有策略平等叠加。Cilium 通过 CiliumNetworkPolicy 的 priority 字段(0-65535,数值越小优先级越高)提供显式优先级控制。
迁移启示: 在从传统 NetworkPolicy 迁移到 CiliumNetworkPolicy 时,需注意 Cilium 的优先级机制可以解决策略冲突问题。例如,在蓝绿发布中,可以为新版本 Pod 设置更高优先级的策略,确保灰度期间的流量隔离。
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: allow-frontend-to-backend
spec:
  endpointSelector:
    matchLabels:
      role: backend
  ingress:
  - fromEndpoints:
    - matchLabels:
        role: frontend
        version: v2   # 仅允许 v2 版本的 frontend 访问
    ports:
    - port: "8080"
      protocol: TCP
  priority: 100       # 显式优先级,数值越小优先级越高

3.5 策略执行流程与默认拒绝模型

下图展示了 Cilium 在处理 Pod 网络流量时的策略评估流程:

Cilium 策略评估流程 流量到达 Pod 检查是否有策略选中该 Pod 无策略 → 默认允许所有流量 有策略 → 默认拒绝 + 白名单 流量放行 仅匹配白名单规则放行 说明:Cilium 默认允许所有流量,直到有策略选中 Pod 后切换为默认拒绝 + 白名单模式

3.6 策略优先级在蓝绿发布中的应用

在蓝绿发布场景中,策略优先级可以解决以下关键问题:

  • 流量隔离:为绿色(新版本)环境设置高优先级策略,确保其仅与同版本服务通信
  • 渐进式放行:通过调整优先级,逐步将流量从蓝色(旧版本)迁移到绿色
  • 快速回滚:当绿色版本出现问题时,降低其策略优先级或直接删除,恢复蓝色版本的默认策略
实战建议: 在 Cilium 中,建议为每个微服务版本维护独立的 CiliumNetworkPolicy,并使用 priority 字段控制生效顺序。例如,将绿色版本的策略优先级设为 50,蓝色版本设为 100,确保绿色版本的规则优先匹配。

下表总结了不同策略配置在蓝绿发布中的行为:

场景 策略配置 流量行为
仅蓝色运行 蓝色策略优先级 100 所有流量流向蓝色
绿色部署完成 绿色策略优先级 50 绿色优先处理,蓝色作为备份
灰度测试 绿色策略 + 标签选择器限制 仅特定标签的流量进入绿色
回滚 删除绿色策略或降低优先级 流量自动切回蓝色
避坑指南: 不要忘记在 CiliumNetworkPolicy 中显式设置 priority 字段。如果不设置,Cilium 会使用默认优先级 0(最高优先级),可能导致多个策略之间的意外覆盖。建议在团队内建立优先级分配规范,例如:核心服务 0-100,普通服务 101-500,测试服务 501-1000。