Cluster Autoscaler - Amazon EKS
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

Cluster Autoscaler

当 Pod 失败或重新安排到其他节点时,Kubernetes Cluster Autoscaler 会自动调整集群中的节点数。也就是说,Kubernetes Cluster Autoscaler 中的 AWS 云提供程序实施控制 .DesiredReplicas Auto Scaling 组的 Amazon EC2 字段。Cluster Autoscaler 通常作为集群中的 Deployment 安装。它使用领导选择以确保高可用性,但扩展是由单个副本一次完成的。

在部署 Cluster Autoscaler 之前,请务必了解 Kubernetes 概念与 AWS 功能的关系。本主题使用以下术语:

  • Kubernetes Cluster Autoscaler– Kubernetes 控制层面的核心组件,用于制定计划和扩展决策。有关更多信息,请参阅 GitHub 上的 Kubernetes 控制层面常见问题

  • AWS 云提供程序实施 – Kubernetes Cluster Autoscaler 的扩展,该扩展通过与 AWS 平台(例如 Amazon EC2)进行通信来实现 Kubernetes Cluster Autoscaler 的决策。有关更多信息,请参阅 GitHub 上的 AWS 上的 Cluster Autoscaler

  • 节点组 集群中一组节点的 Kubernetes 抽象。–节点组不是真正的 Kubernetes 资源,但它们在 Cluster Autoscaler、Cluster API 和其他组件中作为抽象存在。单个节点组中存在的节点可能会共享多个属性,如标签和标签。但是,它们仍然可以包含多个 可用区 或实例类型。

  • Amazon EC2 Auto Scaling 组 Cluster Autoscaler 使用的 – 的一项功能。AWSAuto Scaling 组适用于大量使用案例。Amazon EC2 Auto Scaling 组配置为启动自动加入其 Kubernetes 集群的实例。它们还在 Kubernetes API 中对其相应的节点资源应用标签和存储桶。

为方便参考,托管节点组 使用 Amazon EC2 Auto Scaling 组实现,并与 Cluster Autoscaler 兼容。

本主题介绍如何将 Cluster Autoscaler 部署到 Amazon EKS 集群并进行配置,以修改 Amazon EC2 Auto Scaling 组。

Prerequisites

在部署 Cluster Autoscaler 之前,您必须满足以下先决条件。

  • 拥有现有 Kubernetes 集群 – 如果您没有集群,请参阅创建 Amazon EKS 集群

  • 您的集群的现有 IAM OIDC 提供商。要确定您是否有安全组,或如果没有安全组,请参阅为集群创建 IAM OIDC 提供商

  • 带 Auto Scaling 组的节点组标记 – Cluster Autoscaler 要求 Auto Scaling 组上具有以下标签,以便自动发现它们。如果您使用 eksctl 创建节点组,则将自动应用这些标签。如果您未使用 eksctl 创建节点组,则必须使用以下标签手动标记 Auto Scaling 组。有关更多信息,请参阅 中的标记 Amazon EC2 资源Amazon EC2 用户指南(适用于 Linux 实例)。

    密钥
    k8s.io/cluster-autoscaler/<cluster-name>

    owned

    k8s.io/cluster-autoscaler/enabled TRUE

创建 IAM 策略和角色

创建向 IAM 角色授予 Cluster Autoscaler 所需权限的 IAM 策略。在整个过程中,将 <example-values>(包括 <>)替换为您自己的值。

  1. 创建 IAM 策略。

    1. 将以下内容保存到名为 cluster-autoscaler-policy.json 的文件中。如果您的现有节点组是使用 eksctl 创建的,并且您使用了 --asg-access 选项,则此策略已存在,并且您可以跳至步骤 2。

      { "Version": "2012-10-17", "Statement": [ { "Action": [ "autoscaling:DescribeAutoScalingGroups", "autoscaling:DescribeAutoScalingInstances", "autoscaling:DescribeLaunchConfigurations", "autoscaling:DescribeTags", "autoscaling:SetDesiredCapacity", "autoscaling:TerminateInstanceInAutoScalingGroup", "ec2:DescribeLaunchTemplateVersions" ], "Resource": "*", "Effect": "Allow" } ] }
    2. 使用以下命令创建策略。您可以更改 policy-name 的值。

      aws iam create-policy \ --policy-name AmazonEKSClusterAutoscalerPolicy \ --policy-document file://cluster-autoscaler-policy.json

      记下输出中返回的 ARN,以便在后面的步骤中使用。

  2. 使用以下任一选项创建 IAM 角色并将 IAM 策略附加到该角色:

    • [ eksctl ]

      1. 如果您使用 eksctl 创建了集群,请运行以下命令。如果您使用 --asg-access 选项创建了节点组,则将 <AmazonEKSClusterAutoscalerPolicy> 替换为 IAM 为您创建的 eksctl 策略的名称。该策略名称类似于 eksctl-<cluster-name>-nodegroup-ng-<xxxxxxxx>-PolicyAutoScaling

        eksctl create iamserviceaccount \ --cluster=<my-cluster> \ --namespace=kube-system \ --name=cluster-autoscaler \ --attach-policy-arn=arn:aws:iam::<AWS_ACCOUNT_ID>:policy/<AmazonEKSClusterAutoscalerPolicy> \ --override-existing-serviceaccounts \ --approve
      2. 如果您使用 --asg-access 选项创建了节点组,建议您分离 IAM 策略,该策略由 eksctl 创建并附加到 Amazon EKS 节点 IAM 角色 为您的节点组创建的 eksctl。通过将策略与节点 IAM 角色分离,Cluster Autoscaler 可以正常工作,但不会为节点上的其他 Pod 授予策略中的权限。有关更多信息,请参阅 中的删除 IAM 身份权限Amazon EC2 用户指南(适用于 Linux 实例)。

    • [ AWS 管理控制台 ]

      1. 通过以下网址打开 IAM 控制台:https://console.amazonaws.cn/iam/

      2. 在导航窗格中,依次选择 Roles (角色)Create Role (创建角色)

      3. Select type of trusted entity (选择受信任实体的类型) 部分中,选择 Web identity (Web 身份)

      4. Choose a web identity provider (选择 Web 身份提供商) 部分中:

        1. 对于 Identity provider (身份提供商),选择您集群的 URL。

        2. 对于 Audience (受众),请选择 sts.amazonaws.com

      5. 选择 Next: Permissions (下一步:权限)

      6. Attach Policy (附加策略) 部分中,选择 您在步骤 1 中创建的用于服务账户的 AmazonEKSClusterAutoscalerPolicy 策略。

      7. 选择下一步: 标签

      8. Add tags (optional) (添加标签(可选)) 屏幕上,您可以为账户添加标签。选择下一步:审核

      9. 对于 Role Name (角色名称),为您的角色输入名称,例如 AmazonEKSClusterAutoscalerRole、 然后选择 Create Role (创建角色)

      10. 创建角色后,在控制台中选择角色以将其打开进行编辑。

      11. 选择 Trust relationships 选项卡,然后选择 Edit trust relationship

      12. 更改看上去类似于以下内容的行:

        "oidc.eks.us-west-2.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E:aud": "sts.amazonaws.com"

        要看上去如下所示,请将 <example values>(包括 <>)更改为您自己的内容:

        "oidc.eks.<region-code>.amazonaws.com/id/<EXAMPLED539D4633E53DE1B716D3041E>:sub": "system:serviceaccount:kube-system:cluster-autoscaler"
      13. 选择 Update Trust Policy (更新可信策略) 以完成操作。

部署 Cluster Autoscaler

完成以下步骤以部署 Cluster Autoscaler。我们建议您先查看部署注意事项并优化 Cluster Autoscaler 部署,然后再将其部署到生产集群。

部署 Cluster Autoscaler

  1. 通过完成与集群所在的区域对应的选项,将 Cluster Autoscaler 部署到集群。

    • 或 中国 (宁夏) 之外的所有区域中国(北京)

      kubectl apply -f https://raw.githubusercontent.com/kubernetes/autoscaler/master/cluster-autoscaler/cloudprovider/aws/examples/cluster-autoscaler-autodiscover.yaml
    • 中国 (宁夏) 或者 中国(北京)

      1. 使用下面的命令下载 清单。

        curl -o cluster-autoscaler-autodiscover.yaml https://raw.githubusercontent.com/kubernetes/autoscaler/master/cluster-autoscaler/cloudprovider/aws/examples/cluster-autoscaler-autodiscover.yaml
      2. 修改清单。

        1. 查看您下载的一个或多个清单文件,并记下映像名称。使用以下命令在本地下载映像。

          docker pull image:<tag>
        2. 使用以下命令标记要推送到中国区域内的 Amazon Elastic Container Registry 存储库的映像。

          docker tag image:<tag> <aws_account_id>.dkr.ecr.<cn-north-1>.amazonaws.com/image:<tag>
        3. 使用以下命令将映像推送到中国区域内的 Amazon ECR 存储库。

          docker push image:<tag> <aws_account_id>.dkr.ecr.<cn-north-1>.amazonaws.com/image:<tag>
        4. 更新一个或多个 Kubernetes 清单文件或以引用您所在区域内的 Amazon ECR 映像 URL。

      3. 应用清单。

        kubectl apply -f cluster-autoscaler-autodiscover.yaml
  2. 使用您之前创建的 cluster-autoscaler 角色的 ARN 对 IAM 服务账户进行注释。将 <example values> 替换为您自己的值。

    kubectl annotate serviceaccount cluster-autoscaler \ -n kube-system \ eks.amazonaws.com/role-arn=arn:aws:iam::<AWS_ACCOUNT_ID>:role/<AmazonEKSClusterAutoscalerRole>
  3. 使用以下命令修补部署以将 cluster-autoscaler.kubernetes.io/safe-to-evict 注释添加到 Cluster Autoscaler Pod。

    kubectl patch deployment cluster-autoscaler \ -n kube-system \ -p '{"spec":{"template":{"metadata":{"annotations":{"cluster-autoscaler.kubernetes.io/safe-to-evict": "false"}}}}}'
  4. 使用以下命令编辑 Cluster Autoscaler 部署。

    kubectl -n kube-system edit deployment.apps/cluster-autoscaler

    编辑 cluster-autoscaler 容器命令以将 <YOUR CLUSTER NAME>(包括 <>)替换为您的集群的名称,并添加以下选项。

    • --balance-similar-node-groups

    • --skip-nodes-with-system-pods=false

    spec: containers: - command: - ./cluster-autoscaler - --v=4 - --stderrthreshold=info - --cloud-provider=aws - --skip-nodes-with-local-storage=false - --expander=least-waste - --node-group-auto-discovery=asg:tag=k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/<YOUR CLUSTER NAME> - --balance-similar-node-groups - --skip-nodes-with-system-pods=false

    保存并关闭该文件以应用更改。

  5. 在 Web 浏览器中,从 GitHub 打开 Cluster Autoscaler 版本页面,找到与您的集群的 Kubernetes 主版本和次要版本匹配的最新 Cluster Autoscaler 版本。例如,如果您集群的 Kubernetes 版本是 1.18,则查找以 1.18. 开头的最新 Cluster Autoscaler 版本。记录该版本的语义版本号 (1.18.n) 以在下一步中使用。

  6. 使用以下命令,将 Cluster Autoscaler 映像标签设置为您在上一步中记录的版本。将 1.18.n 替换为您自己的值。如有必要,请将 k8s.gcr.io/autoscaling/cluster-autoscaler 替换为版本列出的地址。

    kubectl set image deployment cluster-autoscaler \ -n kube-system \ cluster-autoscaler=k8s.gcr.io/autoscaling/cluster-autoscaler:v<1.18.n>

查看 Cluster Autoscaler 日志

部署 Cluster Autoscaler 之后,您可以查看日志并验证它在监控您的集群负载。

使用以下命令查看您的 Cluster Autoscaler 日志。

kubectl -n kube-system logs -f deployment.apps/cluster-autoscaler

输出:

I0926 23:15:55.165842 1 static_autoscaler.go:138] Starting main loop I0926 23:15:55.166279 1 utils.go:595] No pod using affinity / antiaffinity found in cluster, disabling affinity predicate for this loop I0926 23:15:55.166293 1 static_autoscaler.go:294] Filtering out schedulables I0926 23:15:55.166330 1 static_autoscaler.go:311] No schedulable pods I0926 23:15:55.166338 1 static_autoscaler.go:319] No unschedulable pods I0926 23:15:55.166345 1 static_autoscaler.go:366] Calculating unneeded nodes I0926 23:15:55.166357 1 utils.go:552] Skipping ip-192-168-3-111.<region-code>.compute.internal - node group min size reached I0926 23:15:55.166365 1 utils.go:552] Skipping ip-192-168-71-83.<region-code>.compute.internal - node group min size reached I0926 23:15:55.166373 1 utils.go:552] Skipping ip-192-168-60-191.<region-code>.compute.internal - node group min size reached I0926 23:15:55.166435 1 static_autoscaler.go:393] Scale down status: unneededOnly=false lastScaleUpTime=2019-09-26 21:42:40.908059094 ... I0926 23:15:55.166458 1 static_autoscaler.go:403] Starting scale down I0926 23:15:55.166488 1 scale_down.go:706] No candidates for scale down

部署注意事项

查看以下注意事项以优化 Cluster Autoscaler 部署。

扩展注意事项

可将 Cluster Autoscaler 配置为考虑节点的其他功能。这些功能可能包括附加到节点的 Amazon EBS 卷、Amazon EC2 实例类型的节点和 GPU 加速器。

可用区s

我们建议您配置多个节点组,将每个组的范围限定为一个 可用区,然后启用 --balance-similar-node-groups 功能。否则,如果您仅创建一个节点组,则可以将该节点组的范围限定为跨多个可用区。

节点组构成

Cluster Autoscaler 假设您如何使用节点组,例如您在组中使用的实例类型。为了与这些假设保持一致,必须根据以下注意事项配置节点组:

  • 节点组中的每个节点都具有相同的计划属性,例如标签、标签和资源。

    • 对于 MixedInstancePolicies,CPU、内存和 GPU 的实例类型必须具有相同形状。

    • 策略中指定的第一个实例类型模拟计划。

    • 如果您的策略具有其他具有更多资源的实例类型,则在扩展后可能会浪费资源。

    • 如果您的策略包含资源少于原始实例类型的其他实例类型,则 Pod 可能无法在实例上计划。

  • 我们建议您为节点组配置的数量较少,而不是相反。这是因为相反配置对可扩展性有负面影响。

  • 只要两个系统都提供支持,我们建议您使用 Amazon EC2 功能。(例如,使用区域和 MixedInstancePolicy。)

如果可能,建议您使用 托管节点组。托管节点组附带了强大的管理功能,包括 Cluster Autoscaler 的功能,如自动 Amazon EC2 Auto Scaling 组发现和正常节点终止。

EBS 卷

持久性存储对于构建有状态应用程序(如数据库和分布式缓存)至关重要。利用 Amazon EBS 卷,您可以在 Kubernetes 上构建有状态的应用程序,但仅限于在特定区域内执行此操作。有关更多信息,请参阅如何在 Amazon EKS 中使用持久性存储?。如果为每个 可用区 使用单独的 Amazon EBS 卷对多个可用区进行分片(拆分),则有状态应用程序可能高度可用。因此,Cluster Autoscaler 可以平衡 Amazon EC2 Auto Scaling 组的扩展。为此,请确保满足以下条件。

  • 通过设置 balance-similar-node-groups=true 启用节点组均衡。

  • 节点组配置了相同设置,但不同的 可用区 和 Amazon EBS 卷除外。

共同计划

机器学习分布式训练作业从相同区域节点配置的最短延迟中显著受益。这些工作负载将多个 Pod 部署到特定区域。这可以通过使用 topologyKey: failure-domain.beta.kubernetes.io/zone 为所有共同计划的 Pod 或节点关联设置 Pod 关联来实现。根据此配置,Cluster Autoscaler 扩展特定区域以满足需求。您可能希望分配多个 Amazon EC2 Auto Scaling 组,每个 可用区 对应一个组,以便为整个共同计划的工作负载启用故障转移。确保满足以下条件。

  • 通过设置 balance-similar-node-groups=false. 启用节点组均衡

  • 当集群同时包含区域和可用区节点组时,使用 节点关联和/或 pod 抢先。

    • 使用 Node Associate (节点关联) 强制或鼓励区域 Pod 并避免可用区节点组。

    • 如果区域 Pod 计划到区域节点组,则会导致区域 Pod 的容量不平衡。

    • 如果您的地区性工作负载可以容忍中断和重新分配,请配置 pod 抢先,以允许区域扩展的 Pod 在争用较少的区域上强制进行抢先和重新计划。

加速器和 GPU

有些集群利用专用的硬件加速器,如专用 GPU。在横向扩展时,加速器设备插件可能需要几分钟才能将资源通告到集群。在此期间,Cluster Autoscaler 模拟此节点具有加速器。但是,在加速器就绪并更新节点的可用资源之前,无法在节点上计划待处理的 Pod。这可能会导致不必要的重复向外扩展

具有加速器和高 CPU 或内存利用率的节点即使加速器未使用,也不会考虑缩减。但是,这可能会非常昂贵。为避免这些成本,Cluster Autoscaler 可以应用特殊规则,以便在节点具有未占用的加速器时考虑缩减。

要确保这些情况的行为正确,您可以在加速器节点上配置 kubelet 以在联接集群之前标记节点。Cluster Autoscaler 使用此标签选择器来调用加速器优化行为。确保满足以下条件。

  • 适用于 GPU 节点的 kubelet 配置了 --node-labels k8s.amazonaws.com/accelerator=$ACCELERATOR_TYPE

  • 具有加速器的节点遵循相同的计划属性规则。

从零扩展

Cluster Autoscaler 可以将节点组缩放到零或从零开始,这可以节省大量成本。它通过检查在 Auto Scaling 或 InstanceType 中指定的 LaunchConfiguration 来检测 LaunchTemplate 组的 CPU、内存和 GPU 资源。某些 Pod 需要其他资源,例如 WindowsENIPrivateIPv4Address 或者特定的 NodeSelectorsTaints,这些资源无法从 LaunchConfiguration 发现。Cluster Autoscaler 可以通过从 Auto Scaling 组的以下标签发现这些因素来考虑这些因素。

Key: k8s.io/cluster-autoscaler/node-template/resources/$RESOURCE_NAME Value: 5 Key: k8s.io/cluster-autoscaler/node-template/label/$LABEL_KEY Value: $LABEL_VALUE Key: k8s.io/cluster-autoscaler/node-template/taint/$TAINT_KEY Value: NoSchedule
注意

当扩展到零时,您的容量将返回到 Amazon EC2,并且将来可能不可用。

其他配置参数

有许多配置选项可用于调整 Cluster Autoscaler 的行为和性能。有关参数的完整列表,请参阅 GitHub 上的对于 CA 有哪些参数?

性能注意事项

您可以更改以调整 Cluster Autoscaler 的性能和可扩展性的主要项目是向进程提供的资源、算法的扫描间隔以及集群中的节点组数量。此算法的实际运行时复杂性还有一些其他因素,例如安排插件复杂性和 Pod 数量。这些参数被视为不可配置的参数,因为它们对于集群的工作负载是自然的,无法轻松地进行调整。

可扩展性 是指 Cluster Autoscaler 在 Kubernetes 集群中的 Pod 和节点数增加时的表现。如果达到可扩展性限制,Cluster Autoscaler 的性能和功能将会下降。此外,如果它超过其可扩展性限制,Cluster Autoscaler 将无法再在集群中添加或删除节点。

性能 是指 Cluster Autoscaler 做出和执行扩展决策的速度。完全执行的 Cluster Autoscaler 立即做出决策并调用扩展操作来响应刺激,例如 Pod 变得不可计划。

熟悉 AutoScaling 算法的运行时复杂性将使优化 Cluster Autoscaler 以使其在大型集群中继续正常运行(超过 1000 个节点)更轻松。

Cluster Autoscaler 将整个集群的状态加载到内存中,包括 Pod、节点和节点组。在每个扫描间隔内,算法将标识不可计划的 pod 并模拟针对每个节点组的计划。优化这些因素会做出不同的权衡,应仔细考虑这一点。

垂直自动扩展

将 Cluster Autoscaler 扩展到较大集群的最简单方法是增加其部署的资源请求。大型集群的内存和 CPU 都应该增加,但这随集群大小而明显不同。自动扩展算法将所有 Pod 和节点存储在内存中。在某些情况下,这可能会导致内存占用大于 1 GB。增加资源通常是手动完成的。如果您发现常量资源优化导致运营负担,请考虑使用 Addon ResizerVertical Pod Autoscaler

减少节点组数量

最大程度地减少节点组数量是确保 Cluster Autoscaler 在大型集群上表现良好的一种方法。如果您根据单个团队或应用程序来构建节点组,这可能会非常困难。即使 Kubernetes API 完全支持此参数,它也被视为具有扩展性推理的 Cluster Autoscaler 防模式。使用多个节点组(如 Spot 或 GPU 实例)有很多原因。在许多情况下,有利用少量组实现相同效果的替代设计。确保满足以下条件。

  • Pod 隔离是使用命名空间而不是节点组完成的。

    • 在低信任多租户集群中可能无法做到这一点。

    • Pod ResourceRequestsResourceLimits 已正确设置,以避免资源争用。

    • 较大的实例类型会得到更最佳的装填和减少系统 pod 开销。

  • NodeTaintsNodeSelectors 用于将 Pod 计划为异常,而不是规则。

  • 区域资源定义为具有多个Amazon EC2的单个 Auto Scaling 可用区 组。

减少扫描间隔

低扫描间隔(如十秒)可确保在 Pod 变得不可计划时 Cluster Autoscaler 尽快做出响应。但是,每次扫描会导致对 Kubernetes API 和 Amazon EC2 Auto Scaling 组或 Amazon EKS 托管节点组 API 进行许多 API 调用。这些 API 调用可能会导致速率限制甚至 Kubernetes 控制层面的服务不可用。

默认扫描间隔为 10 秒,但在 AWS 上,启动节点需要更长的时间来启动新实例。这意味着,可以增加时间间隔,而不会显著增加总体扩展时间。例如,如果启动节点需要两分钟时间,将时间间隔更改为一分钟会导致对于较慢的扩展,将 API 调用减少 6 倍。

跨节点组分区

Cluster Autoscaler 可以配置为对一组特定的节点组进行操作。使用此功能,可以部署 Cluster Autoscaler 的多个实例,每个实例均配置为对一组不同的节点组执行操作。使用此策略时,您可以使用任意数量的节点组,并需要花费交易成本来提高可扩展性。但是,我们仅建议使用此策略作为提高性能的最后一个手段。

Cluster Autoscaler 最初不是为此配置设计的,因此有一些副作用。由于分片不通信,因此多个 Autoscaler 可能会尝试计划一个不可计划的 pod。这可能导致不必要的多个节点组扩展。额外节点在 scale-down-delay 之后缩减。

metadata: name: cluster-autoscaler namespace: cluster-autoscaler-1 ... --nodes=1:10:k8s-worker-asg-1 --nodes=1:10:k8s-worker-asg-2 --- metadata: name: cluster-autoscaler namespace: cluster-autoscaler-2 ... --nodes=1:10:k8s-worker-asg-3 --nodes=1:10:k8s-worker-asg-4

确保以下条件为 true。

  • 每个分片均配置为指向一组唯一的 Amazon EC2 Auto Scaling 组。

  • 每个分片将部署到单独的命名空间,以避免领导选择冲突。

成本效率和可用性

用于优化 Cluster Autoscaler 的成本效益的主要选项与预置 Amazon EC2 实例相关。此外,必须使成本效益与可用性保持平衡。本节介绍一些策略,例如,使用 Spot 实例降低成本和超额配置,以减少创建新节点时的延迟。

  • 可用性 可以快速安排 – Pod,而不会造成中断。即使在需要计划新创建的 Pod 时,以及缩减的节点终止计划的任何剩余 Pod 时,也是如此。

  • 成本 – 由扩展和缩减事件背后的决策决定。如果现有节点未充分利用或添加了对传入 Pod 过大的新节点,则会浪费资源。根据具体使用案例,可能会因主动缩减决策而提前终止 Pod 而产生相关成本。

Spot 实例

您可以在节点组中使用 Spot 实例,节省按需价格最多 1 折。在 Amazon EC2 需要容量退回时, Spot 实例可能会随时中断。只要您的 Insufficient Capacity Errors Amazon EC2 组由于缺少可用容量而无法扩展,Auto Scaling 就会发生。选择许多不同的实例系列有两个主要优势。首先,它可以通过点击多个 Spot 容量池来提高达到所需规模的几率。其次,它还可以减少 Spot 实例中断对集群可用性的影响。使用 Spot 实例的混合实例策略是在不增加节点组数量的情况下提高多样性的好方法。但是,您知道,如果您需要保证资源,请使用按需实例而不是 Spot 实例。

Spot 实例可能会在对实例的需求增加时终止。有关更多信息,请参阅 Spot 实例中断Amazon EC2 用户指南(适用于 Linux 实例)部分。AWS 节点终止处理程序项目会在节点出现故障时自动提醒 Kubernetes 控制层面。该项目使用 Kubernetes API 封锁节点,以确保不在该节点安排任何新工作,然后耗尽它并删除任何现有工作。

在配置混合实例策略时,所有实例类型都必须具有类似的资源容量。Autoscaler 的计划模拟器使用混合实例策略中的第一个实例类型。如果后续实例类型较大,则在扩展后可能会浪费资源。如果较小,您的 Pod 可能会由于容量不足而无法在新实例上计划。例如,M4M5M5a,M5n 实例的 CPU 和内存大小都相似,并且非常适合混合实例策略。实例选择器工具可帮助您识别类似的实例类型。Amazon EC2有关更多信息,请参阅 GitHub 上的 Amazon EC2 实例选择器

我们建议您将按需实例和 Spot 实例容量隔离到单独的 Amazon EC2 Auto Scaling 组中。我们建议不要使用基本容量策略,因为按需实例和 Spot 实例的计划属性不同。Spot 实例可以随时中断。当 Amazon EC2 需要容量退回时,抢先节点通常会受到限制,因此需要显式 Pod 容忍抢先行为。这将为节点生成不同的计划属性,因此它们应分成多个 Amazon EC2 Auto Scaling 组。

Cluster Autoscaler 涉及 Expanders 的概念。它们共同提供了不同的策略,用于选择要扩展的节点组。策略 --expander=least-waste 是很好的通用默认值,如果您将使用多个节点组来细分 Spot 实例,如前所述,它有助于通过扩展在扩展活动后最适合的组来进一步优化节点组成本。

确定节点组或 Auto Scaling 组的优先级

您也可以使用 Priority 展开器配置基于优先级的自动扩展。--expander=priority 使您的集群能够优先处理节点组或 Auto Scaling 组,如果由于任何原因无法扩展,它将在优先级列表中选择下一个节点组。例如,这在由于 GPU 可为工作负载提供最佳性能而希望使用 P3 实例类型的情况下非常有用,但作为第二个选项,您也可以使用 P2 实例类型。例如:

apiVersion: v1 kind: ConfigMap metadata: name: cluster-autoscaler-priority-expander namespace: kube-system data: priority: |- 10: - .*p2-node-group.* 50: - .*p3-node-group.*

Cluster Autoscaler 将尝试扩展与名称 Amazon EC2 匹配的 Auto Scaling p2-node-group 组。如果此操作在 --max-node-provision-time 中不成功,它将尝试扩展与名称 Amazon EC2 匹配的 Auto Scaling p3-node-group 组。此值默认为 15 分钟,并且可以减少以做出响应速度更高的节点组选择,但如果值过低,则可能导致不必要的横向扩展。

Overprovisioning

Cluster Autoscaler 确保节点仅在需要时添加到集群中,从而最大限度地降低成本。这极大影响了部署延迟,因为许多 Pod 将必须等待节点扩展,然后才能安排它们。节点可能需要多分钟才能变得可用,这可能会按数量级增加 pod 计划延迟。

这可使用超额预置来缓解,后者会针对计划延迟而产生费用。过度预置是使用具有负优先级的临时 Pod 实现的。这些 Pod 在集群中占用空间。当新创建的 Pod 无法计划并具有更高的优先级时,临时 Pod 将抢先占用空间。然后,临时 Pod 将变得不可计划,这会导致 Cluster Autoscaler 扩展超额预配置节点。

超额预还有其他好处。在没有超额预的情况下,高利用率集群中的 Pod 使用 preferredDuringSchedulingIgnoredDuringExecution 规则制定不太最佳的计划决策。一个常用案例是,使用 可用区 为跨 AntiAffinity 的高可用应用程序的 Pod 分隔。过度预配置可能会显著增加所需区域的节点可用的可能性。

选择合适的超额预置容量至关重要。做出此决策的一种方法是确定平均扩展频率,并将此数字除以向上扩展新节点所需的时间。例如,如果您平均每 30 秒需要一个新节点,并且 Amazon EC2 需要 30 秒来预置一个新节点,则一个超额预置节点可确保始终有额外的节点可用。这可以减少计划延迟 30 秒,但需要支付单个额外 Amazon EC2 实例的成本。要改进地区性计划决策,您可以过度预置节点数,使之等于 Amazon EC2 Auto Scaling 组中的可用区数量。这样做可确保计划程序可以为传入 Pod 选择最佳区域。

防止缩小移出

一些工作负载的移出成本很高。大数据分析、机器学习任务和测试运行程序可能需要很长时间才能完成,并且必须在它们中断时重新启动。Cluster Autoscaler 的作用是缩减 scale-down-utilization-threshold 下的任何节点。这会中断节点上的任何剩余 Pod。但是,您可以通过确保移出成本高昂的 Pod 受到 Cluster Autoscaler 识别的标签的保护来防止这种情况。为此,请确保移出成本高昂的 Pod 具有标签 cluster-autoscaler.kubernetes.io/safe-to-evict=false