云环境里跑 Kubernetes,Cloud Controller Manager(CCM)的路由控制器一直在默默工作——每隔固定间隔,它就把集群节点信息同步到云厂商的路由表。问题是:节点没变化,它也在同步。对于 API 调用有严格速率限制的云厂商来说,这等于在白白消耗配额。Kubernetes v1.35 引入了 CloudControllerManagerWatchBasedRoutesReconciliation 特性门控,把固定间隔轮询改成基于 Watch 的按需同步;v1.36 则补上了验证这改动效果的关键工具——route_controller_route_sync_total 计数指标。
固定间隔轮询的隐性成本
传统路由控制器的工作方式很简单:一个定时循环,周期性地把所有节点信息刷到云厂商的路由 API。不管节点有没有增删改,循环照转不误。
以默认 5 分钟同步一次为例,10 分钟内即使没有任何节点变化,同步也会执行两次;20 分钟四次。在节点频繁变动的集群里,这不算浪费。但在生产环境中,节点规模往往长期稳定——自动扩缩容触发后可能几小时甚至几天都没有变化。每次无意义的同步都在消耗云厂商的 API 速率配额,还可能拖慢其他控制器的调用。
Watch 模式:只在节点变化时才同步
v1.35 引入的 CloudControllerManagerWatchBasedRoutesReconciliation 特性门控改变了这一行为。启用后,路由控制器不再走定时循环,而是通过 Watch 机制监听节点事件——只有节点实际发生增删改时,才触发一次路由同步。
效果对比很直观:
特性门控关闭(默认,固定间隔循环):
# 10 分钟内无节点变化
route_controller_route_sync_total 60
# 20 分钟,仍然无节点变化
route_controller_route_sync_total 120
特性门控开启(Watch 模式):
# 10 分钟内无节点变化
route_controller_route_sync_total 1
# 20 分钟,仍然无节点变化——计数不变
route_controller_route_sync_total 1
# 一个新节点加入集群——计数增加
route_controller_route_sync_total 2
稳定集群中,差异尤其显著。Watch 模式把同步次数从"按时间线性增长"降到"按事件触发",对 AWS、GCP、Azure 等有严格 API 速率限制的云厂商来说,这意味着配额利用率大幅提升。
用新指标做 A/B 测试
route_controller_route_sync_total 是 v1.36 新增的 Alpha 级别计数器指标,位于 k8s.io/cloud-provider 的路由控制器实现中。每次路由同步完成,计数器加一。它的核心用途就是帮你量化 Watch 模式的实际收益。
下面是一套可操作的 A/B 测试流程:
步骤一:确认指标可用
先检查 CCM 的 metrics 端点是否暴露了该指标:
# 假设 CCM 以 DaemonSet 运行,metrics 端口默认 10253
# 端口可能因部署方式不同,请按实际配置调整
kubectl get --raw /metrics/ccm | grep route_controller_route_sync_total
如果集群用了 kube-proxy 或 port-forward,也可以这样:
# 通过 port-forward 访问
kubectl port-forward -n kube-system daemonset/cloud-controller-manager 10253:10253 &
curl -s http://localhost:10253/metrics | grep route_controller_route_sync_total
预期输出类似:
route_controller_route_sync_total 0
步骤二:在默认模式下采集基线数据
保持特性门控关闭(默认状态),观察一段时间内的同步计数增长:
# 每 5 分钟采样一次,持续 30 分钟
for i in $(seq 1 6); do
sleep 300
echo "=== Sample $i at $(date) ==="
curl -s http://localhost:10253/metrics | grep route_controller_route_sync_total
done
记录每个采样点的数值,计算同步频率。
步骤三:开启 Watch 模式,重复采集
编辑 kube-apiserver 和 CCM 的启动参数,启用特性门控:
# kube-apiserver 或 CCM 的启动参数中添加
# 注意:Alpha 特性门控需要同时在不同组件中启用
# 具体组件取决于你的 CCM 部署方式
apiVersion: v1
kind: Pod
metadata:
name: cloud-controller-manager
namespace: kube-system
spec:
containers:
- name: cloud-controller-manager
command:
- /bin/cloud-controller-manager
- --feature-gates=CloudControllerManagerWatchBasedRoutesReconciliation=true
# ... 其他参数保持不变
重启 CCM 后,用同样的采样脚本再次采集数据。对比两组数据中同步计数的增长曲线——稳定集群中,Watch 模式的增长应该几乎为零,只在节点事件发生时才跳变。
步骤四:模拟节点变化验证响应性
Watch 模式不是"不同步",而是"按需同步"。验证它在节点变化时确实能及时响应:
# 临时扩容一个 Deployment 触发新节点加入(如果集群支持自动扩缩容)
kubectl scale deployment my-app --replicas=50
# 或者手动添加一个节点后观察计数变化
curl -s http://localhost:10253/metrics | grep route_controller_route_sync_total
# 预期:计数在节点加入后短时间内增加
采纳建议与注意事项
- Alpha 状态:该指标和 Watch 模式特性门控目前都是 Alpha 级别,生产环境启用前务必在测试集群中充分验证。Alpha 特性可能在未来版本中变更甚至移除。
- CCM 部署差异:不同云厂商的 CCM 实现部署方式不同——有的以 Static Pod 运行,有的以 DaemonSet 运行,metrics 端口也可能不同。上面的示例端口
10253是常见默认值,请按你的实际部署调整。 - 特性门控传播:
CloudControllerManagerWatchBasedRoutesReconciliation可能需要在多个组件中同时启用,具体取决于 CCM 与 kube-apiserver 的交互方式。参考 KEP-5237 的详细说明。 - 不稳定集群收益有限:如果你的集群节点频繁变动(比如持续扩缩容),Watch 模式减少的同步次数相对较少,收益不如稳定集群明显。但即便如此,它也不会比固定间隔模式更差——只是改善幅度不同。
- 监控集成:将
route_controller_route_sync_total接入 Prometheus 后,可以配合rate()函数计算同步速率,用 Grafana 面板直观对比两种模式下的曲线差异。
如果你在验证过程中发现问题或有反馈,可以通过以下渠道联系 SIG Cloud Provider:
- Kubernetes Slack 的
#sig-cloud-provider频道 - GitHub 上的 KEP-5237 issue
- SIG Cloud Provider 社区页面