news 2026/10/15 15:24:10

eksctl 配置与管理 EC2 Spot 实例:托管节点组与自管节点组实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
eksctl 配置与管理 EC2 Spot 实例:托管节点组与自管节点组实战指南
  • 云原生
  • 容器编排
  • DevOps

【免费下载链接】eksctl

The official CLI for Amazon EKS

项目地址:https://gitcode.com/gh_mirrors/ek/eksctl
点击查看免费下载

导读

本文围绕 eksctl 对 Amazon EKS 集群中EC2 Spot 实例的完整支持展开:既涵盖通过EKS 托管节点组(Managed Nodegroups)一键创建 Spot 节点池的--spot工作流,也深入讲解自管节点组(Unmanaged Nodegroups)借助 Auto Scaling 的 MixedInstancesPolicy 实现 Spot/On-Demand 混合部署的配置方法。读完后你将掌握spot、instancesDistribution系列字段的语义、默认值与校验规则,能在配置文件与命令行之间自由切换,并学会利用node-lifecycle标签区分两类节点。文中所有参数说明均结合 eksctl 仓库源码(类型定义、校验逻辑、CloudFormation 生成器)进行佐证。

背景:EKS 对 Spot 工作节点的支持方式

EC2 Spot 实例以显著低于按需(On-Demand)的价格提供备用计算容量,适合容错型工作负载。eksctl 从两个维度支持 Spot:

  • 托管节点组:EKS 官方托管节点组能力直接支持 Spot。EKS 会按照 Spot 最佳实践配置并启动一个 Spot 实例的 Auto Scaling 组,并在实例被 AWS 回收(中断)之前自动排空(drain)Spot 工作节点,无需用户自行处理中断流程。该特性没有额外收费,用户只需按实际使用的 AWS 资源(Spot 实例、EBS 卷等)付费。
  • 自管节点组:eksctl 通过 Auto Scaling 组的MixedInstancesPolicy(混合实例策略)支持 Spot,由用户自行控制 Spot 与 On-Demand 的混合比例与分配策略。

托管节点组使用 Spot 实例

通过命令行创建

在创建集群时传入--spot标志,并可选地通过--instance-types指定一个实例类型列表(逗号分隔):

$ eksctl create cluster --spot --instance-types=c3.large,c4.large,c5.large

在已有集群上创建 Spot 托管节点组:

$ eksctl create nodegroup --cluster=<clusterName> --spot --instance-types=c3.large,c4.large,c5.large

这两个标志在命令行层的定义可参见 nodegroup_flags.go:

  • --spot:Create a spot nodegroup (managed nodegroups only),即该标志仅对托管节点组有效。
  • --instance-types:逗号分隔的实例类型列表,例如--instance-types=c3.large,c4.large,c5.large。

eksctl 会校验这两个标志的适用范围:在 configfile.go 的validateManagedNGFlags中,spot、instance-types等标志被列入flagsValidOnlyWithMNG,一旦在未指定--managed的情况下使用,会直接报错--spot is only valid with managed nodegroups (--managed),这一点也被 create/nodegroup_test.go 的测试用例覆盖。

通过配置文件创建

更推荐的做法是把 Spot 配置写进 ClusterConfig 配置文件,可完整复现、可版本化:

# spot-cluster.yaml apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: spot-cluster region: us-west-2 managedNodeGroups: - name: spot instanceTypes: ["c3.large","c4.large","c5.large","c5d.large","c5n.large","c5a.large"] spot: true # `instanceTypes` defaults to [`m5.large`] - name: spot-2 spot: true # On-Demand instances - name: on-demand instanceTypes: ["c3.large", "c4.large", "c5.large"]
$ eksctl create cluster -f spot-cluster.yaml

上述示例对应的完整文件见 examples/26-managed-nodegroup-spot-instances.yaml。要点:

  • spot: true声明该托管节点组使用 Spot 容量;
  • instanceTypes是可选的实例类型列表;不指定时默认使用m5.large;
  • 同一配置文件内可以同时定义 Spot 与 On-Demand 节点组(如示例中的on-demand),按需混布。

注意:自管节点组不支持spot与instanceTypes字段,应改用instancesDistribution字段配置 Spot(见下文)。

底层实现:CapacityType 如何生效

在 ManagedNodeGroup 类型定义 中,Spot bool与InstanceTypes []string是托管节点组的两个独立字段。当生成底层 CloudFormation 模板时,managed_nodegroup.go 会把spot: true翻译为托管节点组资源的CapacityType: SPOT:

if m.nodeGroup.Spot { managedResource.CapacityType = gfnt.NewString("SPOT") }

CapacityType最终会写入 CloudFormation 资源的属性(见 beta.go),对应生成的模板样例可参考 testdata/launch_template/spot.json。也就是说,--spot/spot: true本质上是让 EKS 以 Spot 容量类型来创建和托管节点组。

自管节点组使用 Spot 实例(MixedInstancesPolicy)

自管节点组的 Spot 支持建立在 Auto Scaling 的MixedInstancesPolicy之上。核心配置字段是instancesDistribution,它内嵌在nodeGroups中。使用该字段时,不应再设置nodeGroups.X.instanceType(若一定要设置,只能是"mixed",否则校验直接拒绝,见下文)。

经典场景一:50% Spot + 50% On-Demand 混合

nodeGroups: - name: ng-1 minSize: 2 maxSize: 5 instancesDistribution: maxPrice: 0.017 instanceTypes: ["t3.small", "t3.medium"] # At least one instance type should be specified onDemandBaseCapacity: 0 onDemandPercentageAboveBaseCapacity: 50 spotInstancePools: 2

这个配置对应完整示例 examples/08-spot-instances.yaml:

  • minSize: 2/maxSize: 5:节点组容量范围为 2~5;
  • maxPrice: 0.017:单个 Spot 实例愿意支付的最高价格(美元/小时);
  • instanceTypes:参与混合的实例类型列表,至少指定一个实例类型;
  • onDemandBaseCapacity: 0:On-Demand 基础容量为 0;
  • onDemandPercentageAboveBaseCapacity: 50:基础容量之上,On-Demand 与 Spot 的比例为 50/50;
  • spotInstancePools: 2:在 2 个 Spot 实例池之间分散容量。

经典场景二:GPU 实例全 Spot

nodeGroups: - name: ng-gpu instanceType: mixed desiredCapacity: 1 instancesDistribution: instanceTypes: - g5.xlarge - g5.8xlarge - g5.16xlarge maxPrice: 0.50

这里展示了instanceType: mixed的合法用法:当使用instancesDistribution时,instanceType要么不设置,要么显式设为mixed。g5 系列是支持 GPU 加速的实例,配合较高的maxPrice: 0.50提高中断风险下的竞价竞争力。

经典场景三:capacity-optimized 分配策略

nodeGroups: - name: ng-capacity-optimized minSize: 2 maxSize: 5 instancesDistribution: maxPrice: 0.017 instanceTypes: ["t3.small", "t3.medium"] # At least one instance type should be specified onDemandBaseCapacity: 0 onDemandPercentageAboveBaseCapacity: 50 spotAllocationStrategy: "capacity-optimized"

经典场景四:capacity-optimized-prioritized 分配策略

nodeGroups: - name: ng-capacity-optimized-prioritized minSize: 2 maxSize: 5 instancesDistribution: maxPrice: 0.017 instanceTypes: ["t3a.small", "t3.small"] # At least two instance types should be specified onDemandBaseCapacity: 0 onDemandPercentageAboveBaseCapacity: 0 spotAllocationStrategy: "capacity-optimized-prioritized"

capacity-optimized-prioritized的使用要点:按优先级从高到低排列instanceTypes列表(列表中第一个为最高优先级),EC2 Auto Scaling 会在尽力尊重实例类型优先级的同时优先保障容量。它适合"既要最小化中断可能性、又对某些实例类型有偏好"的工作负载。

约束规则:设置spotAllocationStrategy时,不能同时设置spotInstancePools;若spotAllocationStrategy未指定,EC2 默认使用lowest-price策略。

最小示例

nodeGroups: - name: ng-1 instancesDistribution: instanceTypes: ["t3.small", "t3.medium"] # At least one instance type should be specified

只提供instancesDistribution.instanceTypes即可让节点组以 Spot 为主运行,其余参数全部走默认值(见下文参数表)。

底层实现:instancesDistribution 如何映射到 CloudFormation

在 nodegroup.go 的mixedInstancesPolicy函数中,instancesDistribution的每个字段被逐一对齐到 Auto Scaling 的 MixedInstancesPolicy:

  • instanceTypes生成LaunchTemplate.Overrides列表(每个实例类型一个 override);
  • maxPrice→InstancesDistribution.SpotMaxPrice(仅当显式指定时写入,否则 AWS 默认采用 On-Demand 价格);
  • onDemandBaseCapacity→InstancesDistribution.OnDemandBaseCapacity;
  • onDemandPercentageAboveBaseCapacity→InstancesDistribution.OnDemandPercentageAboveBaseCapacity;
  • spotInstancePools→InstancesDistribution.SpotInstancePools;
  • spotAllocationStrategy→InstancesDistribution.SpotAllocationStrategy。

此外,capacityRebalance: true会在生成模板时被写入 ASG 资源的CapacityRebalance属性(见 nodegroup.go),用于开启 Spot 容量再平衡,对应测试用例见 nodegroup_test.go。托管节点组一侧则不支持instancesDistribution字段(见 nodegroup-managed.md)。

instancesDistribution 参数详解

以下参数定义与默认值出自 NodeGroupInstancesDistribution 结构体:

参数是否必填默认值取值范围/说明
instanceTypes是(+required)无参与混合的实例类型列表,至少指定一个实例类型
maxPrice否On-Demand 价格Spot 实例愿意支付的最高小时价格;不设置时 AWS 默认按 On-Demand 价格竞价
onDemandBaseCapacity否0混合策略中 On-Demand 基础容量(台数)
onDemandPercentageAboveBaseCapacity否100基础容量之上 On-Demand 所占百分比,范围0-100
spotInstancePools否2Spot 实例池数量,范围1-20;与spotAllocationStrategy互斥
spotAllocationStrategy否EC2 默认lowest-price支持lowest-price、capacity-optimized、capacity-optimized-prioritized等
capacityRebalance否false是否开启 Spot 容量再平衡

完整的 JSON Schema 可从配置文档 userdocs/src/usage/schema.md 了解入口;该 schema 现已迁移到 AWS 文档体系,可通过eksctl utils schema在本地直接获取原始 JSON Schema。

校验规则(源码级)

validateInstancesDistribution 是这一切约束的"裁判",核心规则如下:

  • 使用instancesDistribution(或 instance selector)时,instanceType必须为空或等于"mixed",否则报错instanceType should be "mixed" or unset when using the instances distribution feature;
  • instanceTypes不能为空,且去重后的数量不能超过 20;
  • onDemandBaseCapacity必须大于等于 0;
  • onDemandPercentageAboveBaseCapacity必须在 0~100 之间;
  • spotInstancePools必须在 1~20 之间;
  • 设置spotInstancePools的同时设置spotAllocationStrategy为capacity-optimized或capacity-optimized-prioritized会直接报错(两个策略互斥);
  • spotAllocationStrategy的合法值由 validateSpotAllocationStrategy 对照 AWS SDK 的SpotAllocationStrategy枚举校验(包含lowest-price、diversified、capacity-optimized、capacity-optimized-prioritized、price-capacity-optimized等)。

上述规则均有对应的 Ginkgo 测试用例佐证,见 validation_test.go,例如:

  • spotInstancePools should be between 1 and 20;
  • percentageAboveBase should be between 0 and 100;
  • spotInstancePools cannot be specified when also specifying spotAllocationStrategy: capacity-optimized(-prioritized);
  • spotAllocationStrategy should be one of: [lowest-price diversified capacity-optimized capacity-optimized-prioritized price-capacity-optimized]。

用 node-lifecycle 标签区分 Spot 与 On-Demand 节点

在混合部署场景中,调度层(如 cluster-autoscaler、拓扑感知调度)往往需要知道一个节点到底是 Spot 还是 On-Demand。eksctl 会在节点引导阶段自动打上 Kubernetes 标签node-lifecycle,其值为spot或on-demand。

该逻辑实现在节点引导脚本 bootstrap.helper.sh 中:

INSTANCE_LIFECYCLE="$(get_metadata instance-life-cycle)" ... NODE_LABELS="${NODE_LABELS},node-lifecycle=${INSTANCE_LIFECYCLE},alpha.eksctl.io/instance-id=${INSTANCE_ID}"

脚本通过 IMDSv2 获取instance-life-cycle元数据(spot/on-demand),并将其注入 kubelet 的--node-labels参数。因此,你可以放心地在工作负载的 nodeSelector / nodeAffinity 中使用node-lifecycle: spot或node-lifecycle: on-demand来精确控制 Pod 落到哪类节点上,这是处理 Spot 中断、实现"关键任务走 On-Demand、弹性任务走 Spot"的常用手段。

CLI 与配置文件的兼容性边界

使用命令行时还有几点值得注意(同样有源码依据):

  • --spot、--instance-types是托管节点组专属标志;自管节点组只能通过配置文件中的instancesDistribution表达 Spot 需求,命令行上并没有等价的 Spot 标志;
  • 当命令行标志与配置文件同时使用时,configfile.go 将spot、instance-types、nodes、node-type等列入commonNGFlagsIncompatibleWithConfigFile,即这些标志不能与-f配置文件混用,防止"双源配置"产生歧义。

小结

  • 托管节点组:--spot或spot: true+ 可选instanceTypes(默认m5.large),底层映射为 EKS 的CapacityType: SPOT,由 EKS 自动完成 Spot 中断前的节点排空,零增量成本;
  • 自管节点组:通过instancesDistribution驱动 MixedInstancesPolicy,可精细控制 Spot/On-Demand 比例、竞价上限、实例池数量与分配策略(lowest-price/capacity-optimized/capacity-optimized-prioritized);
  • 字段互斥:spotInstancePools与spotAllocationStrategy(capacity 类)互斥,instanceType与instancesDistribution互斥(仅允许"mixed");
  • 节点识别:node-lifecycle: spot|on-demand标签由 eksctl 引导脚本自动注入,可作为工作负载调度的可靠依据。

推荐从 examples/08-spot-instances.yaml 与 examples/26-managed-nodegroup-spot-instances.yaml 两个最小可用示例起步,先eksctl create cluster -f <file> --dry-run查看将要生成的资源,再实际落地到你的集群。

  • 云原生
  • 容器编排
  • DevOps

【免费下载链接】eksctl

The official CLI for Amazon EKS

项目地址:https://gitcode.com/gh_mirrors/ek/eksctl
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/15 15:23:48

MilkShape 3D 1.8.2 老游戏模型转换与建模实战指南

简介&#xff1a;MilkShape 3D 1.8.2是一款面向游戏开发者和模型爱好者的轻量级三维建模工具&#xff0c;尤其适合中世纪二代游戏模型的初级修改。该版本运行更稳定&#xff0c;界面布局清晰&#xff0c;各工具面板一目了然&#xff0c;即便是零基础玩家也能快速上手&#xff1…

作者头像 李华
网站建设 2026/10/15 15:23:44

macOS VMware Fusion共享文件夹原理与实战配置指南

1. 项目概述&#xff1a;为什么在 macOS 上的 VMware Fusion 虚拟机里装 VMware Tools 共享文档&#xff0c;不是“可选项”&#xff0c;而是“必选项”如果你正在用 macOS 主机运行 VMware Fusion&#xff0c;并在里面跑着 Windows、Linux 或其他操作系统的虚拟机&#xff0c;…

作者头像 李华
网站建设 2026/10/15 15:23:40

Go语言CGO实战:跨语言调用的核心原理与避坑指南

如果你是一个长期写 Go 的人&#xff0c;迟早会遇到“这功能标准库真没有&#xff0c;但生态里有个 C 库已经写好了”的时刻&#xff1b;又或者你已经把 Go 的调度模型和内存模型聊得头头是道&#xff0c;结果一碰到import "C"心里就发怵。这个import "C"&…

作者头像 李华
网站建设 2026/10/15 15:22:57

统一服务接入的工程分层:受理、分流与闭环怎么设计

做智能运维平台的服务侧建设时&#xff0c;统一服务接入常被理解成一个前端问题&#xff1a;把入口收拢、把页面做干净。但真正决定它能不能长期成立的&#xff0c;是后端的三件事——请求有没有被统一承接、分类逻辑由谁承担、处理状态如何回传给用户。这三件事都属于工程分层…

作者头像 李华
网站建设 2026/10/15 15:22:55

Django Rest Framework实战:模拟豆瓣API全流程

用Django Rest Framework模拟豆瓣API说来也巧&#xff0c;豆瓣这个产品在中文互联网里存在了这么多年&#xff0c;经历了那么多轮冲击&#xff0c;大家骂归骂&#xff0c;可一旦想查一本书、一部电影的口碑&#xff0c;下意识还是会打开它。它的核心业务其实不复杂&#xff1a;…

作者头像 李华
网站建设 2026/10/15 15:22:33

COMSOL激光加工通孔仿真:高斯热源与脉冲激光建模实操指南

做激光加工仿真这几年&#xff0c;我一直觉得“打孔”这个工况是入门多物理场耦合最好的练手案例。原因很简单&#xff1a;几何边界清楚、物理机制明确、软件操作有章可循&#xff0c;但真正把孔“打穿”并得到一张漂亮的温度场演化图&#xff0c;中间的坑远比你想象的要多。今…

作者头像 李华