Cilium网络策略排障要先回答一个问题:流量是被策略按预期拒绝,还是因为身份标签、端口协议、Service 路由或节点数据路径异常而被意外丢弃。Cilium 使用 eBPF 实现网络、可观测性和安全能力,并基于安全身份进行策略判定[1];Kubernetes NetworkPolicy 则描述允许的 Pod 通信关系,具体执行依赖网络插件[2]。
因此,排查时不要只盯着 YAML。更可靠的路径是先构造最小复现,再对齐源端和目标端身份,随后用 Hubble 或 Cilium 观测真实 verdict,最后才进入节点和 eBPF 数据路径分支。
如果你需要先补齐 Kubernetes 网络基础,可以参考 容器网络专题;如果正在比较 CNI 能力,可结合 Kubernetes CNI插件选型 理解 Cilium 与其他插件的边界。

图1:Cilium 网络策略排障需要同时查看策略对象、端点身份
最小复现:先把问题缩到一条流量
服务不可达可能来自 DNS、Service、Endpoint、Node 路由、Pod readiness、应用端口或网络策略。第一步不要直接改策略,而是把问题收敛到“哪个源 Pod 到哪个目标 Pod/Service 的哪个端口失败”。
建议先确认:
- 是 ingress 方向还是 egress 方向失败。
- 是访问 Service 失败,还是直连 Pod IP 也失败。
- 是单节点、跨节点,还是整个命名空间都失败。
- 最近是否变更了 labels、Namespace、NetworkPolicy 或 Cilium 版本。
kubectl get pods -o wide -n app
kubectl get svc,endpoints -n app
kubectl get networkpolicy,ciliumnetworkpolicy -A
cilium status
这些命令用于观察状态,NetworkPolicy 与 Cilium 策略语义应结合官方文档核对[1][2]。生产环境不要为了验证而删除所有 NetworkPolicy,优先用临时测试 Pod 和最小允许规则做对照。
身份标签:策略匹配失败的高频根因
Cilium 策略判定依赖端点身份,而身份由标签集合生成。标签选择器写错、Namespace 缺少标签、发布系统改写 labels,都会导致策略没有匹配到预期对象。
| 证据 | 要看什么 | 常见误判 |
|---|---|---|
| Pod labels | 源端和目标端实际标签 | 只看 Helm values,不看集群实际对象 |
| Namespace labels | namespaceSelector 是否匹配 | 忘记给命名空间补标签 |
| Cilium endpoint | endpoint identity 和 policy 状态 | Pod 重建后身份变化未注意 |
| 策略方向 | ingress/egress 是否写反 | 只允许了入站,忘记出站 DNS |
| 端口 | targetPort、containerPort、协议 | Service 端口和容器端口混淆 |
上线前的关键判断是:NetworkPolicy 一旦对某类 Pod 生效,未显式允许的流量可能被拒绝[2]。所以默认拒绝策略上线前,应先在测试命名空间或低风险服务中观察命中情况。

图2:Cilium 通过标签身份和策略选择器计算端点允许的流量
标签漂移比策略语法更隐蔽
策略 YAML 没变,不代表策略匹配结果没变。发布系统、Operator 或 Helm upgrade 可能修改 Pod labels,导致身份重新计算。排障时应以集群当前对象为准,而不是以仓库模板为准。
Hubble verdict:用真实流量替代猜测
Hubble 是 Cilium 的网络可观测能力,可查看服务依赖、流量方向、策略 verdict 和丢弃原因[3]。当 YAML 看似正确但访问仍失败时,Hubble 比人工推断更可靠。
观察时重点记录:
- 源端和目标端是否是预期 Pod 或 Service。
- verdict 是 FORWARDED、DROPPED 还是其他状态。
- 丢弃原因是否与策略、DNS、端口、身份或节点路径有关。
- 同一请求在同节点和跨节点是否表现一致。
hubble observe --namespace app --verdict DROPPED
hubble observe --from-pod app/client --to-pod app/server
cilium endpoint list
cilium endpoint get <endpoint-id>
verdict 要和策略版本对齐
如果 GitOps 或 CI/CD 正在持续应用网络策略,排障时要确认当前集群策略和仓库版本一致。否则你看到的策略文件可能不是 Cilium 正在执行的策略。
eBPF 数据路径排查边界
大多数 Cilium 网络策略问题停留在身份和策略匹配层。只有当策略、身份和 Hubble 证据都指向数据面异常时,才需要深入节点数据路径。
进入数据路径前,先确认:
- Cilium agent 在相关节点 Running 且 Ready。
- Cilium endpoint 状态为 ready。
- 节点间连通性和 Cilium health 正常。
- 最近没有升级 Cilium、内核或 CNI 配置。
- 问题是否只发生在某一类节点或可用区。

图3:Cilium eBPF 数据路径排障从端点状态、节点连通
修复后要验证收敛边界
网络策略修复后,要验证的不只是失败请求恢复,还要确认不该放行的流量仍然被拒绝。否则修复可能变成过宽放行。
建议做三组验证:
- 正向验证:预期允许的源、目标和端口可以访问。
- 反向验证:未授权命名空间或标签仍被拒绝。
- 回归验证:DNS、健康检查、服务网格代理和外部出口没有被误伤。
对默认拒绝策略,最好把验证脚本沉淀到发布流程中,避免每次变更都靠人工临时 curl。
小结
Cilium网络策略排障应按“最小复现—身份标签—Hubble verdict—数据路径”的顺序推进。多数问题来自标签选择、命名空间选择、方向和端口理解错误,而不是 eBPF 本身异常。
当策略复杂度上升后,建议为默认拒绝、跨命名空间访问、DNS、外部出口和服务网格流量分别建立测试用例。不要用放宽策略来掩盖身份和流量证据不清的问题。
参考资料
- [1] Cilium Documentation: Security Policy
- [2] Kubernetes Network Policies
- [3] Cilium Hubble Introduction
常见问题
1. 先看哪类网络策略?
先看集群实际存在并作用于目标 Pod 的策略类型。如果两者同时存在,要分别确认选择器、方向和端口语义,然后用 Hubble 观察真实 verdict。
2. Hubble 显示 DROPPED 就一定是策略问题吗?
不一定。DROPPED 需要结合丢弃原因、身份、端口和节点状态判断。策略拒绝、DNS、连接跟踪、节点路径异常或服务解析问题都可能导致丢弃。
3. 为什么策略没改,访问突然失败?
常见原因是 Pod 或 Namespace labels 变化导致身份重新计算,或者 GitOps 同步了新策略。也可能是节点、Cilium agent 或服务端口变化。应先核对当前集群对象,而不是只看仓库里的旧 YAML。
4. 与服务网格并用怎么排障?
先区分流量在哪一层被拒绝:应用容器、sidecar 代理、Cilium 策略还是节点路径。可以分别查看 Hubble、服务网格代理日志和应用日志,避免把 mTLS、路由和网络策略混在一起。
5. 修复网络策略时可以临时放开整个命名空间吗?
不建议作为默认动作。更稳妥的做法是增加最小允许规则,并同时验证未授权流量仍被拒绝。临时放开容易留下过宽策略,后续很难审计。