☰
eksctl 0.83.0 版本解读:额外卷映射、节点组驱逐控制与 get nodegroup 能力增强
2026/10/15 18:38:53 网站建设 项目流程
  • 云原生
  • 容器编排
  • DevOps

【免费下载链接】eksctl

The official CLI for Amazon EKS

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

导读

本文围绕 eksctl 0.83.0 版本的发布说明(见 docs/release_notes/0.83.0.md)展开,逐项解析该版本带来的 3 项新功能与 6 项缺陷修复:节点组支持additionalVolumes额外卷映射、get nodegroup为使用自定义 AMI 的托管节点组(MNG)返回 AMI ID、删除集群时新增--disable-nodegroup-eviction选项,以及针对 ASG 名称显示、IPv6 现有 VPC、集群不存在删除逻辑、Karpenter 栈清理等问题的修复。读完本文,你将掌握这些新参数的配置方法与使用场景,并理解其底层实现原理(配置解析、CloudFormation 模板生成与节点排空逻辑)。

一、版本功能总览

eksctl 0.83.0 围绕「节点组的存储与运维体验」做了集中增强,主要包括:

  • Features(新功能)

    1. 允许为节点组配置额外的卷映射(additional volume mappings,PR #4725);
    2. 使用自定义 AMI 的托管节点组在执行get nodegroup时返回 AMI ID(PR #4724);
    3. 删除集群时新增--disable-nodegroup-eviction选项(PR #4659)。
  • Bug Fixes(缺陷修复)

    1. 明确提示「必须提供公有子网」的错误信息(PR #4742);
    2. 修复get nodegroup输出的 ASG 名称问题(PR #4717);
    3. 通过更新节点组堆栈中的Version字段升级非 al2 托管节点组(PR #4666);
    4. 修复使用现有 VPC 创建 IPv6 集群时的 bug(PR #4686);
    5. 修复集群不存在时的删除逻辑(PR #4711);
    6. 删除集群时顺带删除 Karpenter 栈(PR #4710)。

下文将按照「新功能详解 → 缺陷修复解读」的顺序展开,每项均结合当前仓库源码给出实现证据。

二、新功能:节点组额外卷映射(additionalVolumes)

2.1 功能背景

在此之前,eksctl 节点组只支持配置一个根卷(通过volumeSize、volumeType等顶层字段)。0.83.0 引入additionalVolumes字段,允许在一个节点组上同时声明多个数据卷,为数据盘与系统盘分离、按用途挂载独立磁盘等场景提供了原生支持。该能力对托管节点组(managed nodegroups)与非托管节点组(unmanaged nodegroups)均适用。

2.2 配置示例

apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: cluster-with-additional-volumes region: us-west-2 managedNodeGroups: - name: mng-data instanceType: m5.xlarge volumeSize: 40 # 根卷 additionalVolumes: - volumeName: /dev/sdb # 额外数据卷 1 volumeSize: 100 volumeType: gp3 volumeEncrypted: true - volumeName: /dev/sdc # 额外数据卷 2,支持基于快照创建 volumeSize: 200 volumeType: gp3 volumeThroughput: 500 snapshotID: snap-0123456789abcdef0

2.3 字段说明与取值范围

additionalVolumes的元素是VolumeMapping结构体,其定义位于 pkg/apis/eksctl.io/v1alpha5/types.go#L1883-L1903,字段如下:

字段JSON 键说明
VolumeSizevolumeSize卷大小,单位 GB,可选;默认为80(与根卷默认值一致)
VolumeTypevolumeType卷类型,可选,取值为VolumeType系列常量(如gp3、gp2、io1、io2等)
VolumeNamevolumeName设备名,如/dev/sdb,必填
VolumeEncryptedvolumeEncrypted是否加密,可选
VolumeKmsKeyIDvolumeKMSKeyID加密用的 KMS 密钥 ID,可选
VolumeIOPSvolumeIOPS仅io1/io2/gp3类型可设置,可选
VolumeThroughputvolumeThroughput仅gp3类型可设置,可选
SnapshotIDsnapshotID基于快照创建卷时指定,可选

对应的AdditionalVolumes字段挂在NodeGroupBase上,声明于 pkg/apis/eksctl.io/v1alpha5/types.go#L1988,因此nodeGroups与managedNodeGroups均可使用。

2.4 源码实现:默认值与 CloudFormation 映射

从源码实现看,额外卷的能力由「默认值填充」和「CloudFormation 模板生成」两段逻辑协同完成:

  • 默认值填充:setDefaultsForAdditionalVolumes(见 pkg/apis/eksctl.io/v1alpha5/defaults.go#L260-L280)会为未显式指定的额外卷补齐volumeType(默认gp3,Outposts 场景为gp2)、volumeSize(默认80),并根据卷类型填充对应的默认volumeIOPS/volumeThroughput。这意味着你可以在示例中只写volumeName,其余参数由 eksctl 自动补齐。

  • CloudFormation 生成:makeBlockDeviceMappings(见 pkg/cfn/builder/block_device_mapping.go#L15-L61)会把根卷与每个AdditionalVolumes条目一起转换为启动模板(Launch Template)的BlockDeviceMappings;makeBlockDeviceMapping(同文件#L63-L102)负责把VolumeMapping的字段映射为 EBS 配置(VolumeSize、VolumeType、Encrypted、KmsKeyId、Iops、Throughput、SnapshotId),并会跳过未设置卷大小或设备名的条目。

  • 测试佐证:仓库中的单元测试覆盖了「设置 additionalVolumes 时向模板添加额外卷」的断言(见 pkg/cfn/builder/nodegroup_test.go#L1361-L1390 附近),以及带additionalVolumes的托管节点组启动模板黄金文件(pkg/cfn/builder/managed_launch_template_test.go)。集成测试也在真实集群上验证了 Bottlerocket / Ubuntu 节点组挂载额外卷的场景(见 integration/tests/managed/managed_nodegroup_test.go#L471-L509,其中仅声明VolumeName: /dev/sdb即完成挂载,印证了默认值自动填充逻辑)。

三、新功能:get nodegroup 返回自定义 AMI 的 AMI ID

3.1 功能背景

当托管节点组使用自定义 AMI(amiType: CUSTOM或通过启动模板指定自定义镜像)时,用户往往难以直接确认节点实际使用的镜像 ID。0.83.0 之后,eksctl get nodegroup的IMAGE ID列会直接展示该 AMI ID,方便审计与排障。

3.2 使用方法

eksctl get nodegroup --cluster <cluster-name> # 或查询单个节点组 eksctl get nodegroup --cluster <cluster-name> --name <nodegroup-name>

输出中的IMAGE ID列对自定义 AMI 节点组将显示具体的ami-xxxxxxxx形式镜像 ID,而非笼统的CUSTOM类型标记。

3.3 源码实现

该能力实现在getManagedSummary(见 pkg/actions/nodegroup/get.go#L296-L302):

var imageID string if ng.AmiType == ekstypes.AMITypesCustom { // ReleaseVersion contains the AMI ID for custom AMIs. imageID = *ng.ReleaseVersion } else { imageID = string(ng.AmiType) }

代码路径表明:当 EKSDescribeNodegroup返回的AmiType为CUSTOM时,eksctl 从ReleaseVersion字段中读取实际 AMI ID——EKS API 约定ReleaseVersion对自定义 AMI 节点组保存的正是镜像 ID;其余情况则直接展示 AMI 类型。该结果会写入Summary.ImageID并最终呈现在get nodegroup表格输出中。

四、新功能:删除集群时禁用节点组驱逐(--disable-nodegroup-eviction)

4.1 使用场景

eksctl 删除集群时默认对非托管节点组执行 drain(排空),期间会通过 Kubernetes Eviction API 驱逐 Pod。如果集群中存在 PodDisruptionBudget(PDB)策略,且 PDB 限制了同时不可用的副本数,驱逐可能永远无法成功,导致节点无法移除、集群删除卡死。

典型例子:集群安装了aws-ebs-csi-driver,默认会运行两个 Pod,同时其 PDB 策略只允许最多一个 Pod 不可用——删除时另一个 Pod 将「不可驱逐」,造成删除流程阻塞(该场景在 userdocs/src/usage/creating-and-managing-clusters.md#L121-L124 中有明确记载)。

4.2 使用方法

eksctl delete cluster -f cluster.yaml --disable-nodegroup-eviction

该选项强制 drain 流程直接删除 Pod 而非先尝试驱逐,从而绕过 PDB 校验。官方文档提示「use with caution(谨慎使用)」,因为它会跳过 PodDisruptionBudget 的约束,可能造成工作负载非预期中断。

4.3 底层实现链路

从源码结构可以梳理出完整的调用链:

  1. 命令行解析:--disable-nodegroup-eviction注册于 pkg/ctl/delete/cluster.go#L48,默认值为false,帮助文本明确说明「Force drain to use delete, even if eviction is supported. This will bypass checking PodDisruptionBudgets, use with caution.」。该值会连同--force、--pod-eviction-wait-period(默认 10s)、--parallel(默认 1)一起传入删除动作。

  2. 集群删除编排:OwnedCluster.Delete(见 pkg/actions/cluster/owned.go#L125-L159)把该开关透传给drainAllNodeGroups;若集群可操作(CanOperate成功)则先排空所有非托管节点组,drain 出错时只有在--force开启下才继续删除。

  3. 排空参数组装:drainAllNodeGroups(见 pkg/actions/cluster/delete.go#L180-L209)将disableEviction组装进DrainInput,并注明「EKS automatically drains managed nodegroups」,即托管节点组由 EKS 自动排空,该开关只作用于非托管节点组。

  4. 驱逐器判定:底层Evictor.CanUseEvictions(见 pkg/drain/evictor/evictor.go#L76-L80)在disableEviction为真时直接将UseEvictions置为false,跳过对policyAPI 组的探测;随后EvictOrDeletePod(同文件#L126-L133)在禁用驱逐时直接走deletePod分支。

此外,多组集成测试均通过--disable-nodegroup-eviction参数执行真实集群删除(如 integration/tests/accessentries/accessentries_test.go#L519、integration/tests/addons/addons_test.go#L966 等),验证了该开关在带 PDB 场景下的可用性。

五、缺陷修复详解

5.1 明确「必须提供公有子网」的错误提示

当配置要求公有网络(例如非privateNetworking的节点组)但 VPC 中已无可用公有子网时,此前的报错信息不够直观。0.83.0 优化了错误文案,明确告知需要提供公有子网。相关约束在节点组创建校验与 CloudFormation 子网推导中均有体现:例如 pkg/actions/nodegroup/create_test.go#L274-L280 断言「使用privateNetworking: false且 VPC 内无公有子网时创建失败」,提示需通过nodeGroup.subnets手动指定有效公有子网;模板生成侧也存在「could not find public subnets for zones」的校验(见 pkg/cfn/builder/nodegroup_subnets_test.go#L201)。

5.2 修复 get nodegroup 的 ASG 名称

托管节点组背后通常有多个 Auto Scaling Group(例如一个节点组对应多个可用区时)。此前get nodegroup的 ASG 名称展示存在缺陷,0.83.0 修复为返回全部相关 ASG 名称。实现位于getManagedSummary(见 pkg/actions/nodegroup/get.go#L289-L294):遍历DescribeNodegroup返回的ng.Resources.AutoScalingGroups,收集所有名称后用逗号连接写入AutoScalingGroupName(同文件#L316)。对应单元测试断言了多 ASG 场景输出"asg-1,asg-2"(见 pkg/actions/nodegroup/get_test.go#L342)。

5.3 通过更新 Version 字段升级非 al2 托管节点组

此前通过 CloudFormation 堆栈升级托管节点组时,非 Amazon Linux 2(al2)镜像族(如 Bottlerocket、Ubuntu)的升级处理不完整。0.83.0 修复为在升级时同步更新节点组堆栈中的Version字段,使堆栈与 EKS 侧的 Kubernetes 版本保持一致。从模板生成代码看,托管节点组资源的Version属性由managedResource.Version注入(见 pkg/cfn/builder/beta.go#L209),堆栈更新路径(AppendNewClusterStackResource、节点组升级流程)均以该字段为版本变更载体,相关管理逻辑集中在 pkg/cfn/manager/nodegroup.go。

5.4 修复使用现有 VPC 的 IPv6 集群创建

IPv6 集群要求其 VPC 关联 IPv6 CIDR 块;当用户提供现有 VPC(vpc.subnets方式)时,此前存在校验缺失导致创建失败或行为异常的问题。0.83.0 修复后,eksctl 会显式校验现有 VPC 是否已关联 IPv6 CIDR 块:ExistingVPCResourceSet.checkIPv6CidrBlockAssociated(见 pkg/cfn/builder/vpc_existing.go#L98)在 IPv6 模式下通过DescribeVpcs输出检查 IPv6 CIDR 关联情况;校验开关由v.clusterConfig.IPv6Enabled()控制(同文件#L55)。集群级 IPv6 判定定义于 pkg/apis/eksctl.io/v1alpha5/types.go#L1363-L1364。

5.5 修复集群不存在时的删除逻辑

此前在集群已被删除(或从未创建)时执行eksctl delete cluster,可能因集群状态刷新失败而中断,无法继续清理残留的 CloudFormation 栈。0.83.0 修复后,cluster.New(见 pkg/actions/cluster/cluster.go#L22-L55)在RefreshClusterStatusIfStale返回ResourceNotFoundException时将clusterExists置为false:若存在由 eksctl 创建的集群栈则走OwnedCluster删除路径继续清理;若连栈都不存在,则明确报错「cluster %q does not exist」(同文件#L49),不再盲目执行删除。配合--force可在集群栈创建中途失败等场景下继续清理遗留资源(pkg/ctl/delete/cluster.go#L71-L81)。

5.6 删除集群时顺带删除 Karpenter 栈

使用eksctl create cluster的 Karpenter 能力(如 examples/29-cluster-with-karpenter.yaml)会创建额外的 IAM 角色 CloudFormation 栈。此前删除集群不会清理该栈,造成资源残留。0.83.0 修复后,OwnedCluster.Delete在完成主要资源删除后调用deleteKarpenterStackIfExists(见 pkg/actions/cluster/owned.go#L242-L254):通过stackManager.GetKarpenterStack查询 Karpenter 栈,若存在则同步删除(DeleteStackSync),并最终由checkForUndeletedStacks兜底检查是否还有遗留栈(pkg/actions/cluster/delete.go#L156-L178)。对应单元测试验证了「存在 Karpenter 栈时删除流程会调用删除」(见 pkg/actions/cluster/owned_test.go#L114)。

六、升级与验证建议

  • 使用eksctl version确认当前版本;0.83.0 的完整变更条目可查阅 docs/release_notes/0.83.0.md。
  • 验证additionalVolumes:可在测试集群的节点组配置中加入额外卷,创建后通过eksctl get nodegroup --cluster <name>与aws ec2 describe-instances交叉确认块设备映射是否生效。
  • 验证自定义 AMI ID 展示:对使用自定义 AMI 的托管节点组执行eksctl get nodegroup,检查IMAGE ID列。
  • 验证驱逐开关:在存在 PDB 的测试集群上先不带参数执行删除(观察卡住),再使用eksctl delete cluster -f cluster.yaml --disable-nodegroup-eviction完成删除,确认流程绕过 PDB 约束。
  • 注意:--disable-nodegroup-eviction会跳过 PDB 约束,仅应在确认工作负载可接受中断时使用;相关官方使用说明见 userdocs/src/usage/creating-and-managing-clusters.md#L121-L124。
  • 云原生
  • 容器编排
  • DevOps

【免费下载链接】eksctl

The official CLI for Amazon EKS

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

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询