Cilium BGP Control Plane 深度解析:架构、启用方式与源码实现
发布时间:2026/9/15 1:30:44 锦皓数字建站

Cilium BGP Control Plane 深度解析架构、启用方式与源码实现【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/ciliumCilium BGP Control Plane 是 Cilium 中基于 Border Gateway Protocol 为核心骨架结合pkg/bgp、operator/pkg/bgp等源码带你完整理解 BGP Control Plane 的启用开关、Agent-Side / Operator-Side 双控制平面架构、Controller 控制循环、Manager 声明式接口以及 ConfigReconciler 调和机制最终掌握如何在真实集群中启用并排障。BGP Control Plane 能做什么、不能做什么BGP Control Plane 提供了一种让 Cilium 通过 BGP 协议向连接的路由器通告路由的方式。它的核心价值在于让Pod 网络Pod CIDR在集群外部的物理路由器上可见从而打通集群内外的二层/三层网络让LoadBalancer类型 Service 的 IP通过 BGP 通告给上游路由器无需依赖云厂商的负载均衡器即可实现裸金属 自建 LB IP场景这也是 MetalLB 类方案所解决的同类问题。但需要特别强调它的能力边界BGP Control Plane 不编程 datapath数据路径它只负责向路由器通告集群内有哪些路由可达而不参与数据包的转发与策略执行。因此不要使用 BGP Control Plane 来建立集群内部节点之间的可达性——集群内部的数据转发仍然由 Cilium 的 eBPF datapath 负责参见 Cilium 网络与 eBPF 相关文档。换句话说BGP Control Plane 是对外广播的控制面组件而 eBPF datapath 才是对内转发的数据面二者职责互补、不可互相替代。启用 BGP Control Plane目前在Cilium Agent中通过单个开关标志即可启用整套 BGP Control Plane 功能--enable-bgp-control-planetrue该标志对应的源码定义位于 pkg/bgp/config/config.go// Flag to enable BGP control plane features EnableBGPControlPlane enable-bgp-control-plane当设置为true时BGP Control Plane 的Controller会被实例化并开始监听CiliumBGP*系列 CRD 资源上的事件。从 pkg/bgp/cell.go 可以看出所有 BGP 相关资源CiliumBGPNodeConfig、CiliumBGPPeerConfig、CiliumBGPAdvertisement、Secret、CiliumPodIPPool的 informer 都会在开关关闭时返回nil保证 hive 依赖图静态稳定、不执行任何额外工作func newBGPNodeConfigResource(...) resource.Resource[*v2.CiliumBGPNodeConfig] { // Do not create this resource if the BGP Control Plane is disabled if !bc.BGPControlPlaneEnabled() { return nil } ... }同样地pkg/bgp/agent/controller.go 中的NewController在开关关闭时直接返回nil, nil且不向生命周期追加任何任务。相关配置项一览除了主开关BGPConfig还暴露了若干关联配置定义在 pkg/bgp/config/config.go配置标志默认值说明--enable-bgp-control-planefalse启用 BGP Control Plane 主开关--enable-bgp-control-plane-status-reporttrue启用 BGP Control Plane CRD 状态上报--enable-bgp-legacy-origin-attributefalse启用 LoadBalancerIP 路由通告时携带 BGP ORIGIN 属性INCOMPLETE (2)兼容 MetalLB 旧行为默认使用IGP (0)--bgp-secrets-namespace从哪个 Kubernetes namespace 读取 BGP 控制面认证 Secret为空则无法使用 BGP 认证密钥启动时会输出警告日志--bgp-router-id-allocation-modedefaultBGP router-id 分配模式支持default或ip-pool--bgp-router-id-allocation-ip-pool当分配模式为ip-pool时从中分配 router-id 的 IP 池其中 router-id 的解析逻辑可在 pkg/bgp/manager/manager.go 的getRouterID中看到完整链路优先取CiliumBGPNodeInstance中显式声明的 RouterID未声明时default模式取 CiliumNode 的节点 IP节点 IP 不可用时退化为从cilium_host设备的 MAC 地址低 4 字节计算 router-id见calcRouterIDFromMacAddress。总体架构Agent-Side 与 Operator-Side 双控制平面BGP Control Plane 在架构上被拆分为两个控制平面Agent-Side Control PlaneAgent 侧控制平面运行在每一个 Cilium Agent 中负责在本节点上实际运行 BGP 路由进程、维护 BGP 会话与路由通告Operator-Side Control PlaneOperator 侧控制平面运行在 Cilium Operator 中负责将集群级的CiliumBGPClusterConfig声明分发到每个节点。两个控制平面都遵循Kubernetes Controller 模式实现——通过 informer 监听CiliumBGP*CRD以及其他对实现 BGP 控制平面有用的 Cilium / Kubernetes 资源如CiliumNode、CiliumBGPNodeConfigOverride、CiliumBGPPeerConfig等。两者的分工关系如下Operator 侧处理CiliumBGPClusterConfigCRD 以及它引用的其他 CRDPeerConfig、Advertisement 等Operator 为集群中每个启用了 BGP 的节点创建/更新/删除对应的CiliumBGPNodeConfig每个节点上以本节点名称命名的CiliumBGPNodeConfig成为Agent 侧控制平面的主配置来源。从 operator/pkg/bgp/manager.go 中可以看到 Operator 侧BGPResourceManager同时跟踪CiliumBGPClusterConfig、CiliumBGPNodeConfigOverride、CiliumBGPNodeConfig、CiliumBGPPeerConfig与CiliumNode五类资源负责将集群配置转化为节点级配置。在 CRD 定义层面二者的关系也清晰可辨pkg/k8s/apis/cilium.io/v2/bgp_cluster_types.go 定义CiliumBGPClusterConfig集群级的 BGP 声明由用户编写pkg/k8s/apis/cilium.io/v2/bgp_node_types.go 定义CiliumBGPNodeConfig节点本地的 BGP 配置对象名称即节点名由 Cilium Operator 创建对用户只读。Agent-Side 架构详解Agent 侧控制平面由Controller、Manager、Router三个核心角色组成下面按原文档的顺序逐层深入。组件时序与控制流原文档给出了 Agent 侧控制平面控制流的高层时序图展示了Controller如何基于事件驱动完成调和reconcile实际源码中Agent 侧 Controller 监听的是本节点名对应的CiliumBGPNodeConfig事件与本地CiliumNode的 Upsert 事件收到事件后向signaler.BGPCPSignaler发送信号唤醒控制循环执行Reconcile。Controller 的事件驱动模型在 pkg/bgp/agent/controller.go 的Run方法中实现其控制循环是一个select多路复用监听CiliumNode资源事件、context 取消信号、以及Sig.Sig调和信号。架构依赖关系图原文档的架构图完整呈现了 Agent 侧各组件之间的依赖关系注意上图将触发 Controller 的 Kubernetes 事件简化为单个CiliumBGPNodeConfig事件但 Controller 实际还会被其他会影响 Agent 侧 BGP 控制平面的事件唤醒如本地CiliumNode变化完整细节请见源码。Controller事件入口与控制循环Agent 侧控制平面实现了一个 Controller位于 pkg/bgp/agent/controller.go。Controller 的工作流程为监听CiliumBGPNodeConfig事件判断该资源是否应用于当前主机——实际上 informer 在创建时就通过 field selector 固定过滤了metadata.name本节点名见 pkg/bgp/cell.go若适用则捕获 Cilium 当前状态本地CiliumNode对象的一部分信息调用BGPRouterManager接口完成配置下发。调和失败时reconcileWithRetry使用指数退避重试约 15 秒内最多 5 次见 controller.gobackoff : wait.Backoff{ Duration: 500 * time.Millisecond, Factor: 2, Jitter: 0.5, Steps: 5, }Reconcile的核心逻辑controller.go是从资源 store 中按本节点名取出CiliumBGPNodeConfig并DeepCopy一份避免调和器篡改 store 内对象随后调用BGPMgr.ReconcileInstances(ctx, bgpnc, c.LocalCiliumNode)。BGPRouterManager的完整接口定义在 pkg/bgp/agent/routermgr.go除了核心的ReconcileInstances之外还提供GetPeers、GetRoutes、GetRoutePolicies等查询类方法并保留了面向 REST API 的 Legacy 版本以及生命周期方法Stop。Manager声明式配置 APIManager是一个接口用于在Controller与实例化的 BGP 路由器之间定义声明式 API调用方只需给出期望的CiliumBGPNodeConfigManager 负责把 BGP 控制平面推向该期望状态或在无法实现时返回错误。Manager 的实现位于pkg/bgp/manager核心文件是 pkg/bgp/manager/manager.go。它的职责包括评估期望的CiliumBGPNodeConfig创建/移除期望的 BGP 路由器实例通告/撤回期望的 BGP 路由启用/禁用 BGP 服务器特定功能当节点配置无法应用时告知调用方。ReconcileInstances的实现manager.go采用了经典的 diff 三阶段流程构造reconcileDiff计算需要创建register、移除withdraw与调和reconcile的实例集合若CiliumBGPNodeConfig为nil资源被删除调用withdrawAll撤回全部实例先withdraw先撤回再注册以保证重建语义正确再register最后reconcile三者的错误通过errors.Join汇总。Manager 实现的一个重要特性是能够隔离地评估CiliumBGPNodeConfig中的每一个CiliumBGPNodeInstance。这意味着当应用一个节点配置时Manager 会逐个尝试创建每个实例某个CiliumBGPNodeInstance实例化失败时错误被记录Manager 继续处理下一个实例见 manager.go 的register方法实现单实例失败不影响其他实例的容错语义。Manager 内部原理值得展开说明 Manager 实现的内部工作机制Manager 将每个CiliumBGPNodeInstance视为一个BGP 路由器实例router instance每个CiliumBGPNodeInstance定义一个本地 ASNLocalASN、一个Router ID以及一组需要建立对等关系的邻居Neighbors列表凭借这些信息Manager 足以创建一个BgpServer实例——在 gobgp 包的术语中BgpServer即一个 BGP speaker。从源码看实例注册时会构造全局配置manager.goglobalConfig : types.ServerParameters{ Global: types.BGPGlobal{ ASN: uint32(localASN), RouterID: routerID, ListenPort: localPort, RouteSelectionOptions: types.RouteSelectionOptions{ AdvertiseInactiveRoutes: true, }, }, StateNotification: make(types.StateNotificationCh, 1), }其中ListenPort为-1时getLocalPort的默认返回gobgp 将进入非监听模式不监听 TCP 179 端口仅作为对端发起连接的 client 角色。此外 Manager 还会为每个实例启动状态通知消费协程trackInstanceStateChange把底层 BGP 实例的状态变化汇聚到bgp-state-observer作业中统一调和。ConfigReconciler顺序相关的调和器Manager 内部使用一组ConfigReconciler来执行对每个BgpServer的顺序相关调和动作。ConfigReconciler是一个接口通过Reconcile方法被调用其定义在 pkg/bgp/manager/reconciler/reconcilers.gotype ConfigReconciler interface { Name() string Priority() int Init(i *instance.BGPInstance) error Cleanup(i *instance.BGPInstance) Reconcile(ctx context.Context, params ReconcileParams) error }每个 reconciler 的优先级决定了调用顺序数字越小越先执行优先级Reconciler说明10DefaultGateway默认网关处理20Interface接口地址前缀通告30PodCIDRPod CIDR 路由通告40ServiceServiceLoadBalancer IP路由通告50PodIPPoolCiliumPodIPPool 前缀通告100RoutePolicy路由策略需在其他 reconciler 之后运行以收集它们期望的策略110Neighbor邻居配置最后运行以确保 RIB 与策略填充完毕后再添加邻居使 EOR 标记正确这些 reconciler 通过 hive 的group:bgp-config-reconciler依赖注入聚合并在GetActiveReconcilers中按优先级排序见 reconcilers.go。调和时还有一个重要的中止语义如果某个 reconciler 返回ErrAbortReconcileManager 会立即终止当前实例的调和循环并返回错误——这通常意味着基础设施尚未就绪如 store 未初始化或存在硬性的调和顺序依赖而其他普通错误则会被累积reconcileErrs并继续尝试调和尽可能多的配置见 manager.go。调和结果还会写入 statedb 的BGPReconcileError表中供cilium-dbg等工具查询并触发reconcile_errors_total与reconcile_run_duration_seconds指标。以Interfacereconciler 为例pkg/bgp/manager/reconciler/interface.go它会查询 statedb 的设备表只对管理上 up 且操作上 up 或 unknown的设备通告其全局单播地址IPv4 允许 link-local从而避免把 loopback、multicast、link-local IPv6 等无意义地址通告给邻居。Routergobgp 底层路由实现Router 层对上层暴露命令式 API用于 BGP 相关配置例如添加/移除邻居、通告/撤回路由等。目前仅支持 gobgp作为底层路由实现这一层充当Cilium 特有 BGP 类型与 gobgp 类型之间的翻译层shim。源码位于pkg/bgp/gobgp核心文件为 pkg/bgp/gobgp/server.go。从架构上看pkg/bgp/types/bgp.go 定义了厂商无关的RouterProvider与Router接口所有参数均为标准 BGP RFC 语义GoBGPServer包装了github.com/osrg/gobgp/v4/pkg/server的BgpServer实现该接口启动时默认配置了两条全局策略import 方向默认 REJECT 外部通告的路径仅放行本地路由的allow-local策略export 方向默认 REJECT 所有通告直到显式的 export 策略放行从源头保证了未经策略允许的路由绝不进 RIB、绝不出通告通过WatchEvent监听 peer 状态与路由更新事件向StateNotification通道发送信号驱动 Manager 的状态调和停止实例时区分FullDestroy发送 Cease 通知、中断 Graceful Restart与优雅停止StopBgp携带AllowGracefulRestart: true两种模式默认 Agent 退出采用后者以保留对等端的 Graceful Restart 进度。从源码看一条路由的完整通告链路综合上述组件一条LoadBalancerService IP 的路由通告链路可以概括为Operator 侧监听CiliumBGPClusterConfig与CiliumBGPAdvertisement为每个 BGP 节点生成CiliumBGPNodeConfigAgent Controller收到本节点CiliumBGPNodeConfig事件从 store 读取期望配置并调用BGPRouterManager.ReconcileInstancesManager通过reconcileDiff计算实例差异register/reconcile相应实例并按优先级依次调用各ConfigReconcilerService reconciler根据CiliumBGPAdvertisement计算出期望的路径Neighborreconciler 建立与外部路由器的 BGP 会话gobgp shim将 Cilium 路径翻译为 gobgpPath调用AddPath写入 RIB经 export 策略放行后通告给已建立会话的邻居。整个过程完全由声明式 CRD 驱动、事件驱动调和符合标准 Kubernetes Controller 模式。总结Cilium BGP Control Plane 通过Operator 侧声明分发 Agent 侧声明调和 gobgp 底层实现的三层设计将 BGP 路由通告能力以 CRD 驱动的方式接入 Cilium 体系。启用只需一个开关--enable-bgp-control-planetrue之后通过CiliumBGPClusterConfig声明集群级意图由 Operator 生成节点级CiliumBGPNodeConfigAgent 侧的 Controller → Manager → ConfigReconciler → Routergobgp调用链最终将路由通告到外部路由器。若要深入理解每个组件的细节推荐继续阅读以下仓库源码控制面装配 pkg/bgp/cell.goAgent 侧控制器 pkg/bgp/agent/controller.go声明式接口与实现 pkg/bgp/agent/routermgr.go、pkg/bgp/manager/manager.go调和器体系 pkg/bgp/manager/reconciler/reconcilers.gogobgp 翻译层 pkg/bgp/gobgp/server.goOperator 侧分发 operator/pkg/bgp/manager.goCRD 类型定义 pkg/k8s/apis/cilium.io/v2/bgp_node_types.go、pkg/k8s/apis/cilium.io/v2/bgp_cluster_types.go【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/cilium创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。