4. CiliumNetworkPolicy 入门:策略作用域、标签选择器、Ingress/Egress 规则、协议与端口匹配

CiliumNetworkPolicy(CNP)是 Cilium 多租户隔离的核心策略载体。与 Kubernetes 原生 NetworkPolicy 相比,CNP 在作用域、选择器表达能力、协议深度匹配以及 L7 可观测性上均有显著增强。本章将系统拆解 CNP 的四大基础构件,为后续的租户隔离模板与灰度准入检查奠定语法基础。

4.1 策略作用域:集群范围与命名空间范围

Cilium 提供两种策略资源,作用域不同,适用场景也不同:

资源类型 API 版本 作用域 典型用途
CiliumNetworkPolicy cilium.io/v2 命名空间级别 租户内部微隔离、应用层策略
CiliumClusterwideNetworkPolicy cilium.io/v2 集群级别(跨命名空间) 全局基线策略、共享服务访问、节点级管控
设计建议:在多租户集群中,建议将“全局拒绝基线”定义为 CiliumClusterwideNetworkPolicy,将“租户内允许规则”定义为命名空间级别的 CiliumNetworkPolicy。二者通过标签选择器叠加生效,形成“默认拒绝 + 显式允许”的安全模型。

4.2 标签选择器:基于身份的策略匹配

Cilium 不依赖 IP 地址或 CIDR 进行策略匹配,而是使用 基于标签的身份(Identity)。每个 Kubernetes Pod 根据其标签组合被分配一个安全身份,策略通过标签选择器引用该身份。

标签选择器支持三种匹配模式:

  • matchLabels:精确匹配,所有指定标签必须同时存在且值相等。
  • matchExpressions:表达式匹配,支持 In、NotIn、Exists、DoesNotExist 操作符。
  • matchNames:按命名空间名称匹配(仅用于 endpointSelector 或 fromEndpoints/toEndpoints 的命名空间限定)。
关键区别:Kubernetes NetworkPolicy 的标签选择器只能匹配 Pod 自身的标签;CiliumNetworkPolicy 的 endpointSelector 可以匹配任意标签组合,并且支持在 fromEndpoints / toEndpoints 中嵌套命名空间选择器,实现跨命名空间的精确控制。

以下是一个使用标签选择器限定“只允许 frontend 命名空间中 role=api 的 Pod 访问 backend 命名空间中 app=db 的 Pod”的示例:

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: frontend-to-backend
  namespace: backend
spec:
  endpointSelector:
    matchLabels:
      app: db
  ingress:
  - fromEndpoints:
    - matchLabels:
        role: api
      matchNames:
      - frontend
    toPorts:
    - ports:
      - port: "5432"
        protocol: TCP

4.3 Ingress / Egress 规则结构

CNP 的规则结构分为 Ingress(入站)和 Egress(出站)两个方向,每个方向下可以定义多个规则块。每个规则块包含来源/目标选择器、端口匹配、以及可选的 L7 规则。

CiliumNetworkPolicy 规则结构 CiliumNetworkPolicy Ingress 规则块 Egress 规则块 fromEndpoints fromCIDR toPorts toEndpoints toCIDR toPorts 规则叠加说明 • 每个方向可包含多个规则块,规则块之间是 OR 关系 • 每个规则块内的选择器之间是 AND 关系 • 未匹配任何规则的流量默认被拒绝(Default Deny)

4.4 协议与端口匹配

CNP 在 toPorts 字段中支持精细的协议与端口匹配,覆盖 L3/L4 以及可选的 L7 层。

4.4.1 L3/L4 端口匹配

基础端口匹配使用 ports 数组,每个条目包含端口号和协议类型:

toPorts:
- ports:
  - port: "443"
    protocol: TCP
  - port: "53"
    protocol: UDP
  - port: "2379-2380"
    protocol: TCP   # 端口范围

支持的协议值:TCP、UDP、SCTP、ICMP(仅限 Cilium 增强模式)。

4.4.2 L7 协议感知匹配

当启用 L7 代理(Envoy)时,CNP 可以在端口规则内嵌套 L7 规则,实现基于 HTTP 方法、路径、gRPC 服务、Kafka Topic 等应用层匹配:

toPorts:
- ports:
  - port: "8080"
    protocol: TCP
  rules:
    http:
    - method: GET
      path: "/api/v1/orders"
    - method: POST
      path: "/api/v1/orders"
      headers:
      - "X-Tenant-Id: tenant-a"
性能注意事项:L7 规则会引入代理转发路径,增加延迟约 1-5ms。对于延迟敏感型业务(如实时交易、视频流),建议仅在必要的端口上启用 L7 规则,其余端口保持 L3/L4 模式。

4.5 策略生效顺序与默认行为

理解 CNP 的生效顺序对于调试多租户策略至关重要:

  1. 默认拒绝:一旦任何 CiliumNetworkPolicy 选中了一个端点,该端点未显式允许的流量将被拒绝。
  2. 规则叠加:多个策略规则之间是 OR 关系,只要有一条规则允许,流量即通过。
  3. 优先级:CiliumClusterwideNetworkPolicy 与 CiliumNetworkPolicy 具有相同优先级,不存在覆盖关系,二者同时生效。
  4. 无状态回退:如果 Cilium Agent 无法连接到 KV 存储或策略同步延迟,默认行为是保留最后已知的有效策略集,而非放通所有流量。
策略生效决策流程 流量到达端点 检查所有 CNP 规则 匹配到允许规则 无匹配规则 ✅ 允许通过 ❌ 拒绝丢弃

4.6 常见陷阱与最佳实践

陷阱 说明 解决方案
遗漏命名空间选择器 fromEndpoints 未指定命名空间时,默认匹配集群内所有命名空间的端点 始终在 fromEndpoints 中嵌套 matchNames 或使用命名空间级别的 CiliumNetworkPolicy
端口范围格式错误 使用 "2379-2380" 时两端必须为数字,不能包含空格 使用 YAML 引号包裹端口字符串,避免被解析为数字
L7 规则未生效 未在 Cilium Agent 启动参数中启用 L7 代理 确认 helm 安装时设置 l7Proxy=true,且端点已注入 Envoy sidecar
策略未应用到节点 CiliumClusterwideNetworkPolicy 的 nodeSelector 未正确匹配 使用 cilium identity list 验证节点身份标签
调试命令速查:
cilium policy get <namespace>/<policy-name> — 查看已生效策略
cilium endpoint list — 查看端点身份与标签
cilium monitor -t policy-verdict — 实时查看策略判决日志