Cilium ClusterMesh MCS-API CoreDNS 自动配置指南:coredns-mcsapi-auto-configure命令与 Hive 框架详解
【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/cilium
导读
本文聚焦 Cilium 仓库中 ClusterMesh 组件的clustermesh-apiserver coredns-mcsapi-auto-configure命令及其 Hive 子命令,全面讲解如何通过该命令自动为 CoreDNS 注入 Kubernetes Multi-Cluster Services API(MCS-API)推荐的multicluster插件与clusterset.local域名配置。读者将掌握该命令的全部命令行参数、Hive 框架的检查方式、Corefile 的底层改写逻辑、CoreDNS 版本校验规则,以及命令背后的源码实现与测试验证,可直接在真实集群中安全地启用 MCS-API 跨集群服务发现。
一、命令概览:自动化 CoreDNS 的 MCS-API 配置
在 Cilium 的 ClusterMesh 多集群场景中,跨集群 Service 依赖 CoreDNS 的multicluster插件实现clusterset.local域名的解析。传统手工做法需要运维人员编辑 CoreDNS ConfigMap 并滚动重启 Deployment,容易出错且难以回滚。clustermesh-apiserver coredns-mcsapi-auto-configure正是为消除这一手工负担而生的自动化命令。
该命令定义于源码 clustermesh-apiserver/mcsapi-coredns-cfg/root.go,其Short描述为 "Automatically configure CoreDNS with recommended MCS-API settings"。命令整体基于 Cilium 的 Hive 依赖注入框架实现,模块定义位于 clustermesh-apiserver/mcsapi-coredns-cfg/cell.go(模块名为coredns-mcsapi-auto-configure),并由 clustermesh-apiserver/cmd/root.go 中的init()注册为clustermesh-apiserver顶层命令的子命令。
命令用法:
clustermesh-apiserver coredns-mcsapi-auto-configure [flags]从源码结构看,命令执行流程分为两个阶段:
PreRun:初始化 slog 日志(调用option.Config.SetupLogging与option.Config.Populate),并打印 "Cilium MCS-API CoreDNS auto configuration" 启动日志;Run:调用h.Run(...)启动 Hive,驱动cell.Invoke(configureCoreDNS)注册的一次性配置任务。
二、hive子命令:检查依赖注入单元
clustermesh-apiserver coredns-mcsapi-auto-configure hive用于检查 Hive 框架中的各个 cell(依赖注入单元),是调试命令生命周期与依赖关系的主要入口。
命令用法:
clustermesh-apiserver coredns-mcsapi-auto-configure hive [flags]该子命令基于 Hive 提供的通用h.Command()注册(见 clustermesh-apiserver/mcsapi-coredns-cfg/root.go),其作用是通过直接解析命令而不实际启动配置任务,让运维与开发人员安全地检查依赖注入单元。hive命令还派生出一个图形化子命令hive dot-graph,用于输出依赖关系图(详见下文)。
2.1 Options 一览
hive子命令自身仅有一个-h, --help选项;其余选项均继承自父命令,用于配置 CoreDNS 目标与 Kubernetes 客户端行为。
2.2 父命令继承的选项
hive子命令继承的选项与coredns-mcsapi-auto-configure父命令完全相同,如下表所示。这些选项也同时出现在hive dot-graph子命令的 "Options inherited from parent commands" 部分。
CoreDNS 目标配置(默认值定义于 clustermesh-apiserver/mcsapi-coredns-cfg/cell.go)
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
--coredns-cluster-domain | string | cluster.local | CoreDNS 的集群域名(cluster domain) |
--coredns-clusterset-domain | string | clusterset.local | CoreDNS 的 clusterset 域名(MCS-API 跨集群解析域) |
--coredns-configmap-name | string | coredns | CoreDNS 的 ConfigMap 名称 |
--coredns-deployment-name | string | coredns | CoreDNS 的 Deployment 名称 |
--coredns-namespace | string | kube-system | CoreDNS 所在的命名空间 |
Kubernetes 客户端配置
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
--enable-k8s | bool | true | 启用 k8s clientset |
--enable-k8s-api-discovery | bool | false | 通过 discovery API 启用对 Kubernetes API 组与资源的发现 |
--k8s-api-server-urls | strings | 空 | Kubernetes API Server 地址列表 |
--k8s-client-burst | int | 20 | K8s 客户端允许的 burst 值 |
--k8s-client-connection-keep-alive | duration | 30s | K8s 客户端连接的 keep-alive 时长;设为0表示禁用 K8s 客户端 |
--k8s-client-connection-timeout | duration | 30s | K8s 客户端连接超时;设为0表示禁用 K8s 客户端 |
--k8s-client-qps | float32 | 10 | K8s 客户端的每秒查询数(QPS)上限 |
--k8s-heartbeat-timeout | duration | 30s | api-server 心跳超时;设为0表示禁用 |
--k8s-kubeconfig-path | string | 空 | Kubernetes kubeconfig 文件的绝对路径 |
说明:上述选项通过
coreDNSConfig.Flags()(clustermesh-apiserver/mcsapi-coredns-cfg/cell.go)注册前五个 CoreDNS 相关 flag,其余 K8s 客户端 flag 由k8sClient.Cell注入(该 cell 在 cell.go 中被显式依赖)。
2.3hive dot-graph子命令
clustermesh-apiserver coredns-mcsapi-auto-configure hive dot-graph以 graphviz dot 格式输出 Hive 单元间的依赖关系图,便于可视化分析 cell 拓扑:
clustermesh-apiserver coredns-mcsapi-auto-configure hive dot-graph [flags]它仅有一个-h, --help选项,其余选项继承自父命令(与上表一致)。该命令不触发任何真实配置动作,适合在变更 cell 依赖后快速检查注入关系是否正确。
三、核心自动化流程:从 Corefile 改写到底层实现
coredns-mcsapi-auto-configure的配置逻辑集中在 clustermesh-apiserver/mcsapi-coredns-cfg/root.go 的configureCoreDNS函数中,它以 Hive job 的形式注册为一次性任务(job.OneShot("mcsapi-coredns-cfg", ...)),完整流程如下。
3.1 流程步骤
- 客户端检查:若
client.IsEnabled()为假,直接报错 "Kubernetes client is not enabled, cannot configure CoreDNS" 并退出。 - 读取 ConfigMap:从
--coredns-namespace/--coredns-configmap-name指定的命名空间读取 CoreDNS ConfigMap。 - 读取 Deployment:读取
--coredns-namespace/--coredns-deployment-name指定的 Deployment,用于后续滚动重启。 - 版本校验:调用
validateCoreDNSVersion检查 CoreDNS 镜像版本(详见第四节)。 - 提取 Corefile:从 ConfigMap 的
Data["Corefile"]字段取出 Corefile;若缺失则报错退出。 - 改写 Corefile:调用
updateCorefile注入multicluster插件与 clusterset 域名(详见 3.2 节)。 - 幂等判断:若
updateCorefile返回空字符串,说明 Corefile 已包含 MCS-API 配置,记录 "CoreDNS might already have MCS-API configuration, skipping configuration" 并跳过,不做任何修改。 - 备份并更新:将原 Corefile 存入
Corefile.cilium.bak键,再把改写后的 Corefile 写回Corefile键,通过 K8s 客户端执行 ConfigMapUpdate。 - 滚动重启:调用
restartCoreDNS触发 Deployment 滚动(详见 3.3 节)。
3.2updateCorefile:Corefile 的幂等改写逻辑
updateCorefile 是本次自动配置的核心算法,其工作方式如下:
- 幂等保护:若 Corefile 中已包含 clusterset 域名(如
clusterset.local)或multicluster字样,直接返回空字符串"",表示无需重复配置(这正是流程步骤 7 跳过配置的依据)。 - 正则定位 kubernetes 插件块:把 cluster domain 中的
.转义为\.后,用(?m)^\s*kubernetes.*%s.*\{匹配含该 cluster domain 的kubernetes插件配置块;若未匹配到,报错 "CoreDNS not configured with kubernetes plugin and the domain ..."。 - 注入 clusterset 域名:将 Corefile 中所有 cluster domain 出现处替换为
clusterDomain + " " + clustersetDomain(例如cluster.local→cluster.local clusterset.local)。 - 注入 multicluster 指令:用
(?m)^(\s*)kubernetes(.*)\{匹配插件块行,在其后追加缩进后的multicluster <clustersetDomain>指令行。
改写前后的典型对比可见于 clustermesh-apiserver/mcsapi-coredns-cfg/testdata/configure.txtar(configmap.yaml与configmap-expected.yaml)。该测试模拟了完整的端到端流程:先写入初始 Deployment 与 ConfigMap,启动 Hive 触发配置任务,随后断言 ConfigMap 被更新为预期内容,并断言 Deployment 上出现clustermesh.cilium.io/autoPatchedAt:注释。此外 clustermesh-apiserver/mcsapi-coredns-cfg/root_test.go 中的TestUpdateCorefiles覆盖了五种典型场景:
- 正常 Corefile 被正确改写(含
multicluster与双域名); - cluster domain 与配置不匹配时报错;
- 未使用
kubernetes插件时报错; - 已含
multicluster指令时幂等跳过; - 已含 clusterset 域名时幂等跳过。
3.3restartCoreDNS:滚动重启触发机制
restartCoreDNS 通过 server-side apply 为 Deployment 的 Pod 模板注入时间戳注释来触发滚动更新:
- 若 Deployment 处于
spec.Paused(暂停)状态,直接报错拒绝操作; - 否则调用
Apply方法,为 Pod 模板设置注释clustermesh.cilium.io/autoPatchedAt: <RFC3339 时间戳>(常量annotation.CoreDNSAutoPatched定义于 pkg/annotation/k8s.go,值为ClusterMeshPrefix + "/autoPatchedAt",即clustermesh.cilium.io/autoPatchedAt),FieldManager固定为mcsapi-coredns-autocfg且Force: true。
由于 Pod 模板注解变化必然导致 Pod 模板哈希变化,Deployment 会据此触发一次标准滚动发布,从而让 CoreDNS 以新的 Corefile 配置重新加载。
四、CoreDNS 版本校验规则
validateCoreDNSVersion 负责在改写前确认 CoreDNS 镜像版本满足 MCS-APImulticluster插件要求:
- 从镜像 tag 中解析版本号(依次剥离
@digest与-后的自定义构建信息,再去除前缀v); - 使用
github.com/blang/semver解析为语义化版本; - 若版本低于
1.12.2,返回致命错误 "CoreDNS version %s is too old for MCS-API auto configuration, please use v1.12.2 or newer"; - 若镜像 tag 无法解析为合法语义化版本(如自定义镜像
mycompany.org/coredns:mycustomversion),则仅返回 warning,忽略版本检查继续执行。
TestValideCoreDNSVersion(clustermesh-apiserver/mcsapi-coredns-cfg/root_test.go)覆盖了以下输入:
registry.k8s.io/coredns/coredns:v1.12.0→ 报错(版本过低);registry.k8s.io/coredns/coredns:v1.12.2→ 通过;registry.k8s.io/coredns/coredns:v1.12.2@sha256:...(带 digest)→ 通过;registry.k8s.io/coredns/coredns:v1.13.0(更高版本)→ 通过;public.ecr.aws/eks-distro/coredns/coredns:v1.12.2-eks-1-33-latest(非严格语义化 tag)→ 通过;mycompany.org/coredns:v1.12.2+1(带 build 元数据)→ 通过;mycompany.org/coredns:mycustomversion(无法解析)→ 仅 warning。
五、实战演练:完整的一次自动化配置
结合 clustermesh-apiserver/mcsapi-coredns-cfg/testdata/configure.txtar 中的示例,一个标准的 CoreDNS 初始 Corefile 如下:
.:53 { errors health { lameduck 5s } ready kubernetes cluster.local in-addr.arpa ip6.arpa { pods insecure fallthrough in-addr.arpa ip6.arpa ttl 30 } prometheus :9153 forward . 1.1.1.1 { max_concurrent 1000 } cache 30 { disable success cluster.local disable denial cluster.local } loop reload loadbalance log }执行自动化配置后,Corefile 变为:
.:53 { errors health { lameduck 5s } ready kubernetes cluster.local clusterset.local in-addr.arpa ip6.arpa { multicluster clusterset.local pods insecure fallthrough in-addr.arpa ip6.arpa ttl 30 } prometheus :9153 forward . 1.1.1.1 { max_concurrent 1000 } cache 30 { disable success cluster.local clusterset.local disable denial cluster.local clusterset.local } loop reload loadbalance log }同时 ConfigMap 中会新增Corefile.cilium.bak键保存原始 Corefile 作为回滚备份,Deployment 会被滚动重启(Pod 模板打上clustermesh.cilium.io/autoPatchedAt时间戳注解)。
5.1 运行前提
- CoreDNS 镜像版本必须不低于v1.12.2(低于该版本会直接报错拒绝配置);
- 目标集群已具备可用的 kubeconfig(通过
--k8s-kubeconfig-path指定,或依赖默认加载机制); - 执行账户需具备对
kube-system/corednsConfigMap 的读写权限,以及对kube-system/corednsDeployment 的patch权限; - Corefile 中必须存在包含 cluster domain(默认
cluster.local)的kubernetes插件块,否则会报错退出。
5.2 常见使用场景
- 首次启用 MCS-API:直接执行默认配置即可;
- 自定义域名/命名空间:通过
--coredns-cluster-domain、--coredns-clusterset-domain、--coredns-namespace、--coredns-configmap-name、--coredns-deployment-name定制目标; - 调试/只检查:使用
hive或hive dot-graph子命令检查 Hive 单元依赖,不触发任何实际改动; - 幂等重跑:命令具备幂等性,Corefile 已含
multicluster或 clusterset 域名时会自动跳过。
六、回滚与安全设计
该命令在设计中内置了多层安全防护:
- 自动备份:每次改写前将原始 Corefile 保存到
Corefile.cilium.bak键,方便随时手工回滚; - 幂等保护:重复执行不会产生叠加修改,已配置过的集群会被自动识别并跳过;
- 暂停 Deployment 保护:对处于暂停状态的 Deployment 拒绝注入注解,避免破坏运维状态;
- 版本门槛:低于 v1.12.2 的 CoreDNS 不支持 MCS-API 所需的
multicluster插件,命令会提前拦截; - 失败即停机:配置任务为一次性 job,任何步骤失败都会通过
shutdowner.Shutdown(hive.ShutdownWithError(err))使进程以错误状态退出,便于 CI/CD 捕获(见 clustermesh-apiserver/mcsapi-coredns-cfg/root.go)。
七、关联阅读
- 命令体系:
clustermesh-apiserver coredns-mcsapi-auto-configure(父命令)、hive(依赖检查)、hive dot-graph(依赖图输出)均可在 Documentation/cmdref 目录下找到对应文档; - 实现源码:clustermesh-apiserver/mcsapi-coredns-cfg/root.go、clustermesh-apiserver/mcsapi-coredns-cfg/cell.go;
- 测试验证:clustermesh-apiserver/mcsapi-coredns-cfg/root_test.go、clustermesh-apiserver/mcsapi-coredns-cfg/testdata/configure.txtar;
- 注解常量:
clustermesh.cilium.io/autoPatchedAt定义于 pkg/annotation/k8s.go; - 命令注册入口:clustermesh-apiserver/cmd/root.go。
【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/cilium
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考