「连接超时」与「明确被策略拒绝」的根因很少落在同一层。前者可能是
Service 后端为空、CT 压力、或加密路径黑洞;后者在 Hubble
里通常已写明 Policy denied。若一上来重启全部
cilium
DaemonSet,因果链会被冲掉,还可能把可恢复的 identity
同步抖动放大成双故障。
本文是系列第 13 篇:按五轴映射症状,并把每一步钉到 status / Hubble / BPF map / 控制面对象。观测字段语义见第 12 篇;产品级总览外链 k8s-network/13。不粘贴未执行的集群输出。
本文是「Cilium / eBPF 数据面内核」系列第 13 篇(共 16 篇)。→ 系列目录
篇目 核心内容 第 12 篇 · 可观测 status / metrics / bpftool 口径 第 13 篇 · 排障坐标系 五轴归因 第 14 篇 · 对照替代路径 Calico / kube-proxy / sidecar / Ambient
版本锚定:Cilium v1.20.0。官方 Operations / Troubleshooting 为 A 级入口;policy map 压力专节与 identity 同步说明必须对照当前小版本行为。
一、先选轴,再动参数
轴一:通用丢包 / 超时 — 尚未分型的连通性失败
轴二:Policy deny — 明确策略拒绝
轴三:Identity 漂移 — 标签变更窗口内的偶发拒绝或放行
轴四:Service 黑洞 — ClusterIP/NodePort 无有效后端或 LB 未命中
轴五:加密失败 — WireGuard/IPsec 路径上的失败或静默黑洞
每轴固定三列:症状 → 先查什么(按层)→ 不要先做什么。与 Rook 排障、代理系列排障同一纪律:一次否证一轴。
flowchart TD
symptom["Symptom"]
symptom --> axis["Pick one axis"]
axis --> a1["Generic drop / timeout"]
axis --> a2["Policy deny"]
axis --> a3["Identity drift"]
axis --> a4["Service blackhole"]
axis --> a5["Encryption failure"]
| 轴 | 触发选轴的症状 | 先查(层顺序) | 不要先做 |
|---|---|---|---|
| 一 | 超时、无明确 deny 文案 | Hubble drop reason → 分流到二至五;否则 CT/map 压力 | 全集群重启 cilium;改随机 CNP |
| 二 | Hubble/monitor 含 Policy denied | 源/目的 identity → CNP/NP selectors → policy map | 先关全部策略「验证网络」后忘开 |
| 三 | 变更标签/滚动后短暂失败或短暂误放行 | identity 分配与传播 →
policy_implementation_delay |
当成纯 DNS 问题;忽略时间窗 |
| 四 | 对 Pod IP 通、对 ClusterIP 不通;或跨节点 Service 失败 | endpoints/EndpointSlice → bpf lb → KPR
模式 |
先删重建 Service「碰运气」 |
| 五 | 同节点通、跨节点挂;或仅加密开启后失败 | encrypt status → 路径是否应进隧道 → WG/IPsec | 先关加密当永久修复而不记 ADR |
默认入口顺序(可裁剪):cilium status
→ hubble observe --verdict DROPPED(或对应
Pod)→(按 reason)进入轴二至五 → map/metrics。
层坐标(全文复用)
| 层 | 典型对象 | 否证问题 |
|---|---|---|
| Status | cilium status /
cilium-dbg status |
控制面是否已自报故障? |
| Flow | Hubble observe / monitor | 这条流的 verdict 与 reason 是什么? |
| Map | policy / service / CT | 查找键是否存在?map 是否压力过高? |
| API | NetworkPolicy、CiliumNetworkPolicy、Service、EndpointSlice | 意图对象是否与数据面一致? |
| Crypto | WireGuard/IPsec 状态 | 该路径是否应加密却未建立? |
二、轴一:通用丢包 / 超时
症状
- 应用日志
connection timed out/i/o timeout。 - 合成探测失败,但尚无「策略拒绝」证据。
cilium status可能全绿。
核对路径
Status:排除 agent NotReady、kvstore 断连、明显 controller 失败。若 status 已红,先修控制面,再解释业务超时。
Flow:在事故窗口对源/目的 Pod 跑
Hubble(或 cilium-dbg monitor)。关键是读到
drop reason,而不是只确认「有流量」。
| 常见 reason 方向 | 转入 |
|---|---|
| Policy denied | 轴二 |
| 与 service / backend 相关的失败叙事 | 轴四 |
| 加密/无效标记类(视版本文案) | 轴五 |
| CT 相关、或无事件但业务超时 | 继续本轴:map 压力与观测环 |
Map / Metrics:看
cilium_bpf_map_pressure、CT GC 与 CT
条目是否在同窗口尖刺。官方强调 policymap
压力会导致策略行为异常;CT
满则新建连接失败模式与「策略拒绝」不同。
不要先做:关闭 Hubble「减负」;在未分型前把 NetworkPolicy 全部删掉;把超时一律写成「内核 bug」。
轴一出口:只要拿到稳定 reason,就离开轴一;轴一不是垃圾桶,是分诊台。
三、轴二:Policy deny
症状
- Hubble / monitor 明确
Policy denied(或等价文案)。 - 源、目的 identity 数字可复述。
机制回顾(与第 7 篇对齐)
数据面用
identity(而非每次解析全量标签集)做策略键。TC/BPF
路径上对 {src_identity, dport, proto} 一类键做
map 查找;未命中允许规则且默认拒绝时,verdict 为
deny。产品叙事见 k8s-network/13;本轴只钉排障动作。
核对路径
Flow:记录
identity A -> B、端口、方向(ingress/egress)、L7
时是否已进 Envoy 路径(第 10 篇)。L3/L4 deny 与 L7 deny
的修复面不同。
API:列出作用于目的 endpoint 的
NetworkPolicy / CiliumNetworkPolicy;核对
endpointSelector / ingress.from
是否真选中源身份。集群策略(若启用 KCNP 等,v1.20
叙述含集群级策略能力)与命名空间策略叠加时,以实际生效层为准,不要只读租户
YAML。
Map:cilium-dbg policy get
/ policy selectors 类命令(以 v1.20 命令名为准)确认
selector 选中了哪些 identity。官方 policymap pressure
文档要求:压力高时找出选中 identity 最多的 selector——过宽的
/32 CIDR 列表是经典元凶。
Identity:cilium-dbg identity get <id>
核对标签是否仍符合你以为的「app=foo」。若标签对、仍
deny,是规则缺口;若标签不对,进轴三。
不要先做:把
policyEnforcementMode
改成永不执行当长期方案;在未理解 identity 前用 IP
例外「临时放行」并写进生产基线。
四、轴三:Identity 漂移
症状
- 滚动发布、改标签、改 ServiceAccount 后的短暂拒绝或短暂误放行。
- 稍后自愈;复盘时策略 YAML「看起来一直是对的」。
- 多集群时:本集群已新身份,远端节点尚未学会(第 11 篇)。
机制要点
安全身份分配与传播依赖 agent 与(视模式)kvstore/CRD 路径。官方 troubleshooting 写明:新 workload 若复用已知 identity,细节仍可能待传播;其他节点在学会之前,可能出现策略丢包。这不是「BGP 收敛」同构问题,但是同一类控制面传播窗口。
标签变更导致 identity 重新分配 时,旧 identity 的允许规则与新 identity 之间存在窗口:源已用新 ID 发包,目的策略 map 仍按旧 ID 编写,或反之。
核对路径
时间线:对齐「标签/SA 变更时间」与「失败窗口」;无对齐则不要轻易定轴三。
Metrics:policy_implementation_delay
是否在变更后升高。
Identity 列表:变更前后
identity list 中相关标签是否出现新 ID;旧 ID
是否仍被引用。
ClusterMesh:远端是否具备
io.cilium.k8s.policy.cluster
等标签的身份;官方要求在 Cilium pod 内验证远端 identity
可见。
不要先做:把偶发 deny 当成「改严了策略」而放松生产策略;忽略窗口、只加长应用重试当唯一修复。
工程间隙
论文与产品文常强调「identity 相对 IP 更稳定」。生产上稳定的是标签意图,不是数字 ID 永不改号。排障口语应说「身份代际窗口」,不要说「identity 绝对不变」。
五、轴四:Service 黑洞
症状
curl PodIP:port成功,curl ClusterIP:port失败或间歇失败。- EndpointSlice 为空,或后端 Pod 未 Ready,但 DNS 仍返回 ClusterIP。
- 启用 kube-proxy 替代(KPR)后,与残留 iptables/IPVS 规则双轨(第 6 篇)。
核对路径
API:kubectl get endpointslices
/ endpoints;后端是否具备正确 ready
条件;选择器是否仍匹配。
Map:cilium-dbg bpf lb list(及服务相关子命令)查看
BPF LB
映射是否指向预期后端。空后端时黑洞是机制结果,不是「DNS
坏了」。
KPR 模式:确认 Helm/配置中
kubeProxyReplacement 与集群是否仍运行
kube-proxy。官方曾修过「KPR 关闭时误拦 LoadBalancer
VIP」一类问题——双轨时先画谁拥有该
VIP,再改参数。
路径差异:NodePort / externalTrafficPolicy / DSR / Geneve 等组合改变入口节点与回程;同节点与跨节点表现不一致时,对照第 5–6 篇路径,而不是只看策略。
不要先做:在未确认 EndpointSlice 前重启全部后端;把 Service 黑洞写成 NetworkPolicy(除非 Hubble 已显示 deny)。
六、轴五:加密失败
症状
- 启用透明加密后跨节点失败,同节点成功。
cilium status中 Encryption 摘要异常,或摘要 OK 但特定路径未加密/未解密。- 与 Gateway/Ingress、host routing、CNI chaining 组合时出现静默黑洞(社区 issue 显示特定组合下 Hubble 甚至看不到 drop——此时更依赖路径表与 encrypt 状态,而不是只等 Policy denied)。
核对路径
Status:cilium-dbg encrypt status(及文档中的
WireGuard/IPsec 检查)确认密钥分发与链路。
路径表:对照官方 Transparent Encryption 文档——Pod→Pod、经 Service、经 L7 proxy、Egress Gateway、native vs overlay、是否 node-to-node 加密,并非同一开关覆盖一切。路径不应加密却期望加密、或应加密却走了未封装路径,都会表现为「偶发通」。
与第 9 篇对齐:WireGuard 与 IPsec
的失败方言不同;IPsec 还涉及 xfrm
状态(cilium-dbg encrypt dump-xfrm 一类)。站内
WireGuard 系列
补协议内核;本轴只定「Cilium 是否按表封装」。
组合风险:云上 CNI chaining + native routing + node encryption + Gateway 的历史回归说明——南北向入口与东西向加密叠在同一节点时,排障要同时开第 15 篇边界意识:先确认包有没有进预期 hook。
不要先做:永久关闭加密当作「修好了」却不写威胁模型变更;在未确认路径前调整 MTU「碰运气」而不记录。
七、跨轴误判与最小证据包
| 误判 | 实际常属 |
|---|---|
| 「一定是 NetworkPolicy」 | 轴四空后端;轴五加密;轴一 CT 满 |
| 「一定是 DNS」 | ClusterIP 通、FQDN 不通才偏 DNS;反过来查 Service |
| 「Cilium 坏了」 | status 绿时更可能是意图对象与 map 不一致 |
| 「重试能好就是闪断网络」 | 轴三 identity 窗口的经典表象 |
事故关闭前保留最小证据包(可进 postmortem):
- 事故时间窗与变更单(标签、CNP、Service、加密开关)。
- 一则 Hubble 事件(含 identity 与
verdict/reason)或明确「无 drop 事件」陈述。
- 相关
cilium status/ encrypt /bpf lb之一的本环境摘录(可删减,须标注)。
- 选定的轴与否证记录(试过什么、排除了什么)。
八、谱系、争论与开放问题
谱系
排障坐标系继承两类传统:(1)可编程数据面把失败从「iptables 链计数」推进到 map 查找与 verdict(XDP/eBPF 系谱见第 12 篇引用);(2)零信任/身份导向策略把「IP 是否在名单」推进到「工作负载身份是否匹配」——工程上落地为 Cilium numeric identity,而不是每包带完整证书。站内产品篇强调后一点;本篇强调窗口与传播使身份模型仍有运维税。
争论:默认拒绝窗口是否可接受
A 侧:严格默认拒绝 + 快速 identity
传播,安全上优于短暂误放行。
B 侧:滚动发布期间的短暂 deny 破坏
SLO,应允许有界的 stale-allow 或更积极的预热。
双方都有生产拥趸;本系列不站队,只要求 ADR
写明:窗口期间优先保证什么——保密性还是可用性,并配套第
12 篇指标。
开放问题
- 静默黑洞(无 Hubble
drop)的可观测完备性:在 host legacy routing / 加密
/ Gateway 组合下,能否保证失败必留
reason?可检验:复现社区报告的组合,比较 monitor、metrics
与包捕获。
- identity
窗口的可测量上限:在固定节点数与标签变更速率下,deny
窗口 P99
能否纳入发布门禁?入口:
policy_implementation_delay+ 合成探测。
参考资料
官方文档(A 级)
- Cilium v1.20 — Operations / Troubleshooting(Policy denied、policymap pressure、identity 同步、Hubble)
- Cilium v1.20 — Transparent Encryption(WireGuard / IPsec 路径表)
- Cilium v1.20 — Network Policy / Identity 概念文档
- 源码 tag
v1.20.0:
bpf/、pkg/policy/、pkg/identity/
站内对照
实验台账
- 无伪造 flow;五轴为机制分诊。真实集群上应按轴采集证据包后再写进 runbook。
→ 上一篇:可观测 · 系列目录 · 下一篇:对照替代路径
读完这篇,下一步读什么
优先读同系列或同问题的下一篇,把单篇消费变成主题集群。
Cilium / eBPF 数据面内核:从 Identity 到包路径
补齐站内 Cilium 产品单篇与 eBPF 内核实现之上的数据面内核层:Endpoint/Identity、BPF 挂载与 Map、东西向包路径、kube-proxy 替代、策略编译、Hubble、加密与 Mesh/ClusterMesh 边界,并以排障与选型收束。
【Cilium / eBPF】数据面全景:五轴坐标系与 16 篇路线
相对 k8s-network/13、ebpf/ 与 Envoy/HAProxy 排除树,钉清 Cilium eBPF 数据面内核缺口;定义 Identity、BPF 挂载、Map 状态、包路径、策略与观测五条坐标系,给出 16 篇阅读路线。
【Cilium / eBPF】Endpoint 与 Identity:数字身份、标签选择与生命周期
钉清 Cilium Endpoint 与 Numeric Identity 的关系:安全相关标签如何导出集群范围数字身份、保留身份与 well-known 身份、标签变更时的短暂 deny/allow 窗口,以及相对 IP 策略消除了什么。
【Cilium / eBPF】策略编译:NetworkPolicy 到 BPF 与默认拒绝窗口
拆解 Cilium v1.20 如何把 Kubernetes NetworkPolicy / CiliumNetworkPolicy 经 selector→identity 蒸馏进 endpoint policy map;钉死按方向的 default-deny 切换、Deny 优先与 identity 漂移造成的短暂拒绝/放行窗口。