将EC2手工加入EKS集群成为托管节点
本文讲解如何将EC2实例手工加入EKS集群成为托管节点,解决无法使用自动节点组时的部署挑战,提供从AMI选择到节点配置的完整手动集成方案。
EKS动手实验合集请参考这里。
更新到 EKS 1.36版本
一、背景
1、EKS服务使用EC2的两种模式
EKS服务使用EC2的两种模式
- 使用EKS自动生成的托管节点组:在EKS服务控制台或者通过eksctl命令完成,EKS会自动使用最新镜像,全自动创建,并使用Autoscaling缩放;如果是通过eksctl脚本,还会自动创建合适的IAM角色;这时候EC2会在托管节点组内。
- 使用EKS提供的AMI以托管节点方式自行加入集群:使用EKS官方提供的基础镜像(EKS 1.36对应Amazon Linux 2023),手工创建一个EC2,并手工配置IAM角色,然后通过nodeadm初始化程序读取NodeConfig配置,将本EC2加入EKS集群;这时候EC2会成为托管节点,但不会进入上一步的托管节点组。
以上两种方式,都是EKS托管节点,意味着EKS可有效进行版本升级等管理。不过不在节点组中的EC2不能参与缩放,当节点不够用时候,需要手工拉起新的节点。
本文介绍第二种方式的使用。
2、手工加入EC2到EKS成为托管节点的必要条件
前提条件:
- 镜像来自AWS的EKS服务官方列表
- EKS控制平面允许网络连接(配置为Public&Private,或者其他满足EC2能连接的方式)
- EC2使用的安全组正确(出站可抵达API Server)
- 在EC2上使用curl验证EKS API可通达
- EC2使用的IAM Role正确
- 拉起的EC2的AMI是最新的托管镜像,与EKS控制平面版本相同(最多只能差1个小版本)
- 拉起的AMI是从官方AMI全新拉起,不是之前加入过别的集群后二次快照的镜像
二、创建EC2
1、查询要使用的AMI
使用AWSCLI可快速查询EKS服务官方AMI。EKS 1.36的官方节点镜像为Amazon Linux 2023,其SSM参数路径中包含版本号1.36、镜像类型amazon-linux-2023以及架构与变体x86_64/standard或arm64/standard。注意替换如下命令中的版本号与区域。
查询Intel/AMD处理器的x86_64架构的命令如下:
aws ssm get-parameter --name /aws/service/eks/optimized-ami/1.36/amazon-linux-2023/x86_64/standard/recommended/image_id --region ap-southeast-1 --query "Parameter.Value" --output text
查询ARM架构处理器的命令如下:
aws ssm get-parameter --name /aws/service/eks/optimized-ami/1.36/amazon-linux-2023/arm64/standard/recommended/image_id --region ap-southeast-1 --query "Parameter.Value" --output text
以查询x86_64架构为例,返回结果如下。
ami-0b7a5a1d35d68ea86
需要注意,EKS 1.36不再提供Amazon Linux 2的官方镜像,早期版本使用的amazon-linux-2参数路径已不存在,查询会返回ParameterNotFound。因此手工创建节点必须使用Amazon Linux 2023的镜像。
2、查询已经存在的托管节点组EC2使用的安全组
找到EKS集群已经存在的托管节点组EC2,查看其安全标签页,找到当前使用的安全组。复制下来名称,后续将要继续使用。如下截图。
3、查询已经存在的托管节点组EC2使用IAM Role角色
找到EKS集群已经存在的托管节点组EC2,查看其安全标签页,找到当前使用的IAM Role的信息。点击进入,跳转到IAM页面。如下截图。
在跳转到IAM页面后,可以在右侧看到Instance profile ARN,其中的profile/后边的这一个字符串,就是EKS集群节点组使用的IAM Role对应的Profile ID。将这个ID复制下来名称,后续将要继续使用。如下截图。
4、用上述参数创建EC2
接下来以如上参数,包括AMI在对应的区域和VPC内,创建EC2。创建时候磁盘选择gp3,容量建议最小30GB,安全组如上选择,IAM Role如上选择。其他选项可暂不配置。
在创建向导页面最下方,点击Advanced高级设置,在IAM instance profile位置,选择上一步查找的IAM Profile ID的名称。如下截图。
如果在创建EC2时候,并没有分配正确的IAM Role,那么可以在创建完成后,随时修改IAM Role。方法是从操作菜单中找到安全,找到里边的Modify IAM role选项。如下截图。
EC2绑定的IAM Role只能是唯一的一个,不能像安全组那样绑定多个。请注意。如下截图。
创建EC2完成。
三、查询现有EKS集群配置
1、查询Cluster CA证书
执行如下命令:
aws eks describe-cluster --query "cluster.certificateAuthority.data" --output text --name eksworkshop
返回结果就是证书内容。
此外,还可以到EKS控制台上查看。查看位置如下截图。
2、查询API Server Endpoint的地址
执行如下命令:
aws eks describe-cluster --query "cluster.endpoint" --output text --name eksworkshop
返回结果就是API Server地址。
https://D0A7E4BBBBD26CD6E003B94E42FECFD2.gr7.ap-southeast-1.eks.amazonaws.com
此外,还可以到EKS控制台上查看。查看方法如上一步的截图。
3、查询Cluster的DNS地址
nodeadm的NodeConfig配置使用集群的Service CIDR(服务网段),并据此自动推导集群DNS地址,因此这里先查询集群的Service CIDR。执行如下命令:
aws eks describe-cluster --name eksworkshop --region ap-southeast-1 --query "cluster.kubernetesNetworkConfig.serviceIpv4Cidr" --output text
返回结果就是集群的Service CIDR:
10.50.0.0/24
集群DNS(CoreDNS)的Service IP是该网段中的第10个地址,本例即10.50.0.10,EKS默认的DNS地址一般都是所在Service网段的.10。也可以执行kubectl get services -A直接查看kube-dns的CLUSTER-IP进行核对:
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default kubernetes ClusterIP 10.50.0.1 <none> 443/TCP 3d20h
kube-system kube-dns ClusterIP 10.50.0.10 <none> 53/UDP,53/TCP 3d20h
在使用nodeadm时,NodeConfig中填写的是Service CIDR(10.50.0.0/24),而不是单个DNS地址,nodeadm会自动完成DNS地址的推导。
此外,还可以到EKS控制台上查看。查看方法是进入EKS集群,找到Resource资源标签页,点击其中的Service and networking服务和网络,从第一个菜单Service服务中,找到右侧的kube-dns。点击查看。如下截图。
从kube-dns服务的详情中,可看到服务IP是10.50.0.10。如下截图。
4、验证本EC2可以到达EKS网络平面
登录到上一步创建好的EC2上,确认EC2可以访问EKS的API,执行如下命令:
curl -k https://D0A7E4BBBBD26CD6E003B94E42FECFD2.gr7.ap-southeast-1.eks.amazonaws.com/livez?verbose
返回结果如下表示正常:
[+]ping ok
[+]log ok
[+]etcd ok
[+]poststarthook/start-kube-apiserver-admission-initializer ok
[+]poststarthook/generic-apiserver-start-informers ok
[+]poststarthook/priority-and-fairness-config-consumer ok
[+]poststarthook/priority-and-fairness-filter ok
[+]poststarthook/storage-object-count-tracker-hook ok
[+]poststarthook/start-apiextensions-informers ok
[+]poststarthook/start-apiextensions-controllers ok
[+]poststarthook/crd-informer-synced ok
[+]poststarthook/start-service-ip-repair-controllers ok
[+]poststarthook/rbac/bootstrap-roles ok
[+]poststarthook/scheduling/bootstrap-system-priority-classes ok
[+]poststarthook/priority-and-fairness-config-producer ok
[+]poststarthook/start-system-namespaces-controller ok
[+]poststarthook/bootstrap-controller ok
[+]poststarthook/start-cluster-authentication-info-controller ok
[+]poststarthook/start-kube-apiserver-identity-lease-controller ok
[+]poststarthook/start-deprecated-kube-apiserver-identity-lease-garbage-collector ok
[+]poststarthook/start-kube-apiserver-identity-lease-garbage-collector ok
[+]poststarthook/start-legacy-token-tracking-controller ok
[+]poststarthook/aggregator-reload-proxy-client-cert ok
[+]poststarthook/start-kube-aggregator-informers ok
[+]poststarthook/apiservice-registration-controller ok
[+]poststarthook/apiservice-status-available-controller ok
[+]poststarthook/kube-apiserver-autoregistration ok
[+]autoregister-completion ok
[+]poststarthook/apiservice-openapi-controller ok
[+]poststarthook/apiservice-openapiv3-controller ok
[+]poststarthook/apiservice-discovery-controller ok
livez check passed
至此准备工作完毕。
四、将EC2作为托管节点加入集群
在Amazon Linux 2023节点上,节点的初始化由nodeadm程序完成,nodeadm读取名为NodeConfig的YAML配置对象获取集群信息。NodeConfig的最小必填字段为集群名称name、API Server地址apiServerEndpoint、集群CA证书certificateAuthority以及Service CIDRcidr,这些参数均已在第二章、第三章查询完毕。将EC2加入集群有两种方式:一是登录到已创建的EC2上手工执行nodeadm;二是在创建EC2时通过Userdata传入NodeConfig,由镜像自带的nodeadm在开机时自动完成加入。二者选其一即可,下面分别介绍。
1、在EC2节点上手工执行命令加入集群
使用Session Manager或者其他方式,登录到本文第二章创建的EC2上。
需要注意,Amazon Linux 2023镜像已不再提供早期版本中的/etc/eks/bootstrap.sh加入脚本。该路径下虽然仍保留了一个同名文件,但它只是一个提示脚本,执行后会直接报错退出,内容如下:
sudo /etc/eks/bootstrap.sh eksworkshop
!!!!!!!!!!
!!!!!!!!!! ERROR: bootstrap.sh has been removed from AL2023-based EKS AMIs.
!!!!!!!!!!
!!!!!!!!!! EKS nodes are now initialized by nodeadm.
!!!!!!!!!!
!!!!!!!!!! To migrate your user data, see:
!!!!!!!!!!
!!!!!!!!!! https://awslabs.github.io/amazon-eks-ami/nodeadm/
!!!!!!!!!!
正确的做法是使用nodeadm。将第二章、第三章查询到的参数写入一个NodeConfig配置文件,例如/root/nodeConfig.yaml,内容如下。其中certificateAuthority填写第三章第1节查询到的CA证书内容(较长,此处截断示意),cidr填写第三章第3节查询到的Service CIDR:
apiVersion: node.eks.aws/v1alpha1
kind: NodeConfig
spec:
cluster:
name: eksworkshop
apiServerEndpoint: https://D0A7E4BBBBD26CD6E003B94E42FECFD2.gr7.ap-southeast-1.eks.amazonaws.com
certificateAuthority: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t......(此处为CA证书的base64内容,请替换为实际值)
cidr: 10.50.0.0/24
然后执行nodeadm初始化命令,通过--config-source指向该配置文件:
sudo nodeadm init --config-source file:///root/nodeConfig.yaml
命令执行后返回如下信息(节选),显示containerd与kubelet两个守护进程被配置并启动,最后输出done!表示初始化完成:
info init/init.go:129 Configuring daemons...
info init/init.go:218 Configuring daemon... {"name": "containerd"}
info containerd/config.go:77 Writing containerd config to file.. {"path": "/etc/containerd/config.toml"}
info init/init.go:222 Configured daemon {"name": "containerd"}
info init/init.go:218 Configuring daemon... {"name": "kubelet"}
info kubelet/config.go:232 Setup IP for node {"ip": "192.168.33.81"}
info kubelet/config.go:347 Writing kubelet config to file.. {"path": "/etc/kubernetes/kubelet/config.json"}
info init/init.go:222 Configured daemon {"name": "kubelet"}
info init/init.go:151 Running daemons...
info init/init.go:234 Ensuring daemon is running.. {"name": "containerd"}
info init/init.go:238 Daemon is running {"name": "containerd"}
info init/init.go:234 Ensuring daemon is running.. {"name": "kubelet"}
info init/init.go:238 Daemon is running {"name": "kubelet"}
info init/init.go:157 done! {"duration": 0.63711644}
执行过程中如果出现Failed to cache config一类的提示,是因为使用本地文件作为配置源时没有对应的配置缓存路径,属于非致命提示,不影响节点加入。初始化完成后,可执行sudo systemctl is-active kubelet确认kubelet已处于active状态。以上信息显示加入集群成功。
2、验证加入集群成功
登录到EKS服务界面,可从Compute界面中看到这台EC2加入集群成功。
在上述截图中,可看到三个EC2节点的Nodegroup。
在命令行执行如下命令,验证加入集群成功:
kubectl get nodes
返回结果如下(其中AGE很短的一台即为手工加入的节点):
NAME STATUS ROLES AGE VERSION
ip-192-168-30-108.ap-southeast-1.compute.internal Ready <none> 3d20h v1.36.4-eks-a887778
ip-192-168-33-81.ap-southeast-1.compute.internal Ready <none> 45s v1.36.4-eks-a887778
ip-192-168-54-190.ap-southeast-1.compute.internal Ready <none> 3d20h v1.36.4-eks-a887778
ip-192-168-69-155.ap-southeast-1.compute.internal Ready <none> 3d20h v1.36.4-eks-a887778
由此可看到EKS集群中,已经包含了新加入的节点,其Kubernetes版本与其余节点一致,均为v1.36.4-eks-a887778。
如果本机安装了eksctl工具,还可以通过eksctl来确认托管节点组的构成:
eksctl get nodegroup --cluster eksworkshop --region ap-southeast-1
返回结果如下:
CLUSTER NODEGROUP STATUS CREATED MIN SIZE MAX SIZE DESIRED CAPACITY INSTANCE TYPE IMAGE ID ASG NAME TYPE
eksworkshop podsubnet-ng ACTIVE 2026-09-19T13:40:54Z 3 6 3 t3.2xlarge AL2023_x86_64_STANDARD eks-podsubnet-ng-74d05cf2-fab0-a446-979c-fabf549e22c2 managed
由此可确认托管节点组内是3台机器(IMAGE ID一列已显示为AL2023_x86_64_STANDARD,表明使用的是Amazon Linux 2023镜像),而刚才kubectl get nodes中多出来的那一台,就是本文手工加入集群的EC2。
五、使用Userdata脚本在EC2创建时候自动加入集群(可选)
上文的方法,是采用事先创建好EC2,然后在EC2上执行命令的方式加入集群。此外,还可以通过Userdata脚本方式,在创建一个全新EC2时候,自动加入集群。
Amazon Linux 2023的EKS官方镜像在开机时会自动运行nodeadm,它会从EC2的Userdata中读取NodeConfig并完成节点初始化。因此这里无须在Userdata中显式调用nodeadm init(重复调用反而会与镜像自带的初始化流程冲突),只需将NodeConfig以MIME多部分格式放入Userdata即可。
Userdata内容编写如下,然后放到创建EC2服务的高级菜单中的Userdata对话框下。其中Content-Type: application/node.eks.aws用于告知nodeadm这是一段NodeConfig,各参数含义与第四章一致:
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="//"
--//
Content-Type: application/node.eks.aws
apiVersion: node.eks.aws/v1alpha1
kind: NodeConfig
spec:
cluster:
name: eksworkshop
apiServerEndpoint: https://D0A7E4BBBBD26CD6E003B94E42FECFD2.gr7.ap-southeast-1.eks.amazonaws.com
certificateAuthority: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t......(此处为CA证书的base64内容,请替换为实际值)
cidr: 10.50.0.0/24
--//--
如下截图。
启动EC2,并等待3-5分钟。镜像自带的nodeadm会分两个阶段执行:nodeadm-config在Userdata执行之前完成containerd与kubelet的基础配置,nodeadm-run在其后启动相关守护进程。在节点上可通过sudo journalctl -u nodeadm-run --no-pager查看其执行日志,看到Finished nodeadm-run.service即表示初始化完成。
通过EKS服务界面,可看到Node加入成功。如下截图。
通过K9S等管理工具,也可以看到Node添加成功。
六、参考文档
检索 Amazon EKS 优化版 Amazon Linux AMI ID
https://docs.aws.amazon.com/zh_cn/eks/latest/userguide/eks-optimized-ami.html
Amazon EKS 优化版 Amazon Linux 2023 加速版 AMI(nodeadm 初始化说明)
https://docs.aws.amazon.com/eks/latest/userguide/al2023.html
nodeadm 与 NodeConfig 配置参考(amazon-eks-ami 文档)
https://awslabs.github.io/amazon-eks-ami/nodeadm/
在 AL2023 的 Amazon EKS 节点上使用自定义 Userdata
https://repost.aws/knowledge-center/custom-user-eks-2023
使用启动模板自定义托管节点
最后修改于 2026-09-23