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 由租户自治管理。
4.2 与 Namespace 级策略的优先级关系
当 CCNP 与 CNP 同时作用于同一个 Pod 时,Cilium 遵循 “最宽匹配优先 + 显式拒绝优先” 的规则。理解这一优先级模型对于避免策略冲突至关重要。
4.2.1 优先级判定规则
- 显式拒绝(Deny)优先级最高:无论是 CCNP 还是 CNP,只要有一条规则显式拒绝流量,该流量即被丢弃。
- 显式允许(Allow)优先级次之:如果没有任何拒绝规则匹配,则检查允许规则。只要有一条规则显式允许,流量即被放行。
- 默认拒绝(Default Deny):如果没有任何规则匹配,Cilium 默认拒绝所有流量(除非显式配置了默认允许)。
- CCNP 与 CNP 之间无固定优先级:两者在规则层面是平等的,最终结果取决于规则的具体匹配内容。
常见误区: 不要认为 CCNP 的优先级高于 CNP。实际上,如果 CNP 显式允许了某流量,而 CCNP 没有显式拒绝该流量,则流量会被放行。反之亦然。策略冲突的解决依赖于规则内容,而非资源类型。
4.2.2 优先级冲突矩阵
| CCNP 规则 | CNP 规则 | 最终结果 | 说明 |
|---|---|---|---|
| 允许 | 允许 | 允许 | 两者一致,无冲突 |
| 拒绝 | 允许 | 拒绝 | 显式拒绝优先 |
| 允许 | 拒绝 | 拒绝 | 显式拒绝优先 |
| 拒绝 | 拒绝 | 拒绝 | 两者一致,无冲突 |
| 无规则 | 允许 | 允许 | CNP 显式允许生效 |
| 允许 | 无规则 | 允许 | CCNP 显式允许生效 |
| 无规则 | 无规则 | 默认拒绝 | 无任何显式规则 |
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 导致了流量被拒绝,从而调整策略配置。