2. EKS托管节点组创建与自动伸缩配置

EKS托管节点组创建与自动伸缩配置 学习卡片

托管节点组与 Cluster Autoscaler 的协作关系

EKS 托管节点组(Managed Node Group)由 EKS 控制面托管节点生命周期,底层仍是一组 Auto Scaling Group(ASG)。要让 Cluster Autoscaler(CA)能够扩缩容,必须让 CA 能识别节点组边界、ASG 名称,并允许它调整 ASG 的期望容量。核心是三件事:给 ASG 打上 CA 发现标签、给节点打上归属标签、给 CA 授予修改 ASG 的 IAM 权限。

EKS 控制面 API Server / Scheduler 托管节点组生命周期 Cluster Autoscaler 监听 Pending Pod 调整 ASG DesiredCapacity Auto Scaling Group Min / Max / Desired 标签: k8s.io/cluster-autoscaler/enabled EKS 托管节点组 (Managed Node Group) Worker Node 1 label: role=worker 状态: Ready Worker Node 2 label: role=worker 状态: Ready Worker Node 3 待扩容节点 (Desired 增加后创建) Pending Pod 资源不足,无法调度 触发 CA 扩容 监控节点组 调整容量 触发 IAM 权限 (CA ServiceAccount) • autoscaling:SetDesiredCapacity • autoscaling:DescribeAutoScalingGroups • ec2:DescribeInstanceTypes ASG 发现标签 • k8s.io/cluster-autoscaler/enabled = true • k8s.io/cluster-autoscaler/<cluster-name> = owned • 节点标签: role=worker 配合

创建托管节点组并配置自动伸缩

以下使用 eksctl 创建带 CA 标签的托管节点组。关键参数:--nodes-min 和 --nodes-max 决定 ASG 的 Min/Max,CA 只能在此范围内调整 Desired。节点组名称和集群名称必须与 CA 标签中的值一致。

# 创建托管节点组(假设集群名为 my-eks-cluster,区域 ap-southeast-1)
eksctl create nodegroup \
  --cluster my-eks-cluster \
  --region ap-southeast-1 \
  --name ng-worker \
  --node-type t3.medium \
  --nodes 2 \
  --nodes-min 1 \
  --nodes-max 5 \
  --node-labels role=worker \
  --asg-access \
  --managed

# 验证节点组状态
eksctl get nodegroup --cluster my-eks-cluster --region ap-southeast-1

# 查看 ASG 标签是否已自动注入
aws autoscaling describe-auto-scaling-groups \
  --query "AutoScalingGroups[?contains(Tags[?Key=='eks:nodegroup-name'].Value[], 'ng-worker')].[AutoScalingGroupName,MinSize,MaxSize,DesiredCapacity,Tags]" \
  --output json
eksctl 的 --asg-access 会自动为节点组的 IAM 角色附加 CA 所需的策略,并给 ASG 打上 k8s.io/cluster-autoscaler/enabled 和 k8s.io/cluster-autoscaler/<cluster-name> 标签。如果使用 AWS CLI 手动创建,需要自行添加这些标签。

部署 Cluster Autoscaler

CA 以 Deployment 形式运行在集群中,通过 ServiceAccount 的 IAM 角色(IRSA)获得修改 ASG 的权限。以下为关键配置片段:

# 创建 IRSA(如果集群已启用 OIDC)
eksctl create iamserviceaccount \
  --cluster my-eks-cluster \
  --region ap-southeast-1 \
  --name cluster-autoscaler \
  --namespace kube-system \
  --attach-policy-arn arn:aws:iam::aws:policy/AutoScalingFullAccess \
  --approve

# 部署 CA(使用官方 manifest,替换 cluster-name 和 region)
kubectl apply -f https://raw.githubusercontent.com/kubernetes/autoscaler/master/cluster-autoscaler/cloudprovider/aws/examples/cluster-autoscaler-autodiscover.yaml

# 修改 Deployment 中的关键参数
kubectl -n kube-system edit deployment cluster-autoscaler
# 确保以下参数存在:
#   --node-group-auto-discovery=asg:tag=k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/my-eks-cluster
#   --balance-similar-node-groups
#   --skip-nodes-with-system-pods=false

验证自动扩缩容

通过部署一个资源需求超过当前节点容量的 Pod,观察 CA 是否触发扩容。以下为验证步骤:

# 1. 查看当前节点数
kubectl get nodes

# 2. 部署一个需要大量 CPU 的 Pod(示例:请求 3 核,超过单节点可分配量)
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: scale-test
spec:
  containers:
  - name: stress
    image: polinux/stress
    resources:
      requests:
        cpu: "3"
        memory: "2Gi"
    command: ["stress"]
    args: ["--cpu", "3", "--timeout", "300s"]
EOF

# 3. 观察 Pod 状态(应为 Pending)
kubectl get pod scale-test -w

# 4. 查看 CA 日志,确认扩容决策
kubectl -n kube-system logs deployment/cluster-autoscaler --tail=50

# 5. 等待 1-2 分钟,再次查看节点数(应增加)
kubectl get nodes

# 6. 删除测试 Pod,观察缩容(默认 10 分钟后触发)
kubectl delete pod scale-test
缩容默认有 10 分钟延迟(--scale-down-delay-after-add),且节点上不能有无法迁移的 Pod(如未配置 PDB 的裸 Pod)。如果节点长时间不缩容,检查是否有 kube-system 命名空间的 Pod 未设置 --skip-nodes-with-system-pods=false。

关键参数速查

参数作用推荐值
--nodes-minASG 最小容量,CA 不会缩到此值以下1(生产建议 ≥2)
--nodes-maxASG 最大容量,CA 不会扩到此值以上根据预算和配额设定
--node-group-auto-discoveryCA 发现 ASG 的标签过滤条件asg:tag=k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/<cluster-name>
--scale-down-delay-after-add扩容后多久才允许缩容10m(默认)
--scale-down-unneeded-time节点空闲多久才缩容10m(默认)
--balance-similar-node-groups多节点组间均衡扩缩true