ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Cilium bpf ipcache delete 手动删除条目:clusterid 不匹配时你会得到 ENOENT

2026/9/13 18:28:53 拓冰建站 浏览量
Cilium bpf ipcache delete 手动删除条目:clusterid 不匹配时你会得到 ENOENT Cilium bpf ipcache delete 手动删除条目clusterid 不匹配时你会得到 ENOENT【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/ciliumClusterMesh 某个节点上一个 Pod 的流量本应被策略放行却被持续 drop排查后发现是 IPCache 里残留了一条指向错误身份的脏条目。Cilium 的cilium-dbg bpf ipcache delete就是用来把这类 IP—身份映射从内核cilium_ipcache_v2映射里精确摘除的命令本文从语法一路拆到 map 里的键字节。先交代两个概念。IPCache是 Cilium 数据路径上记录IP/CIDR 前缀 → 安全身份Identity基于标签生成的数字编号策略判定只看它而不看 IP与隧道端点的eBPF内核中可编程的字节码运行框架这里指内核里的一张映射表映射它在内核中是一棵LPM Trie最长前缀匹配树内核为按前缀查 IP优化的查找结构。转发路径上的每个包都要查它所以删一条条目直接影响转发与策略行为。命令速查卡delete 的语法与最小可运行示例项目内容命令格式cilium-dbg bpf ipcache delete PREFIX [--clusterid N]必填位置参数IP/CIDR 前缀必须携带前缀长度/32、/128等可选 flag--clusteriduint16默认 0表示本集群权限要求root且必须在 Cilium Agent 所在的节点上执行典型成功输出Deleted entry 10.244.3.110/32clusterid 非 0 时输出Deleted entry 10.244.3.110/321前置条件root 权限本节点有运行中的 Cilium Agentmap 以 pinning 方式固定在内核 BPF 文件系统下可被用户态进程反复打开Cilium 数据路径已就绪。命令直接操作本地内核 map不需要连接 Agent API。# 删除前先确认条目存在及其真实键形态建议养成习惯 cilium-dbg bpf ipcache match 10.244.3.110/32 # 删除本集群的一条 /32 条目 cilium-dbg bpf ipcache delete 10.244.3.110/32帮助文档把二进制名登记为cilium-dbg而代码内示例用的是旧名cilium bpf ipcache delete 10.244.3.110/32 --clusterid 1两者指向同一实现见 Documentation/cmdref/cilium-dbg_bpf_ipcache_delete.md。参数拆解delete 的 flag 如何参与键构造delete 专属 flagflag 名类型功能对底层键/值的实际影响--clusteriduint16指定条目所属集群默认 0直接写入键的ClusterID字段与 prefix 一起决定键的完整字节序列不匹配则删不到任何条目-h, --helpbool显示 delete 帮助无--clusterid在 cilium-dbg/cmd/bpf_ipcache_delete.go 第 20 行通过PersistentFlags().Uint16(clusterid, 0, Cluster ID)注册。继承自父命令的全局 flagflag 名类型功能对 delete 的实际影响--configstring指定配置文件默认$HOME/.cilium.yaml读取全局配置-D, --debugbool开启调试日志仅影响日志输出-H, --hoststring指定 server-side API 地址对 delete 不生效它不走 API直接操作内核 map--log-driverstrings日志后端如 syslog仅影响日志输出--log-optmap日志驱动参数如formatjson仅影响日志输出位置参数只接受 CIDR不接裸 IP实现中用netip.ParsePrefix(arg)解析位置参数cilium-dbg/cmd/bpf_ipcache_delete.go 第 41-44 行。合法输入IPv410.244.3.110/32、10.0.0.0/8IPv6fd00::a0/128、fd00::/64会被拒绝的输入裸 IP10.244.3.110缺前缀长度报Invalid prefix address.不存在的参数报No prefix provided.第 30-32 行超出地址族上限的前缀长度如 IPv4 的/33动手演练从本集群 /32 到带 clusterid 的远端条目场景一先 match 再 delete 的三步验证法准备——用list与match确认目标键真实存在并记下输出形态cilium-dbg bpf ipcache list | grep 10.244.3.110 # IP PREFIX/ADDRESS IDENTITY # 10.244.3.110/32 identity6 encryptkey0 tunnelendpoint172.21.0.2 flagshastunnel cilium-dbg bpf ipcache match 10.244.3.110/32 # key 10.244.3.110/32 has value identity6 encryptkey0 tunnelendpoint172.21.0.2 flagshastunnel执行cilium-dbg bpf ipcache delete 10.244.3.110/32 # Deleted entry 10.244.3.110/32注意 clusterid 为 0 时键的String()不输出0后缀这是正常现象见 pkg/clustermesh/types/addressing.go 第 372-377 行。验证——再次match应查无此键退出码 1cilium-dbg bpf ipcache match 10.244.3.110/32 # 10.244.3.110/32 does not match to any ipcache entry场景二删远端集群条目clusterid 必须带上ClusterMesh 同步来的条目list输出里键会带N后缀N 即写入时的 clusteridcilium-dbg bpf ipcache list | grep # 10.244.3.110/321 identity6 encryptkey0 tunnelendpoint10.1.2.3 flagshastunnel,remotecluster执行时 clusterid 必须与后缀一致cilium-dbg bpf ipcache delete 10.244.3.110/32 --clusterid 1 # Deleted entry 10.244.3.110/321失败演示——漏掉--clusterid时构造出的键 cluster_id0与 map 中1的键字节不等cilium-dbg bpf ipcache delete 10.244.3.110/32 # Error deleting entry 10.244.3.110/32: no such file or directory这个no such file or directory就是内核 BPF 删除不存在的键时返回的 ENOENT。场景三与 update 组合做写入-确认-删除-确认闭环update支持--tunnelendpoint、--identity、--encryptkey、--skiptunnel、--clusteridcilium-dbg/cmd/bpf_ipcache_update.go 第 20-24 行两者共用同一个NewKey是验证删除语义最干净的组合# 1) 写入10.244.3.110/32 归属 identity 6隧道端点 172.21.0.2 cilium-dbg bpf ipcache update 10.244.3.110/32 \ --tunnelendpoint 172.21.0.2 --identity 6 --encryptkey 255 --clusterid 0 # Updated entry 10.244.3.110/32 identity6 encryptkey255 tunnelendpoint172.21.0.2 flagshastunnel # 2) 确认写入 cilium-dbg bpf ipcache match 10.244.3.110/32 # key 10.244.3.110/32 has value identity6 encryptkey255 tunnelendpoint172.21.0.2 flagshastunnel # 3) 删除 cilium-dbg bpf ipcache delete 10.244.3.110/32 --clusterid 0 # Deleted entry 10.244.3.110/32 # 4) 按 IP 做最长前缀匹配复查get 接收裸 IP遍历全部键取最长命中前缀 cilium-dbg bpf ipcache get 10.244.3.110 # 10.244.3.110 does not map to any identity排障速查现象 → 根因 → 处理现象根因处理⚠️Error deleting entry ...: no such file or directory前缀或 clusterid 与真实键不符ENOENT先list看键的真实形态含N后缀按原键重删Invalid prefix address.传了裸 IP 或前缀长度非法补/32、/128IPv4 前缀长度 ≤32No prefix provided.未传位置参数补上 CIDR 参数Please run cilium bpf ipcache delete command(s) with root privileges.非 root 执行sudo后重试删除后条目又长回来Agent 依据自身状态endpoint 同步、ClusterMesh 同步自动重写手动删除只算临时修正应回头找脏数据源头源码链路从 root 校验到 LPM Trie 删键delete 的全部逻辑在 cilium-dbg/cmd/bpf_ipcache_delete.go 第 27-53 行执行链如下cilium-dbg bpf ipcache delete 10.244.3.110/32 --clusterid 1 │ ▼ common.RequireRootPrivilege(cilium bpf ipcache delete) 校验 os.Getuid() 0否则打印错误并 exit(1) │ pkg/common/utils.go 第 71-76 行 ▼ 校验位置参数len(args) 1 或 args[0] 失败 → No prefix provided. 用法提示 │ ▼ cmd.Flags().GetUint16(clusterid) │ ▼ netip.ParsePrefix(arg) 失败 → Invalid prefix address. 用法提示 │ ▼ ipcache.NewKey(prefix, clusterID) 构造 BPF 键Prefixlen staticPrefixBits prefix.Bits() ClusterID --clusterid Family 由地址族自动识别 IP 拷入 16 字节字段IPv4 存低 4 字节 │ ▼ ipcache.IPCacheMap(nil) sync.Once 单例打开名为 cilium_ipcache_v2 的内核 map │ ▼ map.Delete(key) BPF 系统调用删除精确键LPM Trie 的删除不级联 只删掉与所给键字节完全一致的那一条 │ ├─ 成功stdout Deleted entry %s键的 String() 形式 └─ 失败stderr Error deleting entry %s: %vexit(1)键结构与 staticPrefixBits 的作用Go 侧键定义pkg/maps/ipcache/ipcache.go 第 35-42 行源码注释要求它与 C 侧struct ipcache_key保持同步type Key struct { Prefixlen uint32 align:lpm_key // LPM 前缀长度含 staticPrefixBits 偏移 ClusterID uint16 align:cluster_id // ClusterMesh 集群编号 Pad1 uint8 align:pad1 Family uint8 align:family // 区分 IPv4 / IPv6 IP types.IPv6 align:$union0 // 16 字节IPv4 存低 4 字节 }C 侧同名结构在 bpf/lib/eps.h 第 108-117 行map 本身声明为BPF_MAP_TYPE_LPM_TRIE即cilium_ipcache_v2同文件第 120-127 行。staticPrefixBits是关键编码pkg/maps/ipcache/ipcache.go 第 44-46 行它等于整个键除去Prefixlen与IP字段之外的字节数 × 8。本键共 24 字节减去 4 字节Prefixlen与 16 字节IP得(24-4-16)*8 64位。因此写入 map 的前缀长度是64 用户前缀位数IPv4 的/32条目实际Prefixlen 96IPv6 的/128条目是192。这个偏移意味着LPM Trie 参与匹配的前 64 位里包含了 cluster_id 与 family——内核按64 个静态位 N 个 IP 位整体做最长匹配所以 clusterid 或地址族差一位查找与删除都命中不了。C 侧用宏IPCACHE_STATIC_PREFIX算同一个值bpf/lib/eps.h 第 130-133 行数据路径的ipcache_lookup4/6也是按这套编码构造键再map_lookup_elem第 137-164 行。你在用户态删掉的键正是内核转发路径正在引用的那个键一一对应。值结构删掉一条条目到底删了什么值类型RemoteEndpointInfopkg/maps/ipcache/ipcache.go 第 154-161 行type RemoteEndpointInfo struct { SecurityIdentity uint32 // 安全身份策略判定依据 TunnelEndpoint types.IPv6 // 远端隧道端点IPv4 存低 4 字节 _ uint16 Key uint8 // IPsec 加密密钥编号 Flags RemoteEndpointInfoFlags // 位标志 }Flags的四个位第 136-150 行FlagSkipTunnel该端点不走 VXLAN/Geneve 隧道、FlagHasTunnelEndpoint隧道端点非空、FlagIPv6TunnelEndpoint隧道端点是 IPv6、FlagRemoteCluster节点属于远端集群。也就是说 delete 删掉的不止一个 IP 记录而是同时摘除了该前缀的身份归属与隧道封装决策——前缀在 map 里查不到身份后策略与转发都会按未知端点路径处理。生产环境执行前应先想清楚这个后果。map 单例、名称与容量上限单例IPCacheMap用sync.Once保证每个 Agent 进程只初始化一份pkg/maps/ipcache/ipcache.go 第 223-238 行名称常量Name cilium_ipcache_v2第 29 行按名 pin 进内核cilium-dbg打开的就是 Agent 固定的同一张 map容量MaxEntries 512000第 26 行即最多约 51.2 万条前缀映射写权限map 创建时带BPF_F_NO_PREALLOC | BPF_F_RDONLY_PROG第 205-213 行——eBPF 程序侧只读用户态可写这正是 Agent 与 cilium-dbg 都能改这张 map 的原因。边界与避坑delete 之前先把键看清楚如果……就会……如果删远端集群条目时不带--clusterid就会构造出 cluster_id0 的键与 map 中N键字节不等得到 ENOENT而真实条目原封未动如果位置参数传裸 IP不带/32netip.ParsePrefix直接失败报Invalid prefix address.命令不进入删除流程如果条目正被 Agent 依赖endpoint 仍在线、ClusterMesh 仍在同步删掉后 Agent 会很快依据自身状态重写它手动删除解决不了反复出现要先找上游状态源如果该前缀仍有活跃流量删除会立即改变数据路径的身份判定与隧道封装可能表现为连接被 drop 或绕行操作前用get确认这个 IP 当前解析到哪个 identity如果不在 Cilium Agent 所在节点上执行删多少次都无效——命令只作用于本地内核 map继承来的-H/--host对 delete 不起作用。操作前检查清单✅list/match确认条目存在记下完整键含N后缀与 identity 值 ✅ 对关键前缀用get记录删除前的解析结果作为回退参照 ✅ 执行delete prefix --clusterid NN 与键后缀一致 ✅ 再match一次确认键已消失必要时get复查解析结果边界一句话正常路径上 IPCache 由 Agent 自动维护手动 delete 仅限排障、测试与纠正脏数据。一句话带走IPCache 是网络层地址与安全身份之间那座桥delete 只是拆掉桥上某块砖——桥还在Agent 还会把砖按状态重新砌回去。【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/cilium创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考