EKS 两种创建模式:Auto Mode 与 Managed Node Group 实战方案¶
这篇文章解决什么问题¶
在 AWS 控制台创建 EKS 集群时,页面上通常会看到两类入口:
- 快速配置,默认使用 EKS Auto Mode
- 自定义配置,可以自己控制 VPC、节点、插件和访问方式
这两个选项背后真正影响架构的是:EKS 的计算资源由谁管理。
常见模式有两种:
这篇文章给出两套创建方案,适合做生产上线前的验证集群,也能作为后续生产模板的起点。
两种模式怎么选¶
先给结论:
| 场景 | 推荐模式 |
|---|---|
| 快速验证应用能否跑在 EKS 上 | EKS Auto Mode |
| 团队刚开始使用 EKS,希望少管节点 | EKS Auto Mode |
| 想让 EKS 自动准备 EC2 节点承载 Pod | EKS Auto Mode |
| 生产计划使用 Auto Mode | 验证环境也用 Auto Mode |
| 需要验证节点组、实例规格、磁盘、DaemonSet | Managed Node Group |
| 生产计划使用固定节点池、Karpenter 或精细成本治理 | Managed Node Group |
| 需要强控制节点 AMI、启动参数、节点安全基线 | Managed Node Group |
一句话:
共同前置条件¶
两种方案都需要本地具备:
这三个工具的作用分别是:
| 工具 | 作用 |
|---|---|
| Terraform | 创建 VPC、EKS、节点组、IAM 等 AWS 资源 |
| AWS CLI | 认证 AWS 账号、查询集群、生成 kubeconfig |
| kubectl | 连接 EKS 集群并管理 Kubernetes 资源 |
Windows 安装¶
Windows 建议使用 winget 安装。如果你的系统没有 winget,也可以从 HashiCorp、AWS、Kubernetes 官方页面下载安装包。
安装 Terraform:
安装 AWS CLI v2:
安装 kubectl:
安装后重新打开 PowerShell,验证:
macOS 安装¶
macOS 建议使用 Homebrew。
安装 Homebrew 后执行:
brew tap hashicorp/tap
brew install hashicorp/tap/terraform
brew install awscli
brew install kubectl
验证:
Linux 安装¶
Linux 发行版很多,下面给出通用思路。生产机器上建议优先使用官方仓库或公司内部软件源。
Ubuntu/Debian 可以使用 HashiCorp apt 仓库安装 Terraform:
wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(. /etc/os-release && echo "$VERSION_CODENAME") main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update
sudo apt install terraform
AWS CLI v2 可以这样安装:
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
kubectl 可以直接下载稳定版本:
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
验证:
如果是 ARM64 Linux,把 kubectl 下载地址里的 linux/amd64 改成 linux/arm64。
配置 AWS 凭证¶
安装工具后,需要先让 AWS CLI 能访问你的 AWS 账号。
最简单的方式是:
按提示输入:
配置完成后会写入:
Windows 对应路径通常是:
如果公司使用 IAM Identity Center,也可以使用 SSO:
验证当前身份:
能正常返回 Account、Arn、UserId,说明 AWS CLI 认证可用。
并且当前 AWS 身份要有创建这些资源的权限:
- VPC、Subnet、Route Table、NAT Gateway
- EKS Cluster
- EC2、Auto Scaling、Launch Template
- IAM Role、Policy Attachment
- CloudWatch Logs
配置 kubectl 访问 EKS¶
EKS 集群创建完成后,本地 kubectl 还不能直接访问集群,需要先生成 kubeconfig:
这条命令会把 EKS 访问配置写入:
Windows 对应路径通常是:
然后验证:
方案一:EKS Auto Mode¶
适用场景¶
EKS Auto Mode 适合快速创建验证集群。它的重点是:
它不是 Lambda 那种纯 Serverless,底层仍然是 EC2。只是节点创建、替换、生命周期、部分网络和存储基础设施由 EKS 更自动化地管理。
适合验证:
- 应用能否部署到 EKS
- Service、Ingress、PVC 基本链路
- 镜像拉取、Pod 启动、日志采集
- 快速创建、快速销毁的临时集群
不适合重点验证:
- 固定节点组规划
- 自定义 AMI
- 节点启动脚本
- 复杂 DaemonSet 与节点安全基线
- 精细 Spot/On-Demand 成本策略
Terraform 示例¶
下面示例使用 terraform-aws-modules/vpc/aws 和 terraform-aws-modules/eks/aws 创建一个 Auto Mode 验证集群。
terraform {
required_version = ">= 1.6.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
locals {
cluster_name = "eks-prod-verify-135"
# 复用 AWS 控制台“创建推荐的角色”生成的 EKS Auto Mode 角色。
cluster_role_arn = "arn:aws:iam::788356290550:role/AmazonEKSAutoClusterRole"
node_role_arn = "arn:aws:iam::788356290550:role/AmazonEKSAutoNodeRole"
# 可选:让 root 控制台身份也能查看和管理集群内资源。
console_admin_principal_arn = "arn:aws:iam::788356290550:root"
}
data "aws_availability_zones" "available" {
state = "available"
}
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
name = "${local.cluster_name}-vpc"
cidr = "10.20.0.0/16"
azs = slice(data.aws_availability_zones.available.names, 0, 2)
public_subnets = ["10.20.0.0/24", "10.20.1.0/24"]
private_subnets = ["10.20.8.0/22", "10.20.12.0/22"]
enable_dns_hostnames = true
enable_nat_gateway = true
single_nat_gateway = true
public_subnet_tags = {
"kubernetes.io/role/elb" = 1
}
private_subnet_tags = {
"kubernetes.io/role/internal-elb" = 1
}
}
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "~> 20.0"
cluster_name = local.cluster_name
cluster_version = "1.35"
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnets
create_iam_role = false
iam_role_arn = local.cluster_role_arn
create_node_iam_role = false
cluster_endpoint_public_access = true
cluster_endpoint_public_access_cidrs = ["0.0.0.0/0"]
cluster_endpoint_private_access = true
cluster_enabled_log_types = [
"api",
"audit",
"authenticator",
]
cluster_addons = {
coredns = {
most_recent = true
}
kube-proxy = {
most_recent = true
}
vpc-cni = {
most_recent = true
}
}
cluster_compute_config = {
enabled = true
node_pools = ["general-purpose", "system"]
node_role_arn = local.node_role_arn
}
access_entries = {
console_admin = {
principal_arn = local.console_admin_principal_arn
policy_associations = {
cluster_admin = {
policy_arn = "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy"
access_scope = {
type = "cluster"
}
}
}
}
}
enable_cluster_creator_admin_permissions = true
}
output "configure_kubectl" {
value = "aws eks update-kubeconfig --region us-east-1 --name ${local.cluster_name}"
}
验证步骤¶
执行:
配置 kubectl:
查看节点:
部署一个测试应用:
kubectl create deployment nginx --image=nginx:1.25
kubectl scale deployment nginx --replicas=3
kubectl get pod -o wide
如果集群当前没有足够容量,Auto Mode 会自动准备节点来运行 Pod。
控制台访问条目¶
这次实际创建时有一个很容易忽略的点:集群是 terraform IAM 用户创建的,不代表 root 用户登录控制台后就能查看集群内 Kubernetes 资源。
这段配置:
只会给执行 Terraform 的身份授权。例如本次创建者是:
所以这个用户可以执行:
但如果你使用 root 用户登录 AWS 控制台,进入 EKS 页面查看工作负载、Pod、节点等集群内容,还需要额外添加一个 EKS 访问条目,并绑定:
Terraform 里可以这样声明:
access_entries = {
console_admin = {
principal_arn = "arn:aws:iam::788356290550:root"
policy_associations = {
cluster_admin = {
policy_arn = "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy"
access_scope = {
type = "cluster"
}
}
}
}
}
控制台里对应路径是:
生产环境不建议长期用 root 用户管理集群。更好的方式是给运维 IAM Role、SSO Role 或平台管理员组创建访问条目。这里给 root 加访问条目,是为了验证环境里方便从控制台查看集群内容。
如果集群已经创建完成,再补上这段 access_entries 后,先执行:
正常情况下应该只看到新增两个资源:
确认不会重建 EKS、VPC、NAT Gateway 等资源后,再执行:
Auto Mode 注意点¶
验证环境里,下面配置可以接受:
但生产前置验证更建议改成:
如果生产环境也准备用 Auto Mode,验证重点应该放在:
- Pod requests/limits 是否合理
- Auto Mode 是否能按预期创建节点
- Ingress 和 LoadBalancer 是否符合预期
- PVC 和 EBS 是否能正常挂载
- Pod Identity 或 IRSA 是否能正常访问 AWS 资源
- 成本是否符合预期
如果你没有提前在控制台创建 AmazonEKSAutoClusterRole 和 AmazonEKSAutoNodeRole,可以删除下面这些复用现有角色的配置,让 Terraform module 自己创建 Auto Mode 所需角色:
create_iam_role = false
iam_role_arn = local.cluster_role_arn
create_node_iam_role = false
cluster_compute_config = {
enabled = true
node_pools = ["general-purpose", "system"]
node_role_arn = local.node_role_arn
}
然后保留一个不指定 node_role_arn 的 cluster_compute_config:
方案二:普通 EKS + Managed Node Group¶
适用场景¶
Managed Node Group 是传统 EKS 最常见的方式。
它的模型是:
适合验证:
- 固定节点组规划
- 节点实例规格
- 节点磁盘和加密
- DaemonSet、安全 Agent、监控 Agent
- 集群扩缩容策略
- 生产环境相同的节点结构
如果生产集群计划使用 Managed Node Group 或 Karpenter,验证集群也建议采用这种模式。
Terraform 示例¶
下面示例创建一个普通 EKS 集群和一个 Managed Node Group。
terraform {
required_version = ">= 1.6.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
locals {
cluster_name = "eks-mng-verify"
}
data "aws_availability_zones" "available" {
state = "available"
}
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
name = "${local.cluster_name}-vpc"
cidr = "10.30.0.0/16"
azs = slice(data.aws_availability_zones.available.names, 0, 2)
public_subnets = ["10.30.0.0/24", "10.30.1.0/24"]
private_subnets = ["10.30.8.0/22", "10.30.12.0/22"]
enable_dns_hostnames = true
enable_nat_gateway = true
single_nat_gateway = true
public_subnet_tags = {
"kubernetes.io/role/elb" = 1
}
private_subnet_tags = {
"kubernetes.io/role/internal-elb" = 1
}
}
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "~> 20.0"
cluster_name = local.cluster_name
cluster_version = "1.35"
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnets
cluster_endpoint_public_access = true
cluster_endpoint_public_access_cidrs = ["0.0.0.0/0"]
cluster_endpoint_private_access = true
cluster_enabled_log_types = [
"api",
"audit",
"authenticator",
]
cluster_addons = {
coredns = {
most_recent = true
}
kube-proxy = {
most_recent = true
}
vpc-cni = {
most_recent = true
}
}
eks_managed_node_groups = {
main = {
instance_types = ["t3.medium"]
min_size = 1
max_size = 3
desired_size = 2
capacity_type = "ON_DEMAND"
block_device_mappings = {
xvda = {
device_name = "/dev/xvda"
ebs = {
volume_size = 20
volume_type = "gp3"
encrypted = true
delete_on_termination = true
}
}
}
labels = {
role = "app"
}
}
}
enable_cluster_creator_admin_permissions = true
}
output "configure_kubectl" {
value = "aws eks update-kubeconfig --region us-east-1 --name ${local.cluster_name}"
}
验证步骤¶
执行:
配置 kubectl:
查看节点和系统组件:
部署测试应用:
kubectl create deployment nginx --image=nginx:1.25
kubectl expose deployment nginx --port=80 --target-port=80 --type=ClusterIP
kubectl get pod,svc -o wide
如果要验证 NodePort:
kubectl expose deployment nginx --name=nginx-nodeport --port=80 --target-port=80 --type=NodePort
kubectl get svc nginx-nodeport
Managed Node Group 注意点¶
验证环境可以用:
生产环境通常要调整:
- 节点组跨 3 个可用区
- 每个可用区一个 NAT Gateway
- private subnet 留更大地址空间
- system 和 app 节点组分开
- 关键业务使用 On-Demand,弹性任务可以使用 Spot
- 配合 Cluster Autoscaler 或 Karpenter 做自动扩缩容
复用现有 IAM Role 时要注意¶
如果你像控制台截图里那样已经有:
要先判断它们是给 Auto Mode 用,还是给普通 Managed Node Group 用。
不要混成:
这可能导致节点权限、信任关系或托管策略不匹配。
普通 Managed Node Group 的节点角色通常至少需要:
AmazonEKSWorkerNodePolicyAmazonEC2ContainerRegistryPullOnly- VPC CNI 所需权限,常见做法是给
aws-node使用 IRSA,验证环境也可以临时挂在节点角色上
如果是 Auto Mode,则优先按 Auto Mode 文档创建推荐角色,并使用 Auto Mode 的创建方式。
两种模式的验证清单¶
创建完成后,不管哪种模式,都建议检查:
kubectl get nodes -o wide
kubectl get pod -A -o wide
kubectl get svc -A
kubectl get events -A --sort-by=.lastTimestamp
检查 EKS Add-ons:
aws eks list-addons --region us-east-1 --cluster-name <cluster-name>
aws eks describe-addon --region us-east-1 --cluster-name <cluster-name> --addon-name vpc-cni
检查节点是否能拉镜像:
kubectl create deployment image-test --image=public.ecr.aws/nginx/nginx:latest
kubectl get pod -l app=image-test -o wide
检查 DNS:
kubectl run dns-test --image=busybox:1.36 --restart=Never -- sleep 3600
kubectl exec dns-test -- nslookup kubernetes.default
检查出网:
检查集群访问:
销毁验证环境¶
验证集群用完要及时销毁。不要先到控制台手工删除资源,优先让 Terraform 按 state 反向删除,否则容易出现 state 和真实资源不一致。
进入当初执行 terraform apply 的目录。以 Auto Mode 为例:
先查看 Terraform 当前管理了哪些资源:
然后生成销毁计划:
确认计划里只有销毁动作,例如:
再按这个计划执行销毁:
本次 Auto Mode 验证集群实际销毁结果是:
如果只是临时验证,也可以直接执行:
但更推荐先 plan -destroy,因为你能提前看到将要删除的 EKS、VPC、NAT Gateway、EIP、CloudWatch Log Group、KMS Key 等资源。
销毁后建议用 AWS CLI 或控制台检查是否还有残留:
aws eks describe-cluster \
--region us-east-1 \
--name eks-prod-verify-135
aws ec2 describe-nat-gateways \
--region us-east-1 \
--filter Name=vpc-id,Values=<vpc-id>
aws elbv2 describe-load-balancers \
--region us-east-1
aws ec2 describe-vpcs \
--region us-east-1 \
--vpc-ids <vpc-id>
本次实测结果:
describe-cluster返回No cluster found- NAT Gateway 状态为
deleted describe-load-balancers返回空数组describe-vpcs返回InvalidVpcID.NotFound
控制台里也建议重点看这些资源:
- Load Balancer
- Target Group
- EBS Volume
- EBS Snapshot
- Elastic IP
- NAT Gateway
- CloudWatch Log Group
尤其是通过 Kubernetes Service/Ingress 创建的 ALB/NLB,有时会因为 finalizer 或控制器未清理干净而残留。验证环境里要养成销毁后复查账单资源的习惯。
还有一个正常现象:如果 EKS module 创建了 KMS Key,Terraform 销毁时会调用 KMS 的计划删除。KMS Key 不会立刻物理删除,而是进入 PendingDeletion,到删除窗口结束后才真正删除。本次销毁后,对应 KMS Key 的状态就是 PendingDeletion。
我的建议¶
如果只是快速验证业务能否迁到 EKS:
如果你要模拟未来生产架构:
验证环境可以省钱,但不要让验证目标跑偏。最关键的是: