- 云原生
- 容器编排
- DevOps
【免费下载链接】eksctl
The official CLI for Amazon EKS
导读
本文围绕 eksctl 0.80.0 版本的发布说明(docs/release_notes/0.80.0.md),深入解析该版本的三类核心变更:eksctl utils describe-stacks、update-legacy-subnet-settings、write-kubeconfig三个工具命令正式支持通过 ClusterConfig 文件驱动;集群端点访问控制(publicAccessCIDRs、私有/公开端点)从创建后的二次 API 调用迁移到 CloudFormation 模板一次性配置;以及围绕 IPv6 集群的多项配置修复。读完本文,你将掌握这些命令在 0.80.0 之后的标准用法、ClusterConfig 相关字段的完整语义,以及源码层面的实现原理。
一、版本概览:0.80.0 的核心主题
0.80.0 是 eksctl 发布周期中的一个务实版本,改动集中在"配置一致性"与"模板化治理"两条线上:
- 配置一致性:三个常用的
utils子命令此前只能通过--cluster、--region等命令行参数定位目标集群,0.80.0 让它们支持--config-file,使集群元数据(名称、区域、版本等)统一由 ClusterConfig 文件声明,避免命令行拼错与脚本化调用中的重复参数维护; - 模板化治理:集群端点访问控制(
clusterEndpoints、publicAccessCIDRs)此前由 eksctl 在 CloudFormation 栈创建后再调用 AWS API 二次更新,0.80.0 改为在建栈模板中直接声明ResourcesVpcConfig,让"集群长什么样"一步到位; - IPv6 收尾修复:包括配置文件中的
ipFamily大小写不敏感、移除 IPv6 集群中无意义的 NAT64/DNS64 配置、修正 IPv6 示例的前缀问题。
二、utils 命令拥抱 ClusterConfig 文件
2.1 三个命令的演进背景
在 0.80.0 之前,以下命令只能通过命令行标志指定集群:
| 命令 | 功能 | 新增能力 |
|---|---|---|
eksctl utils describe-stacks | 描述指定集群的 CloudFormation 栈 | 支持--config-file(PR #4597) |
eksctl utils update-legacy-subnet-settings | 为集群公共子网开启MapPublicIpOnLaunch | 支持--config-file(PR #4598) |
eksctl utils write-kubeconfig | 为指定集群写入 kubeconfig 文件 | 支持--config-file(PR #4599) |
三个命令的实现都遵循同一模式:在命令初始化时通过api.NewClusterConfig()创建默认配置,然后注册AddConfigFileFlag(fs, &cmd.ClusterConfigFile)(见 pkg/ctl/utils/describe_stacks.go、pkg/ctl/utils/update_legacy_subnet_settings.go、pkg/ctl/utils/write_kubeconfig.go),运行阶段统一调用cmdutils.NewMetadataLoader(cmd).Load()完成配置加载——该 Loader 专门服务于"只需要元数据字段的简单操作命令"(见 pkg/ctl/cmdutils/configfile.go 中的注释)。
加载完成后,代码会做一次显式的"冲突检测":如果配置文件里已经声明了metadata.name,命令行又额外传入了位置参数(集群名),则直接返回ErrFlagAndArg错误,防止两种来源的配置互相覆盖(三个命令中均有此逻辑)。
2.2 典型用法:以 write-kubeconfig 为例
使用 ClusterConfig 文件后,命令可以这样写:
# 配置文件(cluster.yaml)中声明 metadata.name / region eksctl utils write-kubeconfig --config-file cluster.yaml这与纯命令行方式等价:
eksctl utils write-kubeconfig --cluster <name> --region <region>从源码看(pkg/ctl/utils/write_kubeconfig.go),该命令还支持以下与 kubeconfig 输出相关的标志:
--kubeconfig <path>:指定 kubeconfig 输出路径,默认写入~/.kube/config;--auto-kubeconfig:自动生成形如<cluster-name>-<region>.yaml的独立文件路径(通过kubeconfig.AutoPath),且与--kubeconfig互斥(同时指定会报--kubeconfig and --auto-kubeconfig are incompatible flags);--set-kubeconfig-context:写入后同时将上下文设为当前;--authenticator-role-arn:指定 AWS IAM Authenticator 使用的角色 ARN,用于以特定身份生成凭证。
2.3 describe-stacks:从元数据到栈内幕
describe-stacks在 0.80.0 后可用配置文件定位集群,其完整标志集如下(pkg/ctl/utils/describe_stacks.go):
| 标志 | 说明 |
|---|---|
--all | 包含已删除(DELETE_COMPLETE)的栈 |
--events | 同时输出每个栈的 CloudFormation 事件 |
--resource-status | 按资源状态过滤事件(如CREATE_FAILED、UPDATE_FAILED),必须与--events=true搭配使用 |
--trail | 查询并输出该集群相关的 CloudTrail 事件 |
-o, --output | 结构化输出,仅支持json与yaml;指定后不能再使用上述展示类标志 |
实现上(doDescribeStacksCmd,见 pkg/ctl/utils/describe_stacks.go)会通过ctl.NewStackManager(cfg).ListStacks(ctx)拉取全部栈,并给出一个实用提示:如果发现栈数量少于 2,会警告"就绪集群至少应有 2 个栈"(cluster 栈 + nodegroup 栈)。事件过滤逻辑会对resourceStatus与事件状态做大小写归一化后逐一比对,方便快速定位失败资源。
# 查看某集群所有栈的事件中失败的资源 eksctl utils describe-stacks --config-file cluster.yaml --events --resource-status CREATE_FAILED,UPDATE_FAILED2.4 update-legacy-subnet-settings:让旧公共子网具备 IP 自动分配能力
该命令解决的是一个具体的"历史遗留"问题:较早期创建的公共子网没有开启MapPublicIpOnLaunch(新启动实例自动获得公网 IP),导致无法在其中新建节点组。其实现(pkg/ctl/utils/update_legacy_subnet_settings.go)流程为:
- 通过
MetadataLoader加载配置或标志,确定集群名与区域; stackManager.DescribeClusterStack(ctx)定位集群 CloudFormation 栈;ctl.LoadClusterVPC(ctx, cfg, stack, true)反查集群 VPC 配置,得到公共子网列表;- 调用
stackManager.EnsureMapPublicIPOnLaunchEnabled(ctx)为这些公共子网开启MapPublicIpOnLaunch; - 完成后输出
public subnets up to date。
eksctl utils update-legacy-subnet-settings --config-file cluster.yaml该命令与 VPC 导入逻辑共用同一套子网处理函数(见 pkg/vpc/vpc.go),从源码结构可以推断,它处理的是"子网属于 eksctl 创建但属性过时"的兼容场景。
三、端点访问控制迁入 CloudFormation(PR #4526)
3.1 变更本质:从"事后更新"到"一次成型"
0.80.0 之前,clusterEndpoints与publicAccessCIDRs是在集群栈创建完成后,由 eksctl 再调用一次UpdateClusterConfig类型的 AWS API 来生效的。0.80.0 将其直接固化进 CloudFormation 模板的 EKS Cluster 资源中,一次部署即完成全部配置。
模板中的对应实现位于 pkg/cfn/builder/cluster.go 的addResourcesForControlPlane:
clusterVPC := &gfneks.Cluster_ResourcesVpcConfig{ EndpointPublicAccess: gfnt.NewBoolean(*c.spec.VPC.ClusterEndpoints.PublicAccess), EndpointPrivateAccess: gfnt.NewBoolean(*c.spec.VPC.ClusterEndpoints.PrivateAccess), SecurityGroupIds: c.securityGroups, PublicAccessCidrs: gfnt.NewStringSlice(c.spec.VPC.PublicAccessCIDRs...), }也就是说,ResourcesVpcConfig中的四个关键属性(公开端点、私有端点、控制平面安全组、公网访问 CIDR)在模板生成阶段就从spec.VPC提取并写入。这样可以确保:
- 集群创建时端点访问配置即生效,无需额外的等待与二次 API 调用;
- 创建流程中新增的
WaitForControlPlane冗余调用被移除(PR #4615,对应 pkg/eks/api.go 中定义、pkg/eks/client.go 实现的WaitForControlPlane接口,其内部通过对ServerVersion的连续成功探测来判断控制平面就绪)。
3.2 ClusterConfig 中对应的配置字段
相关字段定义在 pkg/apis/eksctl.io/v1alpha5/vpc.go 与同文件中的ClusterEndpoints结构体(第 237-241 行):
vpc: clusterEndpoints: privateAccess: true # 是否允许 VPC 内私有访问 publicAccess: false # 是否允许公网访问 publicAccessCIDRs: - "1.2.3.4/32" # 允许访问公网 K8s API 端点的 CIDR 列表字段说明:
| 字段 | 类型 | 语义 |
|---|---|---|
vpc.clusterEndpoints.privateAccess | bool | 私有端点访问(仅 VPC 内可达) |
vpc.clusterEndpoints.publicAccess | bool | 公开端点访问 |
vpc.publicAccessCIDRs | []string | 白名单 CIDR,EKS 用它为公开端点创建安全组规则 |
校验层面(pkg/apis/eksctl.io/v1alpha5/validation.go)会通过validateCIDRs对publicAccessCIDRs逐一做 CIDR 合法性校验,非法输入直接报错(对应测试见 pkg/apis/eksctl.io/v1alpha5/validation_test.go)。
3.3 与之配套的运行时命令
尽管创建时已模板化,运行中对既有集群的端点调整仍然保留了两个工具命令(注意源码中均标注为 deprecated,统一指向update-cluster-vpc-config):
eksctl utils update-cluster-vpc-config:统一入口,支持--public-access、--private-access、--public-access-cidrs、--control-plane-subnet-ids、--control-plane-security-group-ids等标志(见 pkg/ctl/utils/update_cluster_vpc_config.go);eksctl utils update-cluster-endpoints:仅调整端点开关,已被前者取代(见 pkg/ctl/utils/update_cluster_endpoint_access.go);eksctl utils set-public-access-cidrs:仅调整 CIDR,同样被取代(见 pkg/ctl/utils/set_public_access_cidrs.go)。
此外,当创建"完全私有"集群时,创建逻辑会自动把publicAccess置为 false 并调用端点更新(见 pkg/ctl/create/cluster.go)。
3.4 对 publicAccessCIDRs 的访问警告
发布说明同时提到 "Add warning to cluster access about publicAccessCIDRs"(PR #4576)。从代码结构看,这一警告的语境是:当用户通过publicAccessCIDRs收紧或扩展公网 API 端点的访问范围时,eksctl 会在创建/更新流程中提示该配置对集群可访问性的直接影响——尤其是当配置的白名单过窄时,kubectl等客户端可能因此无法连接集群。实践中建议将 CI 或办公网出口 IP 明确加入白名单,并在变更后立即验证连通性。
四、IPv6 集群修复集
0.80.0 对 IPv6 配置做了三处收尾,均与配置文件的易用性、正确性直接相关:
4.1ipFamily大小写不敏感(PR #4619)
此前配置文件中的ipFamily是大小写敏感的,ipv6、IPv6、IPV6等写法可能导致校验失败。0.80.0 起该字段在配置加载与校验阶段统一按大小写不敏感处理。
源码中的双重佐证:
- 类型定义与默认值(pkg/apis/eksctl.io/v1alpha5/types.go):
IPV4Family = "IPv4"、IPV6Family = "IPv6",默认DefaultIPFamily = IPV4Family; - 校验逻辑(pkg/apis/eksctl.io/v1alpha5/validation.go):
strings.ToLower(c.KubernetesNetworkConfig.IPFamily)后与ipv4/ipv6比对,非法值报invalid value %q for ipFamily; allowed are IPv4 and IPv6; - 辅助方法
func (k *KubernetesNetworkConfig) IPv6Enabled() bool同样使用strings.EqualFold(见 pkg/apis/eksctl.io/v1alpha5/types.go)。
对应测试覆盖了"iPv6"这类混合大小写写法也能通过校验(见 pkg/apis/eksctl.io/v1alpha5/validation_test.go)。
4.2 移除 IPv6 集群的 NAT64/DNS64(PR #4618)
IPv6 集群的子网不需要 NAT64/DNS64 这类为"纯 IPv6 访问 IPv4 资源"设计的转换机制。0.80.0 移除了 IPv6 子网模板中的相关设置。从模板代码看,CloudFormation 的AWS::EC2::Subnet属性集中仍保留EnableDns64等字段的定义(见 pkg/goformation/cloudformation/ec2/aws-ec2-subnet.go 与 pkg/goformation/schema/cloudformation.go 的 schema 声明),但 IPv6 集群构建路径不再写入这些属性,避免生成无意义甚至引发配置冲突的子网属性。
4.3 修正 IPv6 示例前缀(PR #4605)
示例文件 examples/30-vpc-with-ip-family.yaml 中ipFamily的值此前存在大小写/写法不一致的问题,0.80.0 将其统一为合法的IPv6。该示例本身是一个可复制的完整 IPv6 集群配置,要点包括:
apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: cluster-2 region: us-west-2 version: "1.21" kubernetesNetworkConfig: ipFamily: IPv6 # 开启 IPv6 集群 addons: - name: vpc-cni version: latest attachPolicy: # IPv6 模式需要额外的 IAM 权限 Statement: - Effect: Allow Action: - "ec2:AssignIpv6Addresses" ... - name: coredns - name: kube-proxy iam: withOIDC: true managedNodeGroups: - name: mng-1示例中特别注释了:IPv6 集群的vpc-cni需要ec2:AssignIpv6Addresses等权限来为 Pod 分配 IPv6 地址,因此通过attachPolicy显式声明。配套的 VPC 级 IPv6 能力(autoAllocateIPv6: true)可见于 examples/02-custom-vpc-cidr-no-nodes.yaml。
从模板构建看(pkg/cfn/builder/vpc.go),IPv6 子网 CIDR 由Fn::Cidr在 CloudFormation 运行时从 VPC 自动分配的/56IPv6 块中切出若干/64子网(getSubnetIPv6CIDRBlock),路由相关常量(如InternetIPv6CIDR = "::/0"、PubSubIPv6RouteKey)也一并预置,说明 eksctl 对 IPv6 网络是一等公民式支持。
五、升级建议与验证路径
对于使用 0.80.0 及之后版本的用户,建议按以下顺序对齐用法:
- 脚本迁移:若脚本中使用了
utils describe-stacks、update-legacy-subnet-settings、write-kubeconfig并手工维护--cluster/--region,可将集群元数据收敛到 ClusterConfig 文件,用--config-file替换; - 端点配置声明化:新建集群时直接在
vpc.clusterEndpoints与vpc.publicAccessCIDRs中声明端点策略,享受模板一次成型;存量集群的调整继续使用utils update-cluster-vpc-config; - IPv6 配置规范化:检查既有配置中的
ipFamily写法(大小写均可,但建议统一为IPv6),并参考 examples/30-vpc-with-ip-family.yaml 补齐 vpc-cni 的 IPv6 权限。
需要说明的是,以上内容以 0.80.0 发布说明为核心骨架,实现细节均来自当前仓库源码(pkg/ctl/utils、pkg/cfn/builder、pkg/apis/eksctl.io/v1alpha5等),若你在更新的 eksctl 版本中观察到行为差异,应以对应版本的发布说明与源码为准。
参考路径速查
- 发布说明:docs/release_notes/0.80.0.md
- describe-stacks 实现:pkg/ctl/utils/describe_stacks.go
- update-legacy-subnet-settings 实现:pkg/ctl/utils/update_legacy_subnet_settings.go
- write-kubeconfig 实现:pkg/ctl/utils/write_kubeconfig.go
- 配置文件加载器:pkg/ctl/cmdutils/configfile.go
- 端点访问控制模板生成:pkg/cfn/builder/cluster.go
- VPC 配置字段定义:pkg/apis/eksctl.io/v1alpha5/vpc.go
- IPFamily 类型与默认值:pkg/apis/eksctl.io/v1alpha5/types.go
- 配置校验:pkg/apis/eksctl.io/v1alpha5/validation.go
- IPv6 集群示例:examples/30-vpc-with-ip-family.yaml
- IPv6 子网 CIDR 切分:pkg/cfn/builder/vpc.go
- 云原生
- 容器编排
- DevOps
【免费下载链接】eksctl
The official CLI for Amazon EKS
相关推荐
eksctl 0.8.0 版本解析:SSM 参数仓库 AMI 解析与集群 API 端点访问控制实战指南
eksctl 0.8.0 版本解析:SSM 参数仓库 AMI 解析与集群 API 端点访问控制实战指南 eksctl 0.8.0 是 Amazon EKS 官方
云原生容器编排DevOpseksctl 0.79.0 版本解析:IPv6 集群支持、GitOps 前置校验与多项可靠性修复
eksctl 0.79.0 版本解析:IPv6 集群支持、GitOps 前置校验与多项可靠性修复 导读:本文以 eksctl 0.79.0 版本发布说明( do
云原生容器编排DevOpsHyperf数据迁移革命:告别手动SQL,拥抱版本控制新范式
Hyperf数据迁移革命:告别手动SQL,拥抱版本控制新范式 还在为数据库结构变更而头疼吗?每次上线都要手动执行SQL脚本,担心遗漏或冲突?Hyperf的数据库
后端Web框架微服务RPC框架异步编程
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考