AWS EKS集群Worker节点无法加入问题排查求助
问题描述
我通过Shell脚本使用AWS CLI创建一个2节点AWS EKS集群,脚本已创建控制平面和2个EC2实例作为Worker节点,但节点无法加入集群。执行kubectl get nodes返回No resources found。请问是否需要配置网络接口?改用NodeGroup是否可行?
以下是我的脚本:
current_time=$(date +"%Y.%m.%d.%H.%M.%S.%3N") file_name="eks.cluster.ids_${current_time}.txt" VPC_ID=$(aws ec2 create-vpc --cidr-block 10.0.0.0/16 --query 'Vpc.VpcId' --output text) SUBNET_ID1=$(aws ec2 create-subnet --vpc-id $VPC_ID --cidr-block 10.0.1.0/24 --availability-zone us-west-1a --query 'Subnet.SubnetId' --output text) SUBNET_ID2=$(aws ec2 create-subnet --vpc-id $VPC_ID --cidr-block 10.0.2.0/24 --availability-zone us-west-1b --query 'Subnet.SubnetId' --output text) SG_ID=$(aws ec2 create-security-group --group-name my-sg --description "EKS Security Group" --vpc-id $VPC_ID --query 'GroupId' --output text) aws iam create-role --role-name dean-eks-role --assume-role-policy-document file://eks-role-trust-policy.json aws iam attach-role-policy --role-name dean-eks-role --policy-arn arn:aws:iam::aws:policy/AmazonEKSClusterPolicy ROLE_ARN=$(aws iam get-role --role-name dean-eks-role --query 'Role.Arn' --output text) aws eks create-cluster --name dean-eks-cluster --role-arn $ROLE_ARN --resources-vpc-config subnetIds=$SUBNET_ID1,$SUBNET_ID2,securityGroupIds=$SG_ID sleep 5 aws ec2 create-key-pair --key-name dean-eks-key --query 'KeyMaterial' --output text > dean-eks-key.pem NODE_ID1=$(aws ec2 run-instances --image-id ami-01cff12e087f492c6 --count 1 --instance-type t2.medium --subnet-id $SUBNET_ID1 --security-group-ids $SG_ID --key-name dean-eks-key --query 'Instances[0].InstanceId' --output text) NODE_ID2=$(aws ec2 run-instances --image-id ami-01cff12e087f492c6 --count 1 --instance-type t2.medium --subnet-id $SUBNET_ID1 --security-group-ids $SG_ID --key-name dean-eks-key --query 'Instances[0].InstanceId' --output text) aws eks describe-cluster --name dean-eks-cluster --query cluster.status aws eks update-kubeconfig --name dean-eks-cluster sleep 5
问题分析与解决方案
节点无法加入集群的核心原因
你的脚本仅创建了EC2实例,但未完成Worker节点加入EKS集群的关键配置,和手动配置网络接口无关,主要问题包括:
- 缺少节点专用IAM角色:Worker节点需要具备
AmazonEKSWorkerNodePolicy等权限的IAM角色,才能与控制平面通信、拉取容器镜像。 - 未注入集群初始化配置:EKS Worker节点启动时需通过用户数据执行
bootstrap.sh脚本,完成kubelet配置、集群注册等操作,你的脚本未添加此逻辑。 - 安全组规则不完整:当前安全组未开放节点与控制平面的通信端口(如6443)、节点间通信端口,导致节点无法连接集群。
- VPC网络组件缺失:未创建Internet Gateway、路由表并关联子网,节点无法访问EKS服务端点或下载初始化组件。
关于网络接口的疑问
不需要额外手动配置网络接口,但需补全VPC基础网络配置:
- 创建并附加Internet Gateway到VPC
- 为子网创建路由表,添加指向Internet Gateway的默认路由
- 开启子网的“自动分配公有IP”(或配置NAT网关确保节点能访问公网)
改用NodeGroup是否可行?
完全可行,且更推荐使用EKS托管节点组(Managed Node Group),优势如下:
- 自动化节点生命周期管理:自动完成节点的创建、配置、更新、替换,无需手动编写EC2启动脚本。
- 自动配置IAM权限:托管节点组会自动创建符合要求的节点IAM角色及权限,无需手动配置。
- 适配集群网络:自动匹配EKS的VPC、安全组要求,减少手动配置错误。
修复现有脚本的关键步骤
若坚持手动创建EC2节点,需补充以下配置:
- 创建节点IAM角色及实例配置文件
# 创建节点信任策略(eks-node-trust-policy.json内容需允许ec2.amazonaws.com扮演角色) aws iam create-role --role-name dean-eks-node-role --assume-role-policy-document file://eks-node-trust-policy.json # 附加必要权限策略 aws iam attach-role-policy --role-name dean-eks-node-role --policy-arn arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy aws iam attach-role-policy --role-name dean-eks-node-role --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly aws iam attach-role-policy --role-name dean-eks-node-role --policy-arn arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy # 创建实例配置文件并关联角色 aws iam create-instance-profile --instance-profile-name dean-eks-node-profile aws iam add-role-to-instance-profile --instance-profile-name dean-eks-node-profile --role-name dean-eks-node-role NODE_ROLE_ARN=$(aws iam get-role --role-name dean-eks-node-role --query 'Role.Arn' --output text)
- 补全安全组规则
# 允许节点访问控制平面6443端口 aws ec2 authorize-security-group-ingress --group-id $SG_ID --protocol tcp --port 6443 --source 10.0.0.0/16 # 允许节点间通信端口 aws ec2 authorize-security-group-ingress --group-id $SG_ID --protocol tcp --port 10250-10259 --source 10.0.0.0/16 aws ec2 authorize-security-group-ingress --group-id $SG_ID --protocol udp --port 4789 --source 10.0.0.0/16 # 允许节点出站访问公网 aws ec2 authorize-security-group-egress --group-id $SG_ID --protocol all --port all --cidr 0.0.0.0/0
- 配置VPC网络组件
# 创建并附加Internet Gateway IGW_ID=$(aws ec2 create-internet-gateway --query 'InternetGateway.InternetGatewayId' --output text) aws ec2 attach-internet-gateway --vpc-id $VPC_ID --internet-gateway-id $IGW_ID # 创建路由表并添加默认路由 ROUTE_TABLE_ID=$(aws ec2 create-route-table --vpc-id $VPC_ID --query 'RouteTable.RouteTableId' --output text) aws ec2 create-route --route-table-id $ROUTE_TABLE_ID --destination-cidr-block 0.0.0.0/0 --gateway-id $IGW_ID # 关联路由表到子网 aws ec2 associate-route-table --route-table-id $ROUTE_TABLE_ID --subnet-id $SUBNET_ID1 aws ec2 associate-route-table --route-table-id $ROUTE_TABLE_ID --subnet-id $SUBNET_ID2 # 开启子网自动分配公有IP aws ec2 modify-subnet-attribute --subnet-id $SUBNET_ID1 --map-public-ip-on-launch aws ec2 modify-subnet-attribute --subnet-id $SUBNET_ID2 --map-public-ip-on-launch
- 启动EC2实例时添加用户数据
# 等待集群状态变为ACTIVE(原脚本sleep 5时间不足) until aws eks describe-cluster --name dean-eks-cluster --query 'cluster.status' --output text | grep -q ACTIVE; do echo "等待集群启动完成..." sleep 30 done # 获取集群CA证书和端点 CLUSTER_CA=$(aws eks describe-cluster --name dean-eks-cluster --query 'cluster.certificateAuthority.data' --output text) CLUSTER_ENDPOINT=$(aws eks describe-cluster --name dean-eks-cluster --query 'cluster.endpoint' --output text) # 生成初始化用户数据 USER_DATA=$(cat <<EOF #!/bin/bash set -o xtrace /etc/eks/bootstrap.sh dean-eks-cluster --apiserver-endpoint $CLUSTER_ENDPOINT --b64-cluster-ca $CLUSTER_CA EOF ) # 启动实例并指定用户数据和IAM实例配置文件 NODE_ID1=$(aws ec2 run-instances --image-id ami-01cff12e087f492c6 --count 1 --instance-type t2.medium --subnet-id $SUBNET_ID1 --security-group-ids $SG_ID --key-name dean-eks-key --iam-instance-profile Name=dean-eks-node-profile --user-data $(echo "$USER_DATA" | base64) --query 'Instances[0].InstanceId' --output text) NODE_ID2=$(aws ec2 run-instances --image-id ami-01cff12e087f492c6 --count 1 --instance-type t2.medium --subnet-id $SUBNET_ID2 --security-group-ids $SG_ID --key-name dean-eks-key --iam-instance-profile Name=dean-eks-node-profile --user-data $(echo "$USER_DATA" | base64) --query 'Instances[0].InstanceId' --output text)
托管节点组简化脚本示例
若改用托管节点组,脚本可简化为:
# 等待集群启动完成 until aws eks describe-cluster --name dean-eks-cluster --query 'cluster.status' --output text | grep -q ACTIVE; do echo "等待集群启动完成..." sleep 30 done # 创建托管节点组 aws eks create-nodegroup --cluster-name dean-eks-cluster --nodegroup-name dean-managed-nodes --node-role $NODE_ROLE_ARN --subnets $SUBNET_ID1 $SUBNET_ID2 --instance-types t2.medium --desired-size 2 --min-size 1 --max-size 3
内容的提问来源于stack exchange,提问作者Dean Schulze
相关产品推荐
相关产品推荐

