Cilium 身份迁移实战:`cilium-dbg preflight migrate-identity` 原理、参数与 KVStore→CRD 升级路径 📅 发布时间:2026/9/13 3:29:36 👁 浏览次数: Cilium 身份迁移实战cilium-dbg preflight migrate-identity原理、参数与 KVStore→CRD 升级路径【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/ciliumcilium-dbg preflight migrate-identity是 Cilium 提供的身份security identity迁移工具用于将 KVStore 中存储的身份数据迁移为 Kubernetes CRDCiliumIdentity形态从而支撑集群从 kvstore 身份分配模式平滑切换到 CRD 模式。本文基于当前仓库源码 preflight_identity_crd_migrate.go 与该命令的 cmdref 文档内容完整讲解命令的用途、参数、迁移算法与冲突处理策略并给出该命令已被官方废弃后的推荐替代方案——Double Write 双写身份分配模式的四阶段升级流程。一、命令定位KVStore 身份 → CRD 身份的迁移器在 Cilium 中每个 endpointPod、节点等都会被分配一个数值型的 security identity用于标识其安全属性标签集合是策略执行的基础。身份的分配可以存储在键值存储如 etcd下文称 kvstore中也可以存储在 Kubernetes CRDciliumidentity.cilium.io中。两种存储形态对应不同的运行模式kvstore 模式与 CRD 模式。当集群需要从 kvstore 模式升级到 CRD 模式时最核心的风险是身份数值不一致如果新模式下为已有标签集合分配了与旧模式不同的数值 ID那么在升级过程中运行中的连接会因两端身份数值不匹配而被中断。migrate-identity子命令正是为解决这一问题而生的预检preflight工具。根据 preflight_identity_crd_migrate.go 中命令的Long描述其设计目标是允许在最小化连接中断的前提下迁移到 CRD 支撑的身份。它会对 kvstore 中定义的每个 cilium security identity分配一个相同数值的 CRD-backed identity。当 cilium-agent 以identity-allocation-modecrd重启后新实例与未升级实例之间的数值身份将保持一致。在数值身份已被一组不同标签占用的场景下会创建一个新的数值身份。也就是说该工具的本质是预先在 CRD 侧占位在 Agent 正式切换到 CRD 模式之前把所有 kvstore 中存在的 ID→标签映射逐一复制到 CRD 中让两端身份数值对齐从而避免升级瞬间的大规模重新分配。命令挂在cilium-dbg preflight命令组下与 validate-cnp校验集群中已部署的 Cilium Network Policy并列二者共同构成cilium-dbg preflightCilium upgrade helper见 preflight.go这一升级辅助 CLI。二、命令用法与参数详解命令在当前仓库源码中的定义如下preflight.gofunc init() { // From preflight_migrate_crd_identity.go miCmd : migrateIdentityCmd() miCmd.Flags().StringVar(kvStore, kvstore, , Key-value store type) miCmd.Flags().Var(option.NewMapOptions(kvStoreOpts), kvstore-opt, Key-value store options e.g. etcd.address127.0.0.1:4001) PreflightCmd.AddCommand(miCmd) PreflightCmd.AddCommand(validateCNPCmd()) RootCmd.AddCommand(PreflightCmd) }2.1 完整命令形式cilium-dbg preflight migrate-identity \ --kvstore type \ --kvstore-opt option2.2 专有参数参数类型默认值说明--kvstorestring空键值存储类型例如etcd--kvstore-optmap空键值存储选项例如etcd.address127.0.0.1:4001可多次指定这两个参数用于建立到旧 kvstore 的连接--kvstore声明存储后端类型--kvstore-opt以keyvalue形式传入该后端的连接配置地址、凭据等。工具会依据此配置初始化 kvstore 客户端并读取其中的身份数据见下文initKVStore。2.3 继承自父命令的全局参数migrate-identity作为cilium-dbg的子命令同样接受父命令的全局参数见 cilium-dbg preflight 文档参数说明--config string配置文件默认$HOME/.cilium.yaml-D, --debug开启调试消息-H, --host stringserver 端 API 的 URI--log-driver strings日志输出端点例如syslog--log-opt map日志驱动选项例如formatjson2.4 已弃用状态当前仓库源码中该命令已被标记为弃用preflight_identity_crd_migrate.goDeprecated: Deprecated in favor of the Double Write identity allocation modes, that support gradual migration in live clusters and rollbacks.同时 upgrade-next.inc下一版本升级说明也明确写道cilium-dbg preflight migrate-identity工具已弃用并计划在后续版本中移除。请参考kvstore_to_crd_migration章节了解如何利用 Double Write 身份分配模式完成从 KVStore 到 CRD 身份分配模式的迁移。因此在生产环境新部署中应优先采用第五节的 Double Write 方案本文后续的算法剖析仍然具有理解价值因为 Double Write 的收敛目标CRD 与 KVStore 身份一致与 migrate-identity 的迁移目标完全一致。三、迁移工作原理源码级流程剖析migrateIdentityCmd()通过 Cilium Hive 框架组装依赖k8s 客户端、集群信息、BGP 配置等启动后调用migrateIdentities()执行核心逻辑。源码注释preflight_identity_crd_migrate.go给出了明确的步骤设计1- 通过 pkg/allocator.Backend 连接 kvstore 2- 连接 k8s a- 若 ciliumidentity CRD 缺失则创建之 3- 遍历 kvstore 中的每个 identity a- 尝试为每个 key 分配相同的数值 ID b- 已分配且 ID→key 匹配的身份直接跳过 c- kvstore ID 与 CRD 冲突的身份用不同的 ID 分配3.1 强制 CRD 分配模式迁移的第一步是强制身份分配模式为 CRDpreflight_identity_crd_migrate.gooption.Config.IdentityAllocationMode option.IdentityAllocationModeCRD // force CRD mode to make ciliumid所有身份分配模式的合法取值定义在 pkg/option/config.go模式常量命令行取值含义IdentityAllocationModeKVstorekvstore身份仅存于键值存储IdentityAllocationModeCRDcrd身份仅存于 Kubernetes CRDIdentityAllocationModeDoubleWriteReadKVstoredoublewrite-readkvstore同时写入 kvstore 与 CRD从 kvstore 读取IdentityAllocationModeDoubleWriteReadCRDdoublewrite-readcrd同时写入 kvstore 与 CRD从 CRD 读取3.2 双后端初始化迁移同时初始化两个身份后端kvstore 后端initKVStorepreflight_identity_crd_migrate.go基于--kvstore/--kvstore-opt建立连接将身份路径拼接为kvstore.JoinKey(cache.IdentitiesPath, id)构造 kvstore allocator 后端CRD 后端initK8spreflight_identity_crd_migrate.go先通过ciliumClient.CreateCustomResourceDefinitions()确保ciliumidentityCRD 存在再创建 CRD 后端与一个真正的 allocatorallocator 的 ID 范围取自集群信息cinfo.MinimalAllocationIdentity()与cinfo.MaximumAllocationIdentity()并WaitForInitialSync等待与 CRD 的初始同步完成。每个操作步骤列表、分配、获取身份的完成时限为opTimeout 30 * time.Secondpreflight_identity_crd_migrate.go。3.3 快照语义与身份列举迁移开始时工具会一次性列出 kvstore 中的全部身份getKVStoreIdentitiespreflight_identity_crd_migrate.go其语义是启动时快照身份在启动时被快照迁移期间新创建的身份不会被看到。实现上通过kvstoreBackend.ListAndWatch注册kvstoreListHandler回调OnUpsert/OnListDone/OnDelete初始列表完成后关闭listDone通道并取消 watcher若在 30 秒内未完成列表则返回 Timeout while listing identities 错误。由于迁移期间新身份不可见官方建议在迁移窗口内避免大量新建 endpoint。3.4 逐一迁移与冲突处理主循环遍历kvstoreIDs中的每个id → keypreflight_identity_crd_migrate.go调用crdBackend.AllocateID(ctx, id, key)尝试按原数值 ID 分配若返回k8serrors.IsAlreadyExistsID 已被占用将id → key记入alreadyAllocatedKeys等待第二阶段处理若发生其他错误记录 Cannot allocate CRD ID. This key will be allocated with a new numeric identity即该 key 稍后会被分配一个新 ID成功则记录 Migrated identity。第二阶段专门处理 ID 冲突preflight_identity_crd_migrate.go通过crdBackend.GetByID查证冲突 ID 在 CRD 中实际对应的 key相同 ID 且相同 key可能来自上一次运行的残留记录 ID was already allocated to this key. It is already migrated视为已迁移跳过相同 ID 但不同 key数值 ID 已被另一组标签占用这是最需要警惕的情况记录 Warn ID is allocated to a different key in CRD. A new ID will be allocated for the this key随后调用crdAllocator.Allocate(ctx, key)为该 key 分配一个全新的数值 ID并输出 New ID allocated for key in CRD日志中同时给出identity-old与identity-newGetByID 返回错误无法确认是否同一 key记录 ID already allocated but we cannot verify whether it is the same key. It may not be migrated跳过GetByID 返回 nilkey 不存在按不匹配处理走新 ID 分配分支。3.5 使用前提源码注释明确假设迁移发生在 k8s 到 k8s 的安装之间preflight_identity_crd_migrate.go非 k8s 模式下身份 key 的标签形态不同该工具不适用。同时工具会破坏 同一时刻仅一个 backend 处于活跃状态 的常规假设迁移期间 kvstore 与 CRD 两个后端同时被写入因此只应在升级维护窗口内、按照预检流程使用。四、执行前置条件与运行提示需要可用的 kubeconfig工具通过 Hive 的 k8s client cell 连接集群用于创建/校验CiliumIdentityCRD 并执行分配需要可到达的 kvstore通过--kvstore/--kvstore-opt提供的连接信息访问旧身份库读取全部身份快照幂等性重复执行时已迁移且 ID→key 一致的条目会被自动跳过already migrated 分支因此可以安全重跑迁移窗口选择由于快照语义建议在身份变更不频繁的维护窗口执行迁移完成后立即按新模式重启 Agent。五、推荐替代方案Double Write 四阶段迁移由于migrate-identity是离线一次性工具需要停机窗口、无法回滚官方在 Documentation/operations/upgrade.rst 中给出了更完善的替代方案——Double Write 身份分配模式支持在线集群中渐进迁移与快速回滚。5.1 高层迁移计划起点Cilium 运行在纯 KVStore 模式切换为doublewrite-readkvstore与纯 KVStore 模式几乎一致唯一区别是所有身份会同时以 CRD 形式复制一份但读取仍走 kvstoreCRD 副本暂不使用切换为doublewrite-readcrd读取改从 CRD 进行等价于纯 CRD 模式但身份仍持续写入 kvstore从而保留快速回滚的余地切换为纯crd模式不再使用 kvstore可下线 KVStore。在步骤 2、3 任一阶段都可快速回滚。该流程同样适用于反向迁移CRD → KVStore只需逆序执行。5.2 滚动部署指令先重新部署 Operator再重新部署 Agent均使用--identity-allocation-modedoublewrite-readkvstore监控 Operator 指标与日志确认 KVStore 与 CRD 之间所有身份已收敛。相关指标Operator 在 Double Write 模式下额外发出cilium_operator_identity_crd_total_count/cilium_operator_identity_kvstore_total_countCRD 与 KVStore 中的身份总数cilium_operator_identity_crd_only_count/cilium_operator_identity_kvstore_only_count仅存在于单侧的身份数用于发现不一致需要进一步排查时Operator 日志会输出 KVStore 与 CRD 身份差异的详细信息注意KVStore 与 CRD 身份的垃圾回收时机略有不同在--identity-gc-interval与--identity-heartbeat-timeout设置下指标短期内可能出现差异属正常现象身份全部收敛后将 Operator 与 Agent 重新部署为--identity-allocation-modedoublewrite-readcrdCilium 将只从 CRD 读取、仍向 KVStore 写入确认稳定后先 Agent 后 Operator 切换为--identity-allocation-modecrdCilium 完全以 CRD 读写身份此时即可下线 KVStore。对比而言migrate-identity是在切换前用离线命令把身份搬过去而 Double Write 是在运行期间由 Operator 持续双向复制身份靠指标确认收敛后原地切换——后者对在线业务的影响面更小、可观测性更强、且支持回滚这正是其取代前者成为官方推荐路径的原因。六、小结cilium-dbg preflight migrate-identity是理解 Cilium 身份分配模式演进的绝佳切入点它把KVStore 身份库 → CRD 身份库的迁移浓缩为一次可重跑的离线命令核心算法按原 ID 分配、冲突时降级为新 ID清晰地映射了身份迁移的本质矛盾——数值 ID 是共享资源跨存储迁移必须保证 ID→标签映射的收敛一致。结合当前仓库的 Double Write 双写模式与配套 Operator 指标读者可以在在线集群中实现渐进、可回滚的 KVStore→CRD 身份迁移或在阅读源码时快速定位到 preflight_identity_crd_migrate.go 的对应实现。【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/cilium创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考