4. CiliumClusterwideNetworkPolicy详解:集群范围策略的作用域、与Namespace级策略的优先级关系、适用场景

在多租户控制面架构中,租户隔离边界不仅限于单一命名空间。当网络策略需要跨越多个命名空间、作用于集群节点或管控南北向流量时,CiliumClusterwideNetworkPolicy(CCNP) 成为唯一的选择。本章深入解析 CCNP 的作用域模型、与 Namespace 级策略的优先级冲突解决机制,以及典型适用场景。

4.1 作用域模型:从 Namespace 到 Cluster

Cilium 提供两种网络策略资源,其作用域差异决定了多租户架构中的职责划分:

特性 CiliumNetworkPolicy (CNP) CiliumClusterwideNetworkPolicy (CCNP)
资源类型 Namespaced Cluster
作用域 仅作用于指定 Namespace 内的 Pod 作用于集群所有 Namespace 的 Pod 及节点
匹配端点 只能通过 endpointSelector 匹配本 Namespace 的 Pod 可通过 nodeSelector 匹配节点,或通过 endpointSelector 匹配任意 Namespace 的 Pod
适用流量 Pod-to-Pod 东西向流量 东西向 + 南北向(节点流量、HostNetwork Pod、External CIDR)
多租户隔离 租户内部策略 全局基线策略、跨租户管控、节点级安全
关键区别: CNP 受 Namespace 边界约束,而 CCNP 不受 Namespace 限制。在多租户架构中,CCNP 通常由平台团队管理,用于定义全局安全基线;CNP 由租户自治管理。
CCNP 与 CNP 作用域对比 CiliumNetworkPolicy (CNP) 作用域:单一 Namespace Namespace A Pod Pod endpointSelector Namespace B Pod Pod endpointSelector ✗ 无法跨 Namespace 匹配 ✗ 无法匹配节点 CiliumClusterwideNetworkPolicy (CCNP) 作用域:整个集群 集群节点 (nodeSelector) Node-1 Node-2 Node-3 nodeSelector 匹配节点标签 任意 Namespace Pod (endpointSelector) Pod-A Pod-B Pod-C Pod-D endpointSelector 可跨 Namespace 匹配

4.2 与 Namespace 级策略的优先级关系

当 CCNP 与 CNP 同时作用于同一个 Pod 时,Cilium 遵循 “最宽匹配优先 + 显式拒绝优先” 的规则。理解这一优先级模型对于避免策略冲突至关重要。

4.2.1 优先级判定规则

  1. 显式拒绝(Deny)优先级最高:无论是 CCNP 还是 CNP,只要有一条规则显式拒绝流量,该流量即被丢弃。
  2. 显式允许(Allow)优先级次之:如果没有任何拒绝规则匹配,则检查允许规则。只要有一条规则显式允许,流量即被放行。
  3. 默认拒绝(Default Deny):如果没有任何规则匹配,Cilium 默认拒绝所有流量(除非显式配置了默认允许)。
  4. CCNP 与 CNP 之间无固定优先级:两者在规则层面是平等的,最终结果取决于规则的具体匹配内容。
常见误区: 不要认为 CCNP 的优先级高于 CNP。实际上,如果 CNP 显式允许了某流量,而 CCNP 没有显式拒绝该流量,则流量会被放行。反之亦然。策略冲突的解决依赖于规则内容,而非资源类型。

4.2.2 优先级冲突矩阵

CCNP 规则 CNP 规则 最终结果 说明
允许 允许 允许 两者一致,无冲突
拒绝 允许 拒绝 显式拒绝优先
允许 拒绝 拒绝 显式拒绝优先
拒绝 拒绝 拒绝 两者一致,无冲突
无规则 允许 允许 CNP 显式允许生效
允许 无规则 允许 CCNP 显式允许生效
无规则 无规则 默认拒绝 无任何显式规则
CCNP 与 CNP 优先级判定流程 流量到达 Pod 检查所有 CCNP + CNP 拒绝规则 匹配到拒绝规则 未匹配到拒绝规则 拒绝流量 检查允许规则

4.3 适用场景

CCNP 在多租户控制面架构中主要解决以下四类场景:

4.3.1 全局基线策略

平台团队使用 CCNP 定义集群级别的安全基线,例如:

  • 禁止所有 Pod 访问集群节点:防止租户 Pod 绕过 kube-proxy 直接访问节点端口。
  • 强制所有出口流量经过代理:通过 CCNP 将出口流量重定向到 egress-gateway。
  • 允许监控系统访问所有 Pod:为 Prometheus、Grafana 等监控组件创建全局白名单。
apiVersion: cilium.io/v2
kind: CiliumClusterwideNetworkPolicy
metadata:
  name: global-egress-proxy
spec:
  endpointSelector:
    matchLabels:
      "k8s:io.kubernetes.pod.namespace": "*"
  egress:
    - toCIDR:
        - 0.0.0.0/0
      except:
        - 10.0.0.0/8
        - 172.16.0.0/12
        - 192.168.0.0/16
      toEndpoints:
        - matchLabels:
            "k8s:app": egress-proxy

4.3.2 跨租户隔离

当租户分布在多个 Namespace 中时,CCNP 可以强制跨 Namespace 的隔离规则:

  • 禁止租户 A 访问租户 B:通过匹配租户标签实现。
  • 允许共享服务 Namespace 被所有租户访问:例如 DNS、Ingress Controller。

4.3.3 节点级安全管控

CCNP 是唯一能够匹配节点(nodeSelector)的策略类型,适用于:

  • 限制 HostNetwork Pod 的流量:例如 kube-proxy、calico-node 等。
  • 管控节点与外部网络的通信:例如限制节点只能访问特定 NTP/DNS 服务器。

4.3.4 南北向流量策略

对于 LoadBalancer Service、NodePort 或 ExternalIP 的流量,CCNP 可以通过 toCIDR 和 fromCIDR 进行管控:

  • 限制外部客户端只能访问特定 Service:通过 CCNP 的 fromCIDR 实现。
  • 允许特定外部监控系统访问集群:例如允许 203.0.113.0/24 访问 kube-apiserver。
最佳实践: 在多租户架构中,建议将 CCNP 的创建权限仅授予平台管理员(ClusterRole),租户只能管理自己 Namespace 内的 CNP。CCNP 用于定义“不可绕过”的安全基线,CNP 用于租户自定义策略。

4.4 策略冲突排查方法

当 CCNP 与 CNP 产生非预期冲突时,使用以下命令进行排查:

# 查看 Pod 上生效的所有策略
kubectl exec -n tenant-a pod/nginx -- cilium endpoint list

# 查看特定端点的策略决策
kubectl exec -n tenant-a pod/nginx -- cilium endpoint get <endpoint-id>

# 查看 Cilium 策略状态
kubectl get ciliumclusterwidenetworkpolicies -o yaml

# 查看策略追踪日志(需开启 Hubble)
hubble observe --from-pod tenant-a/nginx --to-pod tenant-b/app

通过 Hubble 的流量观察,可以快速定位是 CCNP 还是 CNP 导致了流量被拒绝,从而调整策略配置。