
Cilium 带宽管理实战cilium-dbg bpf bandwidth命令详解与 BPF 数据面限速原理【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/ciliumcilium-dbg bpf bandwidth是 Cilium 提供的用于查看 BPF 数据面datapath带宽bandwidth设置的命令行入口其子命令list能够直接读取内核中cilium_throttleBPF Map展示每个 Endpoint 当前的限速与优先级配置。本文以该命令的官方参考文档Documentation/cmdref/cilium-dbg_bpf_bandwidth.md为核心骨架结合仓库中命令实现与底层带宽管理器的源码完整讲解命令用法、输出字段含义、全局选项以及其背后的 EDTEarliest Departure Time限速机制与 Pod 带宽注解帮助读者既会查又能懂。一、命令概览BPF 数据面带宽设置入口cilium-dbg bpf bandwidth是cilium-dbg bpf的子命令组用于对 BPF 数据面中的带宽相关设置进行直接访问。其定义位于 bpf_bandwidth.go源码中给出的命令描述为var BPFBandwidthCmd cobra.Command{ Use: bandwidth, Short: BPF datapath bandwidth settings, }该命令本身是一个分组命令无实际执行逻辑真正的功能由其子命令承担。官方参考文档列出的选项只有一个-h, --help help for bandwidth可通过cilium-dbg bpf bandwidth --help查看该命令组下的全部子命令。命令组的唯一子命令为listcilium-dbg bpf bandwidth list— 列出 BPF 数据面带宽设置List BPF datapath bandwidth settings父命令cilium-dbg bpf的完整介绍见 Documentation/cmdref/cilium-dbg_bpf.md其定位是直接访问本地 BPF MapDirect access to local BPF maps带宽命令正是这一族命令的成员之一。二、核心子命令cilium-dbg bpf bandwidth list2.1 命令语法子命令参考文档见 Documentation/cmdref/cilium-dbg_bpf_bandwidth_list.md其用法为cilium-dbg bpf bandwidth list [flags]该命令在节点上执行时会打开本机挂载的cilium_throttleBPF Map 并转储其中全部条目从而列出当前节点上所有已配置带宽限制的 Endpoint 及其限速参数。命令在 bpf_bandwidth_list.go 中实现执行流程如下调用common.RequireRootPrivilege(cilium bpf bandwidth list)校验 root 权限读取 BPF Map 需要特权通过bwmap.ThrottleMap(slog.Default())打开cilium_throttleMap若 Map 不存在返回fs.ErrNotExist向 stderr 输出bandwidth manager not enabled并退出码 1 —— 这是未启用带宽管理器时最典型的提示成功打开后调用throttleMap.Dump(...)转储全部键值对若指定了-o/--output则以 JSON/YAML/JSONPath 输出否则以表格形式打印。2.2 选项Options该子命令支持两个选项选项类型说明-h, --helpbool显示 list 子命令的帮助信息-o, --output stringstring输出格式支持json、yaml、jsonpath{}-o/--output选项通过command.AddOutputOption(bpfBandwidthListCmd)注册见 bpf_bandwidth_list.go适用于脚本化采集场景。例如以 JSON 格式获取全部带宽条目cilium-dbg bpf bandwidth list -o json以 YAML 格式获取cilium-dbg bpf bandwidth list -o yaml使用 JSONPath 提取特定字段cilium-dbg bpf bandwidth list -o jsonpath{range .items[*]}{.key}{ - }{.value}{\n}{end}当使用-o时命令会将bpfBandwidthList键为EndpointID,Direction、值为Bps,Prio的字符串映射直接交给command.PrintOutput序列化输出不再打印人类可读表格。2.3 表格输出示例不带-o时默认输出一个四列表格列定义见 bpf_bandwidth_list.goIDENTITY DIRECTION PRIO BANDWIDTH (BitsPerSec)例如IDENTITY DIRECTION PRIO BANDWIDTH (BitsPerSec) 2345 Egress 7 10M 2345 Ingress 0 20M需要说明的是此处 Map 键中记录的其实是Endpoint ID身份标识源码中以IDENTITY作为表头labelsIDTitle IDENTITY其值取自cilium_throttleMap 键的第一段。表格行按键值排序输出。三、输出字段深度解读3.1 IDENTITYEndpoint ID对应 BPF Map 键EdtId.Id即被限速的 EndpointPod 对应的本地端点ID。从键解析逻辑看bpf_bandwidth_list.goMap 键格式为EndpointID,Direction。3.2 DIRECTION方向Map 键的第二段为方向字段取值与pkg/datapath/linux/bandwidth/bandwidth.go中定义的常量一一对应DirectionEgress uint8 0 DirectionIngress uint8 1即方向值为0时显示Egress出方向值为1时显示Ingress入方向其余值默认回退为Egress。这组常量注释明确指出必须与bpf/lib/common.h中的DIRECTION_*保持一致。3.3 BANDWIDTH (BitsPerSec)带宽Map 值中的Bps字段记录的是字节/秒bytes per second而列表命令在展示时做了换算bpf_bandwidth_list.gobps * 8 quantity : resource.NewQuantity(int64(bps), resource.DecimalSI)即乘以 8 转换为比特/秒再通过k8s.io/apimachinery/pkg/api/resource格式化为人类可读的 Kubernetes 资源量如10M、512k。这与用户配置时的语义保持一致——Pod 带宽注解如kubernetes.io/egress-bandwidth: 10M本身就是以 bits 为单位书写的。3.4 PRIO优先级Map 值中的Prio字段代表该 Endpoint 数据包在 FQFair Queueqdisc 中使用的优先级等级用于配合 QoS 分类。关于默认优先级的具体取值见下文带宽管理器一节。四、继承自父命令的全局选项cilium-dbg bpf bandwidth及其子命令还继承了cilium-dbg根命令的一组全局选项见原文档 Options inherited from parent commands选项类型说明--config stringstring配置文件路径默认$HOME/.cilium.yaml-D, --debugbool启用调试消息-H, --host stringstring服务端 API 的 URI默认本地 cilium agent--log-driver stringsstrings使用的日志端点示例syslog--log-opt mapmap日志驱动选项示例formatjson例如指定远端 Agent 执行查询cilium-dbg --host unix:///var/run/cilium/cilium.sock bpf bandwidth list需要留意的是虽然cilium-dbg支持--host指向远端但bpf bandwidth list的实际读取动作是打开本机文件系统中的 BPF Map 挂载点bpf.MapPath因此该命令在语义上仍是节点本地的操作需要在目标节点上以 root 运行。五、底层原理cilium_throttleBPF Map5.1 Map 定义cilium-dbg bpf bandwidth list读取的是名为cilium_throttle的 BPF Map其定义与结构体在 bwmap.go 中MapName cilium_throttle // Flow aggregate is per Pod, so same size as Endpoint map. MapSize lxcmap.MaxEntries // DefaultDropHorizon represents maximum allowed departure // time delta in future... DefaultDropHorizon 2 * time.SecondMap 的键值结构键EdtIdId uint32Endpoint IDDirection uint8方向Pad值EdtInfoBps uint64字节/秒限速、TimeLast uint64BPF 侧维护的最后时间戳、TimeHorizonDropOrTokens uint64出方向为丢包时间窗、入方向为令牌相关取决于方向、Prio uint32优先级。该 Map 由pkg/maps/bwmap包的 Hive Cell 管理见 cell.go。在[服务网格术语里对应表名]它维护一张名为bandwidth-edts的 StateDB 表并通过 reconciler 将表内容同步到cilium_throttleMap。当带宽管理器未启用EnableBandwidthManagerfalse时Cell 会主动移除 Map 的挂载点pin这也解释了为什么未启用时list命令会报出bandwidth manager not enabled。5.2 打开 Map 的实现ThrottleMap函数bwmap.go以只读/打开方式获取已初始化的 Map// ThrottleMap opens an already initialized cilium_throttle map. Direct use of this // outside of this package is solely for cilium-dbg. func ThrottleMap(logger *slog.Logger) (*bpf.Map, error) { return bpf.OpenMap(bpf.MapPath(logger, MapName), EdtId{}, EdtInfo{}) }注释明确说明该函数在包外的直接用途就是供cilium-dbg使用。六、带宽管理器限速从配置到 BPF 的完整链路要真正理解list命令输出的数据来源需要了解带宽管理器Bandwidth Manager如何写入这些条目。核心实现在 pkg/datapath/linux/bandwidth/bandwidth.go。6.1 配置来源Pod 注解带宽限制通过 Kubernetes Pod 注解声明bandwidth.go// EgressBandwidth is the K8s Pod annotation. EgressBandwidth kubernetes.io/egress-bandwidth // IngressBandwidth is the K8s Pod annotation. IngressBandwidth kubernetes.io/ingress-bandwidth // Priority is the Cilium Pod priority annotation. Priority bandwidth.cilium.io/priority典型用法是在 Pod 或 Deployment 中声明apiVersion: v1 kind: Pod metadata: name: bw-limit-demo annotations: kubernetes.io/egress-bandwidth: 10M kubernetes.io/ingress-bandwidth: 20M注解值通过GetBytesPerSecbandwidth.go解析先用resource.ParseQuantity解析为 bit 数再除以 8 得到写入 Map 的字节/秒值。这正与list输出时bps * 8的换算形成闭环。6.2 写入链路带宽管理器实现了Manager接口bandwidth.go提供四个关键方法UpdateBandwidthLimit(endpointID, bytesPerSecond, prio)设置出方向限速DeleteBandwidthLimit(endpointID)删除出方向限速UpdateIngressBandwidthLimit(endpointID, bytesPerSecond)设置入方向限速DeleteIngressBandwidthLimit(endpointID)删除入方向限速。写入时bandwidth.go以 StateDB 事务向bandwidth-edts表插入bwmap.NewEdt(...)记录reconciler 随后将其同步进cilium_throttleBPF Map——因此cilium-dbg bpf bandwidth list看到的就是这一同步后的结果。表结构见 table.go其中TimeHorizonDrop默认取DefaultDropHorizon2 秒用于防止用户态应用通过SO_TXTIME设置的未来出发时间把 FQ qdisc 队列灌满。6.3 出方向 EDT 限速原理出方向带宽限制基于EDTEarliest Departure Time最早出发时间算法pkg/maps/bwmap的包注释即enforce Pod bandwidth limitations via EDT (Earliest Departure Time) BPFCilium 在 BPF 数据面为每个数据包计算其允许出发的最早时间配合内核 FQ qdisc 实现精确的流量整形pacing。带宽管理器启用时会自动设置一组基线 sysctlbandwidth.gonet.core.netdev_max_backlog≥ 1000net.core.somaxconn≥ 4096net.ipv4.tcp_max_syn_backlog≥ 4096net.core.default_qdiscfqnet.ipv4.tcp_congestion_controlcubic启用 BBR 时为bbr。6.4 QoS 优先级分类PRIO列的值与 QoS 类别相关bandwidth.go// GuaranteedQoSDefaultPriority prio value to classify packets to high prio band GuaranteedQoSDefaultPriority 6 1 // BurstableQoSDefaultPriority prio value to classify packets to medium prio band BurstableQoSDefaultPriority 8 1 // BestEffortQoSDefaultPriority prio value to classify packets to medium prio band BestEffortQoSDefaultPriority 5 1代码注释指出优先级值统一加 1是为了区分未设置优先级0与设置了优先级两种情况FQ priomap 从索引 0 开始的默认映射为1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1上述常量分别将数据包归入 high / medium / low 频带。另外host Endpoint 会被惰性lazy设置为 Guaranteed QoS 优先级ensureHostEndpointQoSbandwidth.go因此即使 host Endpoint 没有显式限速list输出中也可能出现一个 BANDWIDTH 为 0、但 PRIO 非 0 的条目。七、启用前提与常见故障排查bandwidth manager not enabled是执行cilium-dbg bpf bandwidth list时最常见的报错。根据probe()的逻辑bandwidth.go带宽管理器在以下情况下不会启用或被自动禁用EnableBandwidthManager配置未开启需要在 Cilium Agent 中开启带宽管理器例如安装时启用bandwidthManager.enabled并选择edt模式无法读取 procfsnet.core.default_qdisc读取失败功能被降级禁用启用 BBREnableBBR但内核低于 5.18缺少bpf_skb_set_tstamphelper只启用了EnableBBRHostnsOnly而未启用EnableBBR启用了 BBR 但同时使用了 legacy host routingBBR 场景要求 BPF host routing与 IPSec 同时启用——此时带宽管理器会被强制禁用并告警。排查建议确认 Agent 日志中是否有 BPF bandwidth manager could not ... / cannot be used with IPSec 等告警用cilium-dbg status检查带宽管理器相关状态确认节点内核版本满足 EDT/FQ 与可选BBR 的要求确认对应的 Pod 注解kubernetes.io/egress-bandwidth、kubernetes.io/ingress-bandwidth已正确下发到节点上的 Endpoint。八、总结cilium-dbg bpf bandwidth命令组cilium-dbg bpf bandwidth与list子命令Documentation/cmdref/cilium-dbg_bpf_bandwidth_list.md为运维者提供了直达内核 BPF 层的带宽配置检视能力。通过cilium_throttleMappkg/maps/bwmap/bwmap.go可以直观看到每个 Endpoint 的限速值、方向与优先级结合 pkg/datapath/linux/bandwidth/bandwidth.go 中 EDT 整形、QoS 分类与注解解析的实现可以完整掌握从声明 Pod 带宽注解到数据面精确限速再到命令行验证限速结果的全链路。当需要验证 Cilium 带宽管理是否生效、排查限速异常或审计节点级带宽策略时cilium-dbg bpf bandwidth list都是首选的诊断工具。【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/cilium创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考