EKS托管节点组更新耗时过长问题咨询
首先,这种更新耗时超一小时的情况确实属于普遍现象,尤其是在默认配置下结合Terraform、EKS托管节点组和Cluster Autoscaler时。核心原因在于默认的滚动更新策略偏保守,加上Cluster Autoscaler的缩放逻辑会引入额外延迟,导致节点替换过程被拉长。
下面是几个实用的优化方法,帮你缩短更新周期:
1. 调整节点组的滚动更新配置
Terraform管理的aws_eks_node_group资源支持通过update_config块自定义更新策略,默认情况下max_unavailable是1(一次只替换1个节点),这对4节点的组来说自然很慢。你可以修改为更高的并行度,比如:
resource "aws_eks_node_group" "example" { # 其他配置... update_config { max_unavailable = 2 # 一次最多不可用2个节点,适合4节点组 max_surge = 0 # 也可设置max_surge先新增节点再移除旧节点,根据业务容错性选择 } }
这样一次可以同时替换2个节点,直接将更新时间压缩一半以上。注意要根据你的应用容错能力调整数值,确保业务不受影响。
2. 用Terraform自动化节点驱逐与替换
手动终止节点虽然快,但可以把这个流程自动化。你可以用Terraform的null_resource配合local-exec,在更新启动模板后批量驱逐旧节点并触发ASG替换:
resource "null_resource" "replace_nodes" { triggers = { launch_template_version = aws_launch_template.example.latest_version } provisioner "local-exec" { command = <<EOF # 获取旧节点的实例ID OLD_NODES=$(kubectl get nodes -l eks.amazonaws.com/nodegroup=${aws_eks_node_group.example.name} -o jsonpath='{.items[*].spec.providerID}' | awk -F/ '{print $NF}') # 并行驱逐并终止节点(避免逐个等待) for node in $OLD_NODES; do kubectl drain $node --ignore-daemonsets --delete-local-data & aws ec2 terminate-instances --instance-ids $node & done wait EOF } depends_on = [aws_eks_node_group.example] }
这个方法模拟你手动操作的逻辑,但完全自动化,避免手动操作的风险。
3. 优化Cluster Autoscaler的参数配置
Cluster Autoscaler默认的一些参数会延缓旧节点的移除,比如scale-down-delay-after-add默认是10分钟,意味着新增节点后要等10分钟才会考虑缩容旧节点。你可以在CA的Deployment中调整这些参数:
--scale-down-delay-after-add=1m:缩短新增节点后的缩容等待时间--scale-down-unneeded-time=3m:旧节点空闲3分钟后就可以被缩容--skip-nodes-with-local-storage=false:如果应用没有依赖本地存储,允许移除带本地存储的节点
这些调整能让CA更快地识别并移除旧节点,加速整个更新流程。
4. 预热新节点的容器镜像
新节点启动后,拉取Pod镜像会占用大量时间。你可以在启动模板的userdata中添加预拉取常用镜像的命令,比如:
#!/bin/bash # 预拉取应用常用镜像 docker pull nginx:1.25-alpine docker pull your-app-image:latest
这样节点就绪后就能直接运行Pod,无需等待镜像拉取,大幅缩短节点进入服务状态的时间。
内容的提问来源于stack exchange,提问作者Tomer Leibovich




