Cilium 节点配置解析实战:cilium-dbg build-config 命令完全指南
【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/cilium
Cilium Agent 支持从多个配置源(ConfigMap、CiliumNodeConfig 自定义资源、Node 注解)按优先级合并出节点级最终配置。cilium-dbg build-config正是这一"配置解析器"的独立可执行形态:它在不启动完整 Agent 的前提下,拉取并合并所有适用于当前节点的配置来源,把最终结果以 Kubernetes ConfigMap 的目录结构写到本地磁盘。读完本文,你将掌握该命令的每个参数含义、三种配置源的语法与合并优先级、allow/deny-config-keys的覆盖控制机制,以及如何用它排障、预检或为离线场景生成配置。
命令概览:一个可独立运行的配置解析器
cilium-dbg build-config的官方定位是"Resolve all of the configuration sources that apply to this node"(解析所有适用于当前节点的配置来源),对应命令文档见 Documentation/cmdref/cilium-dbg_build-config.md。它在cilium-dbg这个 CLI 中注册,命令体位于 cilium-dbg/cmd/build-config.go:
var buildConfigCmd = &cobra.Command{ Use: "build-config --node-name $K8S_NODE_NAME", Short: "Resolve all of the configuration sources that apply to this node", Run: func(cmd *cobra.Command, args []string) { log.Info("Running") if err := buildConfigHive.Run(log); err != nil { logging.Fatal(log, "Build config failed", logfields.Error, err) } }, }它运行一个独立的 Hive 应用(buildConfigHive),组合了k8sClient.Cell(Kubernetes clientset)、hostfirewallbypass.Cell与buildConfigCell(配置解析器)三个单元。启动后立即执行一次配置解析,写盘后调用shutdowner.Shutdown()自行退出,属于"一次性任务型"命令,非常适合:
- 排障:本地快速查看某个节点最终会拿到哪些配置键值,而不必逐一比对 ConfigMap / CiliumNodeConfig / Node 注解;
- 预检与演练:上线前验证节点级覆盖(per-node configuration)是否正确生效;
- 离线配置生成:把最终合并结果落地到
--dest指定目录,供后续挂载或归档。
命令用法与完整参数说明
命令原型如下:
cilium-dbg build-config --node-name $K8S_NODE_NAME [flags]核心参数
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
--node-name | string | 来自K8S_NODE_NAME环境变量 | 当前节点名称。解析cilium-node-config源的节点选择器、node源注解时都需要它来匹配节点 |
--source | strings | [config-map:cilium-config,cilium-node-config:] | 有序配置来源列表,见下文"三种配置源" |
--dest | string | /tmp/cilium/config-map | 最终合并配置的写入目录 |
--allow-config-keys | strings | 空 | 允许被后续来源覆盖的配置键列表;设置后优先于--deny-config-keys |
--deny-config-keys | strings | 空 | 禁止被后续来源覆盖的配置键列表;--allow-config-keys非空时本参数被忽略 |
--enable-k8s | bool | true | 是否启用 Kubernetes clientset |
--enable-k8s-api-discovery | bool | — | 是否用 discovery API 探测 K8s API 分组与资源 |
--node-name的默认值取自K8S_NODE_NAME环境变量(源码常量定义见 pkg/k8s/constants/const.go),因此实际使用中可以只写cilium-dbg build-config并确保环境变量已注入。
Kubernetes 客户端相关参数
命令内部通过完整的 clientset 访问集群,因此也暴露了全部客户端调优选项:
| 参数 | 默认值 | 说明 |
|---|---|---|
--k8s-api-server-urls | — | Kubernetes API Server 地址列表(多集群/外部访问场景) |
--k8s-kubeconfig-path | — | kubeconfig 文件绝对路径 |
--k8s-client-qps | 10 | K8s 客户端每秒查询数上限 |
--k8s-client-burst | 20 | K8s 客户端突发请求数上限 |
--k8s-client-connection-keep-alive | 30s | 客户端连接 keep-alive 时长,设为0则禁用 |
--k8s-client-connection-timeout | 30s | 客户端连接超时,设为0则禁用 |
--k8s-heartbeat-timeout | 30s | API Server 心跳超时,设为0则禁用 |
这些参数的解析、默认值与标志注册都在 cilium-dbg/cmd/build-config.go 的buildConfigCfg中完成,其中--source的默认值直接由 resolver 包的常量拼装:
var defaultBuildConfigCfg = buildConfigCfg{ Dest: "/tmp/cilium/config-map", NodeName: os.Getenv(k8sConsts.EnvNodeNameSpec), Source: []string{ resolver.KindConfigMap + ":cilium-config", resolver.KindNodeConfig + ":" + os.Getenv("CILIUM_K8S_NAMESPACE"), }, AllowConfigKeys: []string{}, DenyConfigKeys: []string{}, }继承自父命令的全局选项
cilium-dbg build-config还继承了cilium-dbg的全局参数:
--config string:配置文件路径(默认$HOME/.cilium.yaml);-D, --debug:开启调试日志;-H, --host string:server-side API 的 URI;--log-driver strings:日志输出端点(如syslog);--log-opt map:日志驱动选项(如format=json)。
三种配置源:从低优先级到高优先级
--source接受一个有序列表,按位置从前到后优先级递增,后面的来源可以覆盖前面的键值。源码中定义了三种来源(常量见 pkg/option/resolver/resolver.go):
1.config-map:<namespace>/<name>— 基础配置 ConfigMap
读取指定 ConfigMap 的data字段作为键值对。命名空间与名称均为可选:
- 只写
config-map:名称默认cilium-config,命名空间默认CILIUM_K8S_NAMESPACE环境变量; - 写
config-map:cilium-config:指定名称,命名空间取环境变量; - 写
config-map:kube-system/cilium-config:同时指定命名空间与名称。
对应的读取实现readConfigMap见 pkg/option/resolver/resolver.go:ConfigMap 不存在时记录日志并忽略(返回空),不会导致命令失败。
2.cilium-node-config:<NAMESPACE>— 节点级覆盖(CiliumNodeConfig)
读取指定命名空间下的全部CiliumNodeConfigCRD 对象,逐一用节点的标签匹配spec.nodeSelector,把匹配对象spec.defaults中的键值合并进来(实现见readNodeConfigs,pkg/option/resolver/resolver.go)。关键行为:
- 命名空间省略时取
CILIUM_K8S_NAMESPACE环境变量; - 同时命中多个 CiliumNodeConfig 时,按对象名称字典序排序,后排序的覆盖先排序的;
- 空
spec.nodeSelector({})匹配所有节点,未提供选择器则默认不匹配任何节点; - 该 CRD 的类型定义见 pkg/k8s/apis/cilium.io/v2/cnc_types.go,
defaults的每个键必须是合法的 ConfigMap data 字段(字符集为a-z、A-Z、-、_、.)。
3.node:<NODENAME>— Node 注解 / 标签覆盖
读取指定 Node 对象上以config.cilium.io/为前缀的注解或标签,前缀之后的KEY=VALUE部分即配置键值。实现见readNodeOverrides(pkg/option/resolver/resolver.go),前缀常量定义在 pkg/annotation/k8s.go:
// ConfigPrefix is the common prefix for configuration related annotations. ConfigPrefix = "config.cilium.io"节点名省略时默认取K8S_NODE_NAME环境变量。例如给节点打注解:
kubectl annotate node kind-worker 'config.cilium.io/monitor-aggregation=maximum'则monitor-aggregation=maximum就会作为一个配置覆盖项参与合并。
配置合并、优先级与覆盖控制
合并算法
ResolveConfigurations(pkg/option/resolver/resolver.go)按顺序遍历--source列表,用mergeConfig逐层叠加:后一个来源的键值无条件写入结果 map,并打印 "Source overrides key" 日志(resolver.go)。因此:
- 第一个来源的键是"基线",任何后续来源都可以覆盖它;
- 整体优先级从低到高为:
config-map<cilium-node-config<node(前提是按此顺序在--source中排列)。
allow / deny 覆盖控制
默认情况下,除第一个来源外,后续来源可以覆盖任意键。--allow-config-keys与--deny-config-keys用于收紧这一权限:
--allow-config-keys k1,k2:只允许列出的键被后续来源覆盖(白名单),且优先于deny 列表;--deny-config-keys k1,k2:禁止列出的键被后续来源覆盖(黑名单),非首个来源中命中 deny 的键会被直接剔除并打警告日志。
对应过滤逻辑在 pkg/option/resolver/resolver.go:当allowConfigKeys非空时构造 allow 集合,否则使用 deny 集合;matchKeys.Has(k) == allowIfMatch不成立即表示该键不可覆盖,予以删除。
合并结果的附加元数据
合并完成后,命令还会向最终配置注入两个特殊键(见 resolver.go):
config-sources:实际生效的配置来源 JSON 数组(按优先级顺序、去重后),供上层核对"这个键来自哪里";config-sources-overrides:本次使用的allowConfigKeys/denyConfigKeysJSON 对象。
这两个键与 Agent 的--config-sources/--config-sources-overrides隐藏参数(见 pkg/dynamicconfig/cell.go)一一对应,是 Agent 侧动态配置(dynamicconfig)持久化后重新解析配置来源的依据;Agent 运行时还会依据来源顺序为每个键计算覆盖优先级(实现见 pkg/dynamicconfig/reflectors.go)。
输出格式:以 ConfigMap 目录结构落盘
--dest目录下的最终产物完全模仿 Kubernetes ConfigMap 的挂载结构,这是为了让 Agent 可以像读取挂载的 ConfigMap 一样消费这些文件。写入逻辑WriteConfigurations见 pkg/option/resolver/resolver.go,采用双层符号链接 + 原子替换:
- 新建时间戳数据目录
..data_<unix时间戳>,把每个配置键作为普通文件写入其中(0644); - 用
..data.tmp临时符号链接指向新数据目录,再os.Rename原子替换为..data; - 为每个键创建
destDir/key -> ../..data/key的符号链接。
因此最终目录形如:
/tmp/cilium/config-map/ ├── ..data -> ..data_1726000000 ├── ..data_1726000000/ │ ├── config-sources │ ├── config-sources-overrides │ ├── monitor-aggregation │ ├── bpf-lb-acceleration │ └── ...(其余合并后的键) ├── bpf-lb-acceleration -> ../..data/bpf-lb-acceleration └── monitor-aggregation -> ../..data/monitor-aggregation这样的设计保证了消费方随时通过..data读取到完整一致的一版配置,任何一次更新都不会出现半写状态。写入前会先用os.MkdirAll创建目标目录,键名中包含路径分隔符的条目会被拒绝并记录错误日志。
实战场景
场景一:查看节点最终生效配置(排障)
export K8S_NODE_NAME=kind-worker cilium-dbg build-config --dest /tmp/cilium/config-map cat /tmp/cilium/config-map/bpf-lb-acceleration # 查看某个键 cat /tmp/cilium/config-map/config-sources # 查看该键来源链场景二:按节点逐步启用 XDP 硬件加速
参考官方节点级配置文档 Documentation/configuration/per-node-config.rst,先给具备相应硬件的节点打标签并创建CiliumNodeConfig:
apiVersion: cilium.io/v2 kind: CiliumNodeConfig metadata: namespace: kube-system name: enable-xdp spec: nodeSelector: matchLabels: io.cilium.xdp-offload: "true" defaults: bpf-lb-acceleration: native然后在本机预检合并结果(假设当前节点带有io.cilium.xdp-offload=true标签):
cilium-dbg build-config --source config-map:cilium-config,cilium-node-config:kube-system --node-name kind-worker cat /tmp/cilium/config-map/bpf-lb-acceleration # 期望输出 native注意:与 CiliumNodeConfig 相关的机制相同,创建或修改 CiliumNodeConfig 后,需要删除并重建 Pod(或重启节点)配置才会生效,文档中亦有此提示(per-node-config.rst)。
场景三:限制节点级覆盖范围
只允许bpf-lb-acceleration、monitor-aggregation被节点级来源覆盖:
cilium-dbg build-config \ --node-name kind-worker \ --source config-map:cilium-config,cilium-node-config:kube-system,node:kind-worker \ --allow-config-keys bpf-lb-acceleration,monitor-aggregation此时即便 Node 注解或 CiliumNodeConfig 中包含其他键,也会被过滤并在日志中提示 "Source has non-overridable key"。
与 Agent 运行时的关系
cilium-dbg build-config并非孤立工具,它与 Agent 内部的动态配置体系共享同一套pkg/option/resolver包:
- Agent 启动参数中的
--config-sources(默认[{"kind":"config-map","namespace":"kube-system","name":"cilium-config"}])定义了运行时的配置来源,见 pkg/dynamicconfig/cell.go; - 运行时通过 reflector 监听 ConfigMap / CiliumNodeConfig / Node 的变化并计算优先级(pkg/dynamicconfig/reflectors.go),优先级计算规则
getPriorityForKey与 build-config 的覆盖控制语义一致:第一个来源优先级最高,其余来源按allow/deny决定键是否参与覆盖。
因此,cilium-dbg build-config可以看作这套运行时机制的"单次快照执行版":先用它本地验证合并结果,再放心地把同样的--source、allow/deny配置交给 Agent 长期运行。
小结
cilium-dbg build-config把 Cilium 多级配置解析能力封装成了一个可独立执行的命令:通过--source声明配置来源顺序,--allow-config-keys/--deny-config-keys控制覆盖范围,最终把合并结果以原子、ConfigMap 兼容的目录结构写入--dest。无论是排查节点配置漂移、验证 CiliumNodeConfig 的节点选择器,还是为 Agent 预生成配置,它都是比直接比对 YAML 更可靠、更贴近真实解析逻辑的选择。其完整选项与继承参数可随时通过cilium-dbg build-config --help查看,源码入口位于 cilium-dbg/cmd/build-config.go,核心合并算法位于 pkg/option/resolver/resolver.go。
【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/cilium
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考