news 2026/9/18 14:08:32

terraform-aws-eks 实战 FAQ 全解析:启动模板、节点注册、安全组与 Add-on 配置排障指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
terraform-aws-eks 实战 FAQ 全解析:启动模板、节点注册、安全组与 Add-on 配置排障指南

terraform-aws-eks 实战 FAQ 全解析:启动模板、节点注册、安全组与 Add-on 配置排障指南

【免费下载链接】terraform-aws-eksTerraform module to create Amazon Elastic Kubernetes (EKS) resources 🇺🇦项目地址: https://gitcode.com/GitHub_Trending/te/terraform-aws-eks

本文基于 terraform-aws-eks 官方文档 docs/faq.md,结合仓库源码,系统解答使用该 Terraform 模块创建 Amazon EKS 集群时最高频的 7 类问题:为什么disk_size/remote_access不生效、安全组标签冲突报错、节点无法注册、desired_size修改无变化、如何读取计算资源输出属性,以及如何查询 EKS Add-on 的可用版本与配置 Schema。读完本文,你将掌握这些常见"坑"的根因,并能给出可直接落地的 Terraform 配置修复方案。

一、为什么设置了disk_sizeremote_access却没有任何变化?

这是使用本模块创建 EKS 托管节点组(EKS Managed Node Group)时最常见的问题之一。根因在于:disk_sizeremote_access只有在使用 EKS 托管节点组默认启动模板(default launch template)时才有效

本模块默认会为节点组提供自定义启动模板(custom launch template),目的是支持自定义安全组、标签传播(tag propagation)、用户数据(user data)等高级能力。一旦使用自定义启动模板,EKS 服务端便不允许在节点组层面直接设置disk_size(磁盘大小)和remote_access(SSH 远程访问)——这两个值应当定义在启动模板本身。

这一约束在源码中有明确体现。在 modules/eks-managed-node-group/main.tf#L484 中:

disk_size = var.use_custom_launch_template ? null : var.disk_size # if using a custom LT, set disk size on custom LT or else it will error here

也就是说,只要use_custom_launch_template = true(模块默认值),传入的disk_size会被直接置为null,自然"没有任何变化"。对应的变量声明同样强调了使用前提,见 modules/eks-managed-node-group/variables.tf#L517-L521(disk_sizeOnly valid whenuse_custom_launch_template=false)与 modules/eks-managed-node-group/variables.tf#L553-L560(remote_access:同样限定)。

解决方案

如果你确实需要放弃自定义启动模板,改由 EKS 使用默认启动模板,可以在节点组定义中显式关闭它:

module "eks" { source = "terraform-aws-modules/eks/aws" version = "~> 21.0" name = "my-cluster" kubernetes_version = "1.33" vpc_id = "vpc-1234556abcdef" subnet_ids = ["subnet-abcde012", "subnet-bcde012a", "subnet-fghi345a"] eks_managed_node_groups = { example = { use_custom_launch_template = false disk_size = 100 # 仅在 use_custom_launch_template = false 时生效 remote_access = { ec2_ssh_key = "my-key-pair" source_security_group_ids = ["sg-0123456789abcdef0"] } instance_types = ["m5.xlarge"] min_size = 2 max_size = 10 desired_size = 2 } } }

需要权衡的是:关闭自定义启动模板后,你将失去模块提供的自定义安全组挂载、标签传播、cloudinit_pre_nodeadm/post_bootstrap_user_data等扩展能力。大多数生产场景建议保留自定义启动模板,并通过block_device_mappings配置磁盘大小、通过key_name配置 SSH 密钥,效果相同且能力更完整。

二、报错expect exactly one securityGroup tagged with kubernetes.io/cluster/<CLUSTER_NAME> ...如何解决?

⚠️ 提示:错误信息中的<CLUSTER_NAME>即你的集群名称,例如my-cluster

错误根因

默认情况下,EKS 服务会创建一个集群主安全组(cluster primary security group),它由 EKS 服务在模块之外创建,并被打上标签:

{ "kubernetes.io/cluster/<CLUSTER_NAME>" = "owned" }

这个标签本身并不会引发冲突,直到用户决定同时挂载以下两个安全组到同一批节点上:

  1. 集群主安全组(cluster primary security group);
  2. 模块创建的共享节点安全组(shared node security group)——通过设置attach_cluster_primary_security_group = true触发。

问题的关键不在于账号下存在多个带有该key:value标签组合的安全组,而在于同一集群的节点上同时挂载了多个带有该标签的安全组。像 AWS Load Balancer Controller 这类依赖该标签发现集群安全组的 Add-on,会因"期望恰好一个"而报错。

从源码可以看到,模块创建的共享节点安全组确实带上了这个标签,见 node_groups.tf#L187-L194:

tags = merge( var.tags, { "Name" = local.node_sg_name "kubernetes.io/cluster/${var.name}" = "owned" }, var.node_security_group_tags )

同时,模块在 node_groups.tf#L70-L74 中默认创建该共享节点安全组:

create_node_sg = var.create && var.create_node_security_group

解决方案

根据你的使用意图,有两种方式:

方案一:使用集群主安全组,禁用共享节点安全组的创建

module "eks" { source = "terraform-aws-modules/eks/aws" version = "~> 21.0" # ... 其他配置 create_node_security_group = false # 默认是 true eks_managed_node_groups = { example = { attach_cluster_primary_security_group = true # 默认是 false } } # 或者对于 self-managed 节点组: # self_managed_node_groups = { # example = { # attach_cluster_primary_security_group = true # 默认是 false # } # } }

方案二:不挂载集群主安全组

集群主安全组的访问权限相当宽泛;模块转而提供了一个以最小权限启动空 EKS 集群的安全组,并鼓励用户按需放开访问以满足工作负载。这也是模块的默认行为:

eks_managed_node_groups = { example = { attach_cluster_primary_security_group = false # 默认是 false } } # 或者对于 self-managed # self_managed_node_groups = { # example = { # attach_cluster_primary_security_group = false # 默认是 false # } # }

理论上,如果你选择挂载集群主安全组,就不应该再使用模块创建的共享节点安全组;反之亦然。具体取舍由你根据自身需求和用例决定。

附加提醒:Custom Networking

如果你使用了 EKS 的Custom Networking(自定义 CNI 网络,通过ENIConfig指定子网与安全组),请务必在ENIConfig资源中只挂载上面你选定方案对应的安全组,避免冗余标签再次引发同样的问题。

三、节点为什么无法注册到集群?

节点无法与 EKS 控制面完成注册(NotReady/ 未出现在kubectl get nodes中),绝大多数情况下是网络配置问题。请按以下顺序排查:

1. 至少启用一个集群端点

集群的公开端点(public endpoint)与私有端点(private endpoint)至少需要启用一个

如果你需要使用公开端点,推荐同时启用公开与私有端点,并通过cluster_endpoint_public_access_cidrs限制公开端点的访问来源。关于与端点的通信方式,可参考 AWS EKS 官方文档中关于集群端点的说明。

2. 节点必须能够访问集群端点

模块默认只创建公开端点(variables.tf#L142-L146 中endpoint_public_access默认false,而 main.tf#L78-L85 中端点的启用与 CIDR 限制会原样传给aws_eks_clustervpc_config)。因此节点需要出站公网访问能力

  • 私有子网中的节点:需要 NAT 网关或 NAT 实例,并配置好对应的路由规则;
  • 公有子网中的节点:确保节点以公网 IP 启动(通过模块配置或子网设置默认值)。

⚠️重要:如果你只启用公开端点,并通过cluster_endpoint_public_access_cidrs限制访问来源,请务必注意——EKS 节点同样会走公开端点,你必须把节点的出网 IP(或所在子网的 CIDR)加入白名单。否则节点将无法正常工作。

3. 启用私有端点时的 VPC 前提

你也可以通过设置cluster_endpoint_private_access = true启用私有端点(该变量默认即为true,见 variables.tf 中endpoint_private_access的定义)。启用私有端点时,请确保 VPC 的DNS 解析(DNS resolution)和 DNS 主机名(DNS hostnames)都已开启。

4. 节点访问其他 AWS 服务的能力

节点还需要连接其他 AWS 服务才能正常工作(下载容器镜像、调用 API 完成角色代入等)。如果出于安全原因无法为节点开通公网访问,可以为相关服务添加VPC Endpoint:EC2 API、ECR API、ECR DKR 以及 S3。

模块侧的时序保障

另外,模块在集群创建与数据面(节点组、Fargate Profile)创建之间内置了一个等待期time_sleep,默认 30 秒(node_groups.tf#L10-L23,对应根模块变量dataplane_wait_duration,默认"30s")。它的作用是给需要先于数据面配置的 Add-on 留出创建与自配置的时间。如果集群刚创建完成节点就立即注册失败,也可以适当调大该值。

四、修改节点组的desired_size为什么没有任何变化?

这是模块的有意设计,不是 bug。模块通过lifecycle.ignore_changes显式忽略了desired_size的变更,见 modules/eks-managed-node-group/main.tf#L561-L566:

lifecycle { create_before_destroy = true ignore_changes = [ scaling_config[0].desired_size, ] }

原因是:Terraform 的lifecycle块中不支持变量(无法写成ignore_changes = [scaling_config[0].desired_size]的条件式),因此模块选择无条件忽略该值,从而保证Cluster Autoscaler、Karpenter 等自动扩缩容控制器可以独立调整节点数量,而不会被 Terraform 的下一轮apply覆盖回去。

因此,节点组创建完成后,修改期望节点数必须绕过 Terraform,例如:

  • 由 Cluster Autoscaler / Karpenter 自动扩缩容;
  • 通过aws eks update-nodegroup-config等 AWS API/CLI 手动调整;
  • 使用社区提供的eks-desired-size-hack类方案绕开该限制(该方案利用 Terraform 的triggers/外部数据源技巧,在保留ignore_changes的同时仍能通过 Terraform 驱动desired_size,具体原理可参考该项目说明)。

注意:min_sizemax_size不在忽略之列,仍然可以通过 Terraform 正常修改。

五、如何访问计算资源(节点组 / Fargate)的属性?

根模块通过module.eks_managed_node_groupmodule.self_managed_node_groupmodule.fargate_profile三个子模块管理计算资源,并把它们的完整属性以 Map 形式暴露为输出。以下示例假设你的集群模块定义命名为eks(即module "eks" { ... })。

EKS Managed Node Group 属性

eks_managed_role_arns = [for group in module.eks_managed_node_group : group.iam_role_arn]

iam_role_arn是子模块输出之一,见 modules/eks-managed-node-group/outputs.tf#L73-L76。同一个子模块还输出了node_group_arnnode_group_autoscaling_group_nameslaunch_template_idsecurity_group_id等丰富属性,可组合使用。

Self Managed Node Group 属性

self_managed_role_arns = [for group in module.self_managed_node_group : group.iam_role_arn]

对应子模块输出见 modules/self-managed-node-group/outputs.tf#L88-L96,此外还可取autoscaling_group_nameiam_instance_profile_arnaccess_entry_arn等。

Fargate Profile 属性

fargate_profile_pod_execution_role_arns = [for group in module.fargate_profile : group.fargate_profile_pod_execution_role_arn]

fargate_profile_pod_execution_role_arn在 modules/fargate-profile/outputs.tf#L39-L42 中定义。

根模块输出汇总

根模块在 outputs.tf#L259-L281 中同样暴露了这三类资源整体:

  • module.eks.eks_managed_node_groups—— 所有托管节点组属性 Map;
  • module.eks.eks_managed_node_groups_autoscaling_group_names—— 托管节点组对应的 Auto Scaling Group 名称列表;
  • module.eks.self_managed_node_groups/module.eks.self_managed_node_groups_autoscaling_group_names
  • module.eks.fargate_profiles—— 所有 Fargate Profile 属性 Map。

这样你可以在其他模块中直接消费这些属性,例如为节点组 IAM 角色配置额外的信任策略或附加策略。

六、有哪些 EKS Add-on 可以使用?

EKS Add-on 的可用清单由 AWS EKS 服务本身维护,会随区域和 Kubernetes 版本变化。官方可用列表见 AWS EKS 用户指南中的 Add-on 文档页;你也可以直接通过 AWS CLI 查询当前账号可用区域内的全部 Add-on 名称:

aws eks describe-addon-versions --query 'addons[*].addonName'

常见的 EKS 官方 Add-on 包括:corednskube-proxyvpc-cni(Amazon VPC CNI)、eks-pod-identity-agentaws-ebs-csi-driveraws-efs-csi-driveraws-load-balancer-controller等。本模块在 main.tf#L769-L866 中通过aws_eks_addonaws_eks_addon.before_compute两个资源实现 Add-on 管理,并支持before_compute标记——将vpc-cnieks-pod-identity-agent等设为before_compute = true,可以保证它们在数据面计算资源创建之前完成部署(这也是 README.md 中 EKS Managed Node Group 示例的推荐写法)。

模块中一个典型的 Add-on 配置示例(来自 README.md):

addons = { coredns = {} eks-pod-identity-agent = { before_compute = true } kube-proxy = {} vpc-cni = { before_compute = true } }

七、某个 Add-on 支持哪些配置值(configuration values)?

[!NOTE] 可用配置值会随 Add-on 版本变化——随着 EKS 为后续版本开放更多功能,通常会有更多配置项被加入。

查询配置 Schema 的命令

对于给定的 Add-on 名称与版本,可以通过以下命令获取其配置值的 JSON Schema:

aws eks describe-addon-configuration --addon-name <value> --addon-version <value> --query 'configurationSchema' --output text | jq

例如,查询 CoreDNSv1.11.1-eksbuild.8的配置 Schema:

aws eks describe-addon-configuration --addon-name coredns --addon-version v1.11.1-eksbuild.8 --query 'configurationSchema' --output text | jq

返回结果示例

(以下为撰写本文时该命令的返回结果,随版本演进可能不同)

{ "$ref": "#/definitions/Coredns", "$schema": "http://json-schema.org/draft-06/schema#", "definitions": { "Coredns": { "additionalProperties": false, "properties": { "affinity": { "default": { "affinity": { "nodeAffinity": { "requiredDuringSchedulingIgnoredDuringExecution": { "nodeSelectorTerms": [ { "matchExpressions": [ { "key": "kubernetes.io/os", "operator": "In", "values": ["linux"] }, { "key": "kubernetes.io/arch", "operator": "In", "values": ["amd64", "arm64"] } ] } ] } }, "podAntiAffinity": { "preferredDuringSchedulingIgnoredDuringExecution": [ { "podAffinityTerm": { "labelSelector": { "matchExpressions": [ { "key": "k8s-app", "operator": "In", "values": ["kube-dns"] } ] }, "topologyKey": "kubernetes.io/hostname" }, "weight": 100 } ] } } }, "description": "Affinity of the coredns pods", "type": ["object", "null"] }, "computeType": { "type": "string" }, "corefile": { "description": "Entire corefile contents to use with installation", "type": "string" }, "nodeSelector": { "additionalProperties": { "type": "string" }, "type": "object" }, "podAnnotations": { "properties": {}, "title": "The podAnnotations Schema", "type": "object" }, "podDisruptionBudget": { "description": "podDisruptionBudget configurations", "enabled": { "default": true, "description": "the option to enable managed PDB", "type": "boolean" }, "maxUnavailable": { "anyOf": [ { "pattern": ".*%$", "type": "string" }, { "type": "integer" } ], "default": 1, "description": "minAvailable value for managed PDB, can be either string or integer; if it's string, should end with %" }, "minAvailable": { "anyOf": [ { "pattern": ".*%$", "type": "string" }, { "type": "integer" } ], "description": "maxUnavailable value for managed PDB, can be either string or integer; if it's string, should end with %" }, "type": "object" }, "podLabels": { "properties": {}, "title": "The podLabels Schema", "type": "object" }, "replicaCount": { "type": "integer" }, "resources": { "$ref": "#/definitions/Resources" }, "tolerations": { "default": [ { "key": "CriticalAddonsOnly", "operator": "Exists" }, { "effect": "NoSchedule", "key": "node-role.kubernetes.io/control-plane" } ], "description": "Tolerations of the coredns pod", "items": { "type": "object" }, "type": "array" }, "topologySpreadConstraints": { "description": "The coredns pod topology spread constraints", "type": "array" } }, "title": "Coredns", "type": "object" }, "Limits": { "additionalProperties": false, "properties": { "cpu": { "type": "string" }, "memory": { "type": "string" } }, "title": "Limits", "type": "object" }, "Resources": { "additionalProperties": false, "properties": { "limits": { "$ref": "#/definitions/Limits" }, "requests": { "$ref": "#/definitions/Limits" } }, "title": "Resources", "type": "object" } } }

如何理解并应用到模块中

这份 Schema 展示了该 Add-on 版本支持的所有可配置字段、类型、默认值与校验规则(如replicaCount为整数、tolerations为对象数组、resources.limits.cpu为字符串等)。拿到 Schema 后,你就可以在模块的addons配置中通过configuration_values传入自定义 JSON/YAML:

addons = { coredns = { addon_version = "v1.11.1-eksbuild.8" configuration_values = jsonencode({ replicaCount = 2 resources = { requests = { cpu = "100m" memory = "128Mi" } limits = { cpu = "200m" memory = "256Mi" } } }) } }

模块会将configuration_values原样传递给aws_eks_addon资源(见 main.tf#L779 中configuration_values = each.value.configuration_values的透传逻辑)。注意additionalProperties: false意味着不能传入 Schema 未定义的字段,否则 EKS 会拒绝该配置,因此务必先通过上面的 CLI 命令确认当前版本支持的确切字段。

总结

本文覆盖的 7 个 FAQ 都来自模块维护者长期收集的真实使用场景:

问题根因关键配置/命令
disk_size/remote_access不生效自定义启动模板接管了这些参数use_custom_launch_template = false
安全组标签冲突报错同一批节点挂了两个带kubernetes.io/cluster/<NAME>标签的安全组create_node_security_group/attach_cluster_primary_security_group
节点无法注册端点未启用或节点无法访问端点/AWS 服务endpoint_public_accesscluster_endpoint_public_access_cidrs、VPC Endpoint
desired_size修改无变化模块lifecycle.ignore_changes有意忽略由 Autoscaler/Karpenter 或 AWS API 调整
读取计算资源属性子模块输出为 Mapmodule.eks_managed_node_group/module.fargate_profile等输出
可用的 Add-on由 EKS 服务维护aws eks describe-addon-versions
Add-on 配置值随版本变化的 JSON Schemaaws eks describe-addon-configuration

建议在排障时先对照 docs/faq.md 定位问题类别,再结合 README.md 中的完整示例(EKS Managed Node Group、EKS Auto Mode、Karpenter、Hybrid Nodes 等场景)与 main.tf、node_groups.tf 等源码确认参数语义。如需进一步了解数据面细节,可继续阅读 docs/compute_resources.md 与 docs/network_connectivity.md。

【免费下载链接】terraform-aws-eksTerraform module to create Amazon Elastic Kubernetes (EKS) resources 🇺🇦项目地址: https://gitcode.com/GitHub_Trending/te/terraform-aws-eks

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

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

Cursor Settings 界面汉化实战:绕过签名校验的资源覆盖方案

1. 为什么 Cursor 的设置界面默认不支持中文&#xff1f;——从架构根源看本地化盲区 Cursor 编辑器不是简单套壳 VS Code 的“换皮产品”&#xff0c;它的底层架构决定了汉化这件事不能照搬 VS Code 的那一套。我第一次在公司内部推广 Cursor 给前端团队时&#xff0c;就栽在…

作者头像 李华
网站建设 2026/9/18 14:07:32

MATLAB水文计算实战:P-III频率分析与马斯京根洪水演算

简介&#xff1a;《MATLAB在水文计算中的应用》是一份面向水文、水利专业学生及工程技术人员的参考文献。内容围绕单位线推求、相关分析、系列插补延长等典型水文计算任务&#xff0c;讲解如何借助MATLAB矩阵运算与最小二乘法完成求解&#xff0c;相比传统手算方法更快捷、准确…

作者头像 李华
网站建设 2026/9/18 14:06:08

双功能雷达通信系统(DFRC)的Matlab仿真与波束成形优化

1. 项目背景与核心价值去年参与某军工研究所的合作项目时&#xff0c;我第一次接触到双功能雷达通信系统&#xff08;DFRC&#xff09;的工程实现需求。传统方案中雷达和通信设备往往独立部署&#xff0c;导致频谱资源紧张、硬件成本高昂。而采用波束成形技术的DFRC系统&#x…

作者头像 李华
网站建设 2026/9/18 14:02:03

AIOps平台实践:从数据采集到根因定位的智能运维指南

简介&#xff1a;面向运维与技术管理人员的一份AIOps平台架构解读文档&#xff0c;围绕数据驱动理念&#xff0c;系统说明如何在海量多维IT数据中提炼运维价值。内容覆盖全栈数据采集范围与采集方式&#xff0c;包括基础资源、应用、日志、流量、用户体验及交易数据&#xff0c…

作者头像 李华