3. CiliumNetworkPolicy 核心概念:策略作用域、标签选择器与默认拒绝
在 Cilium 的零信任安全模型中,理解策略的作用域、标签选择器机制以及默认拒绝原则是编写可排查策略的基础。本章将拆解这三个核心概念,并展示它们如何共同构成 Cilium 网络策略的骨架。
3.1 策略作用域:Ingress 与 Egress
CiliumNetworkPolicy 通过 spec.ingress 和 spec.egress 两个独立字段定义流量方向。每个方向都是一个规则列表,规则之间是 OR 关系(满足任意一条即放行)。
| 作用域 | 方向 | 控制对象 | 典型场景 |
|---|---|---|---|
| Ingress | 入站 | 谁可以访问当前 Pod | 只允许 frontend 访问 backend |
| Egress | 出站 | 当前 Pod 可以访问谁 | 只允许 backend 访问数据库 |
排查要点: 当流量被拒绝时,首先确认策略是作用于 Ingress 还是 Egress。使用
cilium monitor -t drop 查看丢弃事件中的方向标识。
3.2 标签选择器机制:身份识别的核心
Cilium 不使用传统 IP 或 CIDR 作为策略主体,而是使用 Kubernetes 标签选择器。每个 Pod 的标签集合决定了它的安全身份。策略通过 matchLabels 和 matchExpressions 选择目标端点。
- fromEndpoints / toEndpoints:基于标签选择源或目标 Pod。
- fromRequires / toRequires:强制要求所有匹配的端点必须同时满足额外标签(用于多租户隔离)。
- fromNodes / toNodes:基于节点标签选择(适用于节点级控制)。
- fromCIDR / toCIDR:用于与集群外部通信(非 Kubernetes 端点)。
故障排查黄金法则: 如果策略未生效,90% 的原因是标签选择器写错了。使用
kubectl get pods --show-labels 验证目标 Pod 的标签是否与策略中的 matchLabels 完全匹配。
3.3 默认拒绝原则
Cilium 的默认行为是 白名单模式:一旦任何 CiliumNetworkPolicy 应用到某个 Pod,该 Pod 的所有流量(Ingress 和 Egress)都会被默认拒绝,除非显式放行。这是实现零信任网络的基础。
- 隐式拒绝:未匹配任何规则的流量被丢弃。
- 显式放行:必须编写规则明确允许特定流量。
- 策略优先级:Cilium 不支持传统防火墙的优先级数字。所有规则是 累加且非冲突 的——只要有一条规则允许,流量即通过;只要没有规则允许,流量即拒绝。
常见陷阱: 很多工程师误以为“没有策略就是允许”。在 Cilium 中,没有策略 = 默认拒绝(仅针对被策略选中的 Pod)。未被任何策略选中的 Pod 仍然可以自由通信,直到第一个策略应用。
3.4 核心概念关系图
下图展示了策略作用域、标签选择器与默认拒绝之间的逻辑关系:
3.5 策略优先级与规则合并
Cilium 的策略模型是 非抢占式 的。多个策略可以同时作用于同一个 Pod,所有规则被合并处理。合并规则如下:
| 场景 | 合并结果 | 示例 |
|---|---|---|
| 策略 A 允许 Ingress | 允许 | 策略 A 允许来自 app=frontend 的流量 |
| 策略 B 拒绝 Ingress | 允许(Cilium 无拒绝规则) | 策略 B 无法覆盖策略 A 的允许 |
| 策略 A 允许,策略 C 允许不同源 | 两个源都允许 | 来自 app=frontend 和 app=monitor 的流量均放行 |
| 无策略匹配 | 默认拒绝 | 流量被丢弃 |
排查技巧: 使用
kubectl describe cnp <policy-name> 查看策略的 Status 字段。如果 Enforcing: true,说明策略已生效。使用 cilium endpoint list 查看每个端点的策略摘要。
3.6 标签选择器匹配流程
下图展示了当流量到达 Pod 时,Cilium 如何通过标签选择器决定是否放行:
3.7 实战排查清单
- 确认策略是否应用:
kubectl get cnp -n <namespace>查看策略列表。 - 确认标签是否匹配:
kubectl get pods -n <namespace> --show-labels对比策略中的matchLabels。 - 确认作用域方向:检查被拒绝的流量是 Ingress 还是 Egress,对应查看策略中的
fromEndpoints或toEndpoints。 - 确认默认拒绝是否生效:如果 Pod 有策略但流量被拒,检查是否有显式放行规则。
- 使用 Hubble 可视化:
hubble observe -n <namespace> --verdict DROPPED查看丢弃流量的具体原因。
关键提醒: 标签选择器是大小写敏感的。Kubernetes 标签值中的空格、特殊字符都会导致匹配失败。建议在编写策略前,先使用
kubectl label --dry-run=client 验证标签语法。