在 Utho Kubernetes Engine 上部署与理解 Cluster Autoscaler:云提供商配置、节点池伸缩原理与源码剖析

在 Utho Kubernetes Engine 上部署与理解 Cluster Autoscaler:云提供商配置、节点池伸缩原理与源码剖析 在 Utho Kubernetes Engine 上部署与理解 Cluster Autoscaler云提供商配置、节点池伸缩原理与源码剖析【免费下载链接】autoscalerAutoscaling components for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/au/autoscalerCluster Autoscaler 的 Utho 云提供商cloud provider让 Kubernetes 集群能够基于工作负载自动调整 Utho Kubernetes EngineUKE中节点池Node Pool的大小。本文以 cluster-autoscaler/cloudprovider/utho/README.md 为核心结合仓库内源码、部署清单与测试用例完整讲解 cloud-config 配置字段、Deployment 部署参数、节点池伸缩策略的设定方式以及底层调用链与实现细节帮助你快速上手并在生产环境正确运行。Utho Kubernetes Engine 与节点池模型Utho Kubernetes Engine 是 Utho 提供的托管 Kubernetes 服务。它允许用户创建节点池Node Pool——即一组规格完全相同的节点相同机型、相同标签整个节点池是 Cluster Autoscaler 进行扩缩容操作的基本单元。理解 UKE 的节点池语义是正确配置 Cluster Autoscaler 的前提池大小可随时调整节点池的规模节点数量可以在任意时刻被修改。缩容时不可指定删除对象当缩小节点池时用户无法选择具体删除哪些节点。Utho Kubernetes 会随机选择节点删除以达到目标规模即便某个节点不健康、或已被手动删除也遵循这一规则。节点是可丢弃的节点池中的节点被视为一次性资源可在任意时刻被删除并重建。如果用户在 UKE 之外直接删除某个节点Utho 会在短时间内自动将其重建。正是基于节点可任意替换这一假设Cluster Autoscaler 才能在缩容时通过云 API 直接删除节点而无需担心数据持久性——这正是该云提供商设计的核心前提参见 README 原文。工作原理概览一个自动发现节点池的云提供商从源码结构看Utho 云提供商的实现由三部分构成文件职责utho_cloud_provider.go实现cloudprovider.CloudProvider接口负责装配管理器、对外暴露节点组utho_manager.go解析配置、创建 Utho API 客户端并通过Refresh()定期同步节点池列表utho_node_group.go实现cloudprovider.NodeGroup接口执行具体的扩容、缩容、删节点动作utho-go/封装 Utho 公开 APIhttps://api.utho.com/v2/见 utho.go的 Go 客户端其中最关键的设计决策体现在BuildUthoutho_cloud_provider.go#L181-L204// the cloud provider automatically uses all node pools in Utho. // This means we dont use the cloudprovider.NodeGroupDiscoveryOptions // flags (which can be set via --node-group-auto-discovery or -nodes) return newUthoCloudProvider(manager, rl)从源码可以确认Utho 云提供商会自动接管集群中所有开启了自动扩缩容的节点池而不是通过--nodes或--node-group-auto-discovery参数逐个指定节点组。这意味着部署清单里的--node-group-auto-discoveryutho:regexp.*参数见 cluster-autoscaler-deployment.yaml在实际运行中并不会参与节点组的筛选逻辑节点组的取舍完全取决于节点池自身的自动扩缩容开关状态。整个运行循环为Cluster Autoscaler 主循环每轮调用Refresh()→ 管理器通过ListNodePoolsAPI 拉取全部节点池 → 只保留auto_scaletrue的节点池构造成NodeGroup→ 后续的扩缩容决策都围绕这些节点组展开。必配项cloud-config 配置文件原 README 明确要求必须定义云配置文件cloud-config否则 Cluster Autoscaler 无法启动。缺失时的报错逻辑在 utho_cloud_provider.go#L186-L193if opts.CloudConfig { klog.Fatalf(No config file provided, please specify it via the --cloud-config flag) } configFile, err : os.Open(opts.CloudConfig) if err ! nil { klog.Fatalf(Could not open cloud provider configuration file %q, error: %v, opts.CloudConfig, err) }配置字段说明cloud-config 支持两个字段对应源码中 Config 结构体 的 JSON 标签字段JSON 键是否必填说明cluster_idcluster_id否见下方说明Utho Kubernetes 集群的 IDtokentoken是Utho API 密钥Access Token按字面值写入需要特别说明两点token是硬性必填项。在 newManager 中如果解析后cfg.Token 会直接返回errors.New(access token is not provided)。cluster_id可以省略。如果配置中未提供cluster_id管理器会尝试从集群节点的cluster_id标签中自动获取获取失败才会报错cluster ID is not provided and couldnt be retrieved from nodes。实现位于 utils.go#L46-L69 的getNodeLabel函数——它通过 in-cluster 配置创建 Kubernetes 客户端遍历节点列表查找第一个带该标签的节点。为稳妥起见生产环境仍建议显式填写cluster_id。格式说明JSON 而非 INI值得注意的一个细节原 README 将 cloud-config 描述为 an INI file但从示例文件和源码解析逻辑看实际采用的是 JSON 格式——newManager使用json.Unmarshal解析配置内容utho_manager.go#L64-L72。因此配置时应严格遵循 JSON 语法。仓库提供的官方示例位于 examples/cluster-autoscaler-secret.yaml如下apiVersion: v1 kind: Secret metadata: name: cluster-autoscaler-cloud-config namespace: kube-system type: Opaque stringData: cloud-config: |- { cluster_id: CLUSTER_ID, token: TOEKN }使用Secret保存云配置是推荐的实践将token以 Secret 的形式存放在kube-system命名空间再通过卷挂载到 Autoscaler 容器中避免 API 密钥明文出现在 Deployment 清单里。注意示例中TOEKN为占位符原文拼写即如此实际使用时请替换为真实的 Utho API Token。部署 Cluster AutoscalerDeployment 与 RBAC 解析仓库在 examples/cluster-autoscaler-deployment.yaml 中提供了开箱即用的完整部署清单包含四部分资源ServiceAccountcluster-autoscaler命名空间kube-systemClusterRole Role 对应 Binding授予 Autoscaler 管理节点nodes 的 watch/list/get/update/patch、驱逐 Podpods/eviction 的 create、读取工作负载deployments、statefulsets、daemonsets、jobs 等以及写cluster-autoscaler-statusConfigMap 的权限Deployment核心容器配置如下containers: - name: utho-cluster-autoscaler image: utho/autoscaler:1.0.0 imagePullPolicy: IfNotPresent command: - ./cluster-autoscaler - --v4 - --cloud-providerutho - --cloud-config/config/cloud-config - --node-group-auto-discoveryutho:regexp.* resources: limits: cpu: 100m memory: 300Mi requests: cpu: 100m memory: 300Mi volumeMounts: - name: ssl-certs mountPath: /etc/ssl/certs/ca-certificates.crt readOnly: true - name: cloud-config mountPath: /config readOnly: true volumes: - name: ssl-certs hostPath: path: /etc/ssl/certs/ca-certificates.crt - name: cloud-config secret: secretName: cluster-autoscaler-cloud-config各启动参数的作用参数说明--v4日志级别。Utho 提供商源码在关键路径节点池同步、扩缩容请求大量使用klog.V(4)输出细节故障排查时可保持此级别--cloud-providerutho指定云提供商对应源码中const ProviderName uthoutho_cloud_provider.go#L35--cloud-config/config/cloud-config指向挂载的 cloud-config 文件必须存在且可读--node-group-auto-discoveryutho:regexp.*如前所述Utho 提供商自动接管所有开启自动扩缩容的节点池该参数实际不参与节点组筛选源码中明确不使用NodeGroupDiscoveryOptions部署与验证步骤将 Secret 中的CLUSTER_ID与TOEKN替换为真实值后先创建配置 Secretkubectl apply -f cluster-autoscaler/cloudprovider/utho/examples/cluster-autoscaler-secret.yaml再创建 Deployment 及其 RBAC 资源kubectl apply -f cluster-autoscaler/cloudprovider/utho/examples/cluster-autoscaler-deployment.yaml观察日志确认节点池被发现与接管kubectl -n kube-system logs -l appcluster-autoscaler从源码看utho_manager.go#L102-L145Refresh()会为每个节点池输出node-pool ID: autoscalingtrue/false (min… max…)的 V(4) 日志并跳过auto_scalefalse的池若最终没有任何节点池启用自动扩缩容会输出 cluster-autoscaler is disabled. no node pools are configured。仓库还附带了一个 stress-test.yaml 压测清单创建一个replicas: 10、每个副本请求 750m CPU 的 Deployment可用于验证扩容是否触发。节点池伸缩策略通过 Utho API 而非 Autoscaler 参数配置原 README 强调了一个与多数云提供商不同的关键设计是否监控某节点池、最小/最大节点数等 Autoscaler 相关配置应通过 Utho API 配置——而不是在 Kubernetes 侧通过 Autoscaler 的启动参数或节点组标注来指定。Cluster Autoscaler 会自动拾取这些变更并相应调整行为。从源码印证节点池侧控制自动扩缩容的核心字段定义在 utho-go/kubernetes.go#L133-L146 的NodepoolDetails结构体type NodepoolDetails struct { ID string json:id Size string json:size Count int json:count,string AutoScale bool json:auto_scale,omitempty MinNodes int json:min_size,omitempty MaxNodes int json:max_size,omitempty Workers []WorkerNode json:workers ... }它们与 Autoscaler 行为的对应关系节点池字段影响auto_scale决定该节点池是否被 Autoscaler 接管。Refresh()只对AutoScale true的池构造NodeGrouputho_manager.go#L117-L120min_sizeMinNodes作为节点组的MinSize()缩容下限max_sizeMaxNodes作为节点组的MaxSize()扩容上限count作为当前目标规模TargetSize()这些值通过 Utho 控制台或 Kubernetes APIUpdateKubernetesAutoscaleNodepool请求支持count、min_nodes、max_nodes字段见 kubernetes.go#L690-L701修改后Autoscaler 在下一轮Refresh()中就会自动感知Refresh在每个主循环开始前被调用对应CloudProvider.Refresh()接口约定见 utho_cloud_provider.go#L175-L178节点池的新增、移除或规模边界变化都会被动态应用。源码级剖析NodeGroup 的扩缩容调用链理解了配置层再看NodeGroup如何驱动真实云资源变更。utho_node_group.go实现了cloudprovider.NodeGroup接口其内部持有nodePool缓存NodepoolDetails以及minSize/maxSize。扩容IncreaseSizeIncreaseSize 的流程校验delta 0否则报错计算targetSize nodePool.Count delta若超过MaxSize()则拒绝size increase is too large构造UpdateKubernetesAutoscaleNodepool{ClusterId, NodePoolId, Count}并调用UpdateNodePoolAPI对应POST /v2/kubernetes/{clusterId}/nodepool/{poolId}/update见 kubernetes.go#L720-L735调用ReadNodePool回读实际规模校验是否真的达到targetSize不一致则返回错误成功后更新内部缓存nodePool.Count。缩容DecreaseTargetSize 与 DeleteNodes缩容路径分为两种DecreaseTargetSizeutho_node_group.go#L194-L236用于撤回尚未兑现的新节点请求要求delta 0且结果不得低于MinSize()。它同样通过UpdateNodePool额外携带label: utho.com与size字段调整目标规模并回读校验。DeleteNodesutho_node_group.go#L139-L182真正的节点删除。Autoscaler 决定删除具体节点后为每个节点从节点标签node_id解析出 Utho 侧节点 ID——这是删除流程的硬依赖若节点缺少node_id标签例如尚未注册的虚拟节点会拒绝删除并返回 node ID label is missing调用DeleteNodeAPIDELETE /v2/kubernetes/{clusterId}/nodepool/{poolId}/{nodeId}/delete成功后将本地nodePool.Count减一。节点归属判定与 ProviderIDNodeGroupForNodeutho_cloud_provider.go#L79-L114负责判定节点属于哪个节点组优先读取node.Spec.ProviderID为空时回退到node_id标签随后通过normalizeID剥掉utho://前缀见 utils.go#L72-L74与各节点组内实例 ID 逐一比对。实例 ID 统一格式化为utho://nodeIDtoProviderIDutils.go#L110-L113。扩容模拟TemplateNodeInfoCluster Autoscaler 在做扩容决策时需要预测新节点长什么样。TemplateNodeInfoutho_node_group.go#L289-L340以节点池第一个 worker 为模板合成一个模拟节点CPU 直接取 worker 的Cpu核数内存按Ram * 1024 * 1024MB 转字节计算Pod 容量固定 110并打上kubernetes.io/oslinux、kubernetes.io/archamd64、node.kubernetes.io/instance-type、topology.kubernetes.io/zone、node_id等标签同时附加一个模拟 kube-proxy Pod 以便把 DaemonSet 的资源占用计入模拟见 utils.go#L87-L97 的buildKubeProxy。测试覆盖行为契约的保障Utho 云提供商带有较完整的单元测试既是行为契约也是排查问题时的参考文档utho_node_group_test.go覆盖IncreaseSize含超上限拒绝、API 失败回滚语义、DecreaseTargetSize含负 delta 校验、DeleteNodes含缺失node_id标签、多节点批量删除、worker 状态过滤、TargetSize、TemplateNodeInfo等utho_manager_test.go覆盖配置解析、Refresh对非自动扩缩容池的过滤、空节点池列表等utho_cloud_provider_test.go覆盖 provider 装配、NodeGroupForNode匹配、Refresh错误传播等。开发与构建从源码产出镜像原 README 的 Development 章节给出了构建流程。进入本仓库的cluster-autoscaler目录后make container该命令会在本地构建 Cluster Autoscaler 的 Docker 镜像构建配置见 cluster-autoscaler/Dockerfile 与 cluster-autoscaler/Makefile。构建完成后为生成的镜像打上目标仓库标签再推送到你的镜像仓库即可在 cluster-autoscaler-deployment.yaml 中替换image字段使用。Utho 云提供商的注册入口在utho包的init()函数utho_cloud_provider.go#L37-L42它调用builder.RegisterCloudProvider(utho, ...)将自己注册进 Cloud Provider Builder并被设为默认提供商。注意事项与排障清单cloud-config 必须可读--cloud-config指向的文件不存在或无法打开时Autoscaler 直接Fatalf退出请确认 Secret 卷挂载路径正确。token 错误是最高频故障token为空会在启动阶段直接报错token 无效则 API 调用如ListNodePools返回失败Refresh()报错并导致本轮无法同步节点池。未开启自动扩缩容的节点池不会被管理若日志显示 no node pools are configured请到 Utho 控制台/API 确认目标节点池的auto_scale已开启并设置合理的min_size/max_size。不要期望缩容时指定删除某台节点这是 UKE 平台行为随机选择删除Autoscaler 只负责调用DeleteNodeAPI 按node_id删除最终取舍由 Utho 平台决定。手动删除节点会被自动重建节点池中的节点由 Utho 托管直接kubectl delete node或删除底层实例后Utho 会在一段时间后自动重建这与 Autoscaler 的缩容路径通过 API 删除是两回事。总结Utho 云提供商展示了 Cluster Autoscaler 云提供商抽象的一种极简形态配置仅需cluster_idtoken两个字段节点组完全由云端节点池的auto_scale/min_size/max_size字段驱动无需在 Kubernetes 侧维护节点组清单。理解Refresh()的同步循环、IncreaseSize/DeleteNodes的 API 调用链以及node_id标签的依赖关系是运维好 UKE 上 Cluster Autoscaler 的关键。更多细节可继续研读 utho 云提供商源码目录 及其测试文件。【免费下载链接】autoscalerAutoscaling components for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/au/autoscaler创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考