Autoscaling
弹性伸缩是一项功能,可以自动上下伸缩您的资源以满足不断变化的需求。若没有此项重要的 Kubernetes 功能,则需要耗费大量的人力资源来手动执行这些工作。
Amazon EKS 支持两款弹性缩放产品:Kubernetes Cluster Autoscaler
Cluster Autoscaler
当 pods 失败或被重新安排到其他节点时,Kubernetes Cluster Autoscaler
在部署集群 Cluster Autoscaler 之前,请确保您熟悉 Kubernetes 概念与 Amazon 功能相互联系的方式。本主题中使用了以下术语:
-
Kubernetes Cluster Autoscaler – Kubernetes 控制面板的核心组件,用于制定调度和缩放决策。有关更多信息,请参阅 GitHub 上的 Kubernetes 控制面板常见问题
。 -
Amazon 云提供商实施 – Kubernetes Cluster Autoscaler 的扩展,通过与 Amazon 产品和服务(例如 Amazon EC2)通信实施 Kubernetes Cluster Autoscaler 的决策。有关更多信息,请在 GitHub 上参阅 Amazon 上的 Cluster Autoscaler
。 -
节点组 – 集群中一组节点的 Kubernetes 抽象。节点组不是真正的 Kubernetes 资源,但它们在 Cluster Autoscaler、集群 API 和其他组件中作为抽象被找到。在单个节点组中找到的节点可能共享多个常见属性,如标签和污点。但是,它们仍然可以由多个可用区或实例类型组成。
-
Amazon EC2 Auto Scaling 组 – 为 Cluster Autoscaler 所用的一个Amazon功能。Auto Scaling 组适用于大量使用案例。Amazon EC2 Auto Scaling 组配置为启动自动加入其 Kubernetes 集群的实例。它们还将标签和污点应用到 Kubernetes API 中的相应节点资源。
作为参考,托管节点组 使用 Amazon EC2 Auto Scaling 组进行管理,并且与 Cluster Autoscaler 兼容。
本主题说明如何将 Cluster Autoscaler 部署到 Amazon EKS 集群以及如何配置它来修改 Amazon EC2 Auto Scaling 组。
先决条件
在部署集群 Cluster Autoscaler之前,您必须满足以下先决条件:
-
现有 Amazon EKS 集群:如果您没有集群,请参阅创建 Amazon EKS 集群。
-
集群的现有 IAM OIDC 提供商。要确定是否具有 IAM OIDC 提供商,还是需要创建一个,请参阅 为集群创建 IAM OIDC 提供商。
-
带有 Auto Scaling 组标签的节点组。Cluster Autoscaler 要求您 Auto Scaling 组上具有以下标签,以便能够自动发现它们。
-
如果您使用
eksctl
创建节点组,则节点组会自动应用这些标签。 如果未使用
eksctl
,则必须使用以下标签手动标记您的 Auto Scaling 组。有关更多信息,请参阅适用于 Linux 实例的 Amazon EC2 用户指南 中的标记 Amazon EC2 资源。
键 值 k8s.io/cluster-autoscaler/
my-cluster
owned
k8s.io/cluster-autoscaler/enabled
true
-
创建 IAM policy 和角色
创建授予 Cluster Autoscaler 使用 IAM 角色所需权限的 IAM policy。将整个过程中的所有
替换为您自己的值。example values
-
创建一个 IAM policy。
-
将以下内容保存到名为
cluster-autoscaler-policy.json
的文件中。如果现有节点组是使用eksctl
创建的并且您使用了--asg-access
选项,则此策略已存在,您可以跳至第 2 步。{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "autoscaling:SetDesiredCapacity", "autoscaling:TerminateInstanceInAutoScalingGroup" ], "Resource": "*", "Condition": { "StringEquals": { "aws:ResourceTag/k8s.io/cluster-autoscaler/
my-cluster
": "owned" } } }, { "Sid": "VisualEditor1", "Effect": "Allow", "Action": [ "autoscaling:DescribeAutoScalingInstances", "autoscaling:DescribeAutoScalingGroups", "ec2:DescribeLaunchTemplateVersions", "autoscaling:DescribeTags", "autoscaling:DescribeLaunchConfigurations", "ec2:DescribeInstanceTypes" ], "Resource": "*" } ] } -
使用以下命令创建策略。您可以更改
policy-name
的值。aws iam create-policy \ --policy-name AmazonEKSClusterAutoscalerPolicy \ --policy-document file://cluster-autoscaler-policy.json
记下输出中返回的 Amazon Resource Name (ARN)。您需要在后面的步骤中用到它。
-
-
您可以创建一个 IAM 角色并使用
eksctl
或 Amazon Web Services Management Console 向其附加 IAM policy。为以下说明选择所需的选项卡。
部署 Cluster Autoscaler
要部署 Cluster Autoscaler,请完成以下步骤。建议您查看 部署注意事项 并优化 Cluster Autoscaler 部署,然后再将其部署到生产集群。
部署 Cluster Autoscaler
-
curl -O https://raw.githubusercontent.com/kubernetes/autoscaler/master/cluster-autoscaler/cloudprovider/aws/examples/cluster-autoscaler-autodiscover.yaml
-
修改 YAML 文件并将
<YOUR CLUSTER NAME>
替换为您的集群名称。另请考虑替换您的环境决定的cpu
和memory
值。 -
将 YAML 文件应用于集群。
中国(宁夏)或中国(北京)
-
使用下面的命令下载清单。
curl -O https://raw.githubusercontent.com/kubernetes/autoscaler/master/cluster-autoscaler/cloudprovider/aws/examples/cluster-autoscaler-autodiscover.yaml
-
修改清单。
-
查看您下载的一个或多个清单文件,并记下镜像的名称。使用下面的命令将镜像下载到本地。
docker pull image:
tag
-
使用以下命令标记要推送到中国 Amazon Elastic Container Registry 存储库的镜像。
docker tag image:
tag
111122223333
.dkr.ecr.cn-north-1
.amazonaws.com.cn/image:tag
-
通过以下命令将镜像推送到中国 Amazon ECR 存储库。
docker push image:
tag
111122223333
.dkr.ecr.cn-north-1
.amazonaws.com.cn/image:tag
-
更新 Kubernetes 的一个或多个清单文件,以引用您所在区域的 Amazon ECR 镜像 URL。
-
-
运用该清单。
kubectl apply -f cluster-autoscaler-autodiscover.yaml
-
-
使用您以前创建的 IAM 角色的 ARN 对
cluster-autoscaler
服务账户添加注释。将
替换为您自己的值。example values
kubectl annotate serviceaccount cluster-autoscaler \ -n kube-system \ eks.amazonaws.com/role-arn=arn:aws:iam::
ACCOUNT_ID
:role/AmazonEKSClusterAutoscalerRole
-
使用以下命令修补部署以向 Cluster Autoscaler pods 添加
cluster-autoscaler.kubernetes.io/safe-to-evict
注释。kubectl patch deployment cluster-autoscaler \ -n kube-system \ -p '{"spec":{"template":{"metadata":{"annotations":{"cluster-autoscaler.kubernetes.io/safe-to-evict": "false"}}}}}'
-
使用以下命令编辑 Cluster Autoscaler 部署。
kubectl -n kube-system edit deployment.apps/cluster-autoscaler
编辑用于添加以下选项的
cluster-autoscaler
容器命令。--balance-similar-node-groups
确保所有可用区都有足够的可用计算。--skip-nodes-with-system-pods=false
确保缩减到零时不会出现问题。-
--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/
my-cluster
- --balance-similar-node-groups - --skip-nodes-with-system-pods=false保存并关闭该文件以应用更改。
-
-
在 Web 浏览器中从 GitHub 打开 Cluster Autoscaler 版本
页面,找到与您集群的 Kubernetes 主版本和次要版本相匹配的 Cluster Autoscaler 最新版本。例如,如果您集群的 Kubernetes 版本是 1.25
,则查找以1.25
开头的最新 Cluster Autoscaler 版本。记录该版本的语义版本号 (1.25.n
) 以在下一步中使用。 -
使用以下命令,将 Cluster Autoscaler 映像标签设置为您在上一步中记录的版本。将
替换为您自己的值。1.25.n
kubectl set image deployment cluster-autoscaler \ -n kube-system \ cluster-autoscaler=registry.k8s.io/autoscaling/cluster-autoscaler:v
1.25.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 加速器。
跨多个可用区设定节点组的范围
我们建议您配置多个节点组,将每个组的范围设定为单个可用区,并启用 --balance-similar-node-groups
功能。如果您只创建一个节点组,则将该节点组的范围设置为跨越多个可用区。
如果将 --balance-similar-node-groups
设为 true,请确保希望 Cluster Autoscaler 平衡的节点组具有匹配的标签(自动添加的区域标签除外)。可以向有着不同标签的各个节点传递一个 --balancing-ignore-label
标志,这样就会直接对它们进行平衡,而不考虑它们的标签;但只能在需要时这样做。
优化节点组
Cluster Autoscaler 会假定您使用节点组的方式。包括您在组中使用的实例类型。要与这些假设保持一致,请根据以下注意事项和建议配置节点组:
-
节点组中的每个节点必须具有相同的调度属性,包括标签、污点和资源。
-
对于
MixedInstancePolicies
,实例类型必须具有兼容的 CPU、内存和 GPU 规范。 -
策略中指定的第一个实例类型模拟调度。
-
如果您的策略具有拥有更多资源的其他实例类型,则在横向扩展后可能会浪费资源。
-
如果您的策略具有其他实例类型,其资源比原始实例类型少,则 pods 在实例上调度可能失败。
-
-
请使用较多节点配置较少数量的节点组,因为相反的配置可能会对可扩展性产生不利影响。
-
只要两个系统都为 Amazon EC2 功能提供支持,就可以使用 Amazon EC2 功能(例如,使用区域和
MixedInstancePolicy
。)
如果可能,建议您使用 托管节点组。托管节点组附带强大的管理功能。这包括适用于 Cluster Autoscaler 的功能,例如 Amazon EC2 Auto Scaling 自动组发现功能和正常节点终止功能。
将 EBS 卷用作持久性存储
持久性存储对于构建有状态应用程序(如数据库和分布式缓存)至关重要。借助 Amazon EBS 卷,您可以在 Kubernetes 上构建有状态的应用程序。但是,您只能在单个可用区中构建。有关更多信息,请参阅如何使用 Amazon EKS 中的持久性存储?
-
通过设置
balance-similar-node-groups=true
启用节点组平衡。 -
将节点组配置为具有相同的设置(除了位于多个可用区内并使用不同的 Amazon EBS 卷之外)。
协同调度
Machine Learning 分布式培训作业可从同区节点配置的最小化延迟中获益匪浅。这些工作负载将多个 pods 部署到特定区域。您可以通过使用 topologyKey:
topology.kubernetes.io/zone
为所有协同调度 pods 或节点亲和性设置 pod 亲和性来实现这一点。使用此配置,Cluster Autoscaler 可横向扩展特定区域以满足需求。分配多个 Amazon EC2 Auto Scaling 组,每个可用区分配一个组,以便为整个协同调度工作负载启用故障转移。确保满足以下条件:
加速器和 GPU
某些集群使用专用硬件加速器,例如专用 GPU。横向扩展时,加速器可能需要几分钟才能将资源通告到集群。在此期间,Cluster Autoscaler 会模拟此节点具有加速器的情况。但是,在加速器准备就绪并更新节点的可用资源之前,无法在节点上调度待处理的 pods。这可能会导致重复、不必要的横向扩展
即使加速器未使用,也不会考虑缩减具有加速器和高 CPU 或内存利用率的节点。但这可能会导致不必要的成本。要避免这些成本,在节点具有未占用的加速器的情况下,Cluster Autoscaler 可以应用特殊规则来考虑节点进行缩减。
要确保在这些情况下执行正确行为,请在加速器节点上配置 kubelet
,以便在节点加入集群之前对其进行标注。Cluster Autoscaler 会使用此标注选择器调用经加速器优化的行为。确保满足以下条件:
-
用于 GPU 节点的
kubelet
配置有--node-labels k8s.amazonaws.com/accelerator=$ACCELERATOR_TYPE
。 -
带有加速器的节点遵守相同的调度属性规则。
从零扩展
Cluster Autoscaler 可以将节点组缩减到零和从零扩展节点组。这可以节省大量成本。Cluster Autoscaler 会通过检查其 LaunchConfiguration
或者 LaunchTemplate
中指定的 InstanceType
来检测 Auto Scaling 组的 CPU、内存和 GPU 资源。某些 pods 需要额外的资源,例如 WindowsENI
或者 PrivateIPv4Address
。或者它们可能需要特定的 NodeSelectors
或 Taints
。后两者不能从 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,并可能会在将来变得不可用。
您可以使用 describeNodegroup 诊断缩减到零和从零扩展时托管节点组存在的问题。
简化了 Kubernetes 1.24
及更高版本的集群的行为。对于早期版本,您需要使用其负责的节点的详细信息来标记底层 Amazon EC2 Auto Scaling 组。对于 Kubernetes 1.24
及更高版本的集群,当托管节点组中没有正在运行的节点时,Cluster Autoscaler 会调用 Amazon EKS DescribeNodegroup
API 操作。此 API 操作提供了 Cluster Autoscaler 所需有关托管节点组的资源、标签和污点的信息。此功能要求您向 Cluster Autoscaler 服务账户 IAM policy 添加 eks:DescribeNodegroup
权限。当为 Amazon EKS 托管节点组提供支持的自动扩缩组上 Cluster Autoscaler 标签的值与节点组本身发生冲突时,Cluster Autoscaler 倾向于使用自动扩缩组标签的值。这样您就能根据需要覆盖值。
其他配置参数
有许多配置选项可用于调整 Cluster Autoscaler 的行为和性能。有关参数的完整列表,请参阅 GitHub 上的面向 CA 的参数是什么?
性能注意事项
您可以更改一些关键项目来优化 Cluster Autoscaler 的性能和可扩展性。主要项目包括提供给进程的任何资源、算法的扫描间隔以及集群中的节点组数。但是,此算法的真正运行时间复杂性也涉及其他几个因素,其中包括调度插件的复杂性和 pods 的数量。这些因素被视为不可配置的参数,因为它们是集群工作负载的组成部分,而且不容易进行优化。
可扩展性是指随着 Kubernetes 集群中的 pods 和节点数量的增加,Cluster Autoscaler 的性能如何。如果达到其可扩展性配额,则 Cluster Autoscaler 的性能和功能会降低。此外,当超出其可扩展性配额时,Cluster Autoscaler 就无法再添加或删除集群中的节点。
性能是指 Cluster Autoscaler 可以做出和实施扩展决策的速度。性能完美的 Cluster Autoscaler 可以立即做出决策并调用扩展操作,以对特定状况做出响应,例如 pod 变得不可调度。
熟悉弹性伸缩算法的运行时间复杂性。这样可以更轻松地优化 Cluster Autoscaler,以使其在大型集群(具有超过 1000 个节点
Cluster Autoscaler 会将整个集群的状态加载到内存中,包括 pods、节点和节点组。在每个扫描间隔时间期间,算法会识别不可调度的 pods 并模拟每个节点组的调度。请注意,以不同的方式优化这些因素都会需要做出不同的折衷。
垂直弹性伸缩
您可以通过增加其部署的资源请求,将 Cluster Autoscaler 扩展到较大的集群。这是实现这一点的更简单的方法之一。增加大型集群的内存和 CPU。请注意,内存和 CPU 应该增加的量在很大程度上取决于特定的集群大小。自动缩放算法将所有 pods 和节点存储在内存中。在某些情况下,这可能会导致内存占用大于 1 GB。您通常需要手动增加资源。如果您发现经常需要手动增加资源,请考虑使用 Addon Resizer
减少节点组数量
您可以减少节点组的数量来提高 Cluster Autoscaler 在大型集群中的性能。如果您以单个团队或应用程序为基础构建节点组,此做法可能具有挑战性。虽然 Kubernetes API 完全支持此做法,但它被认为是 Cluster Autoscaler 反面模式,会影响可扩展性。使用多个节点组有许多好处,例如同时使用 Spot 或 GPU 实例。在许多情况下有替代设计,可在使用少量组的同时实现同样效果。确保满足以下条件:
-
使用命名空间而非节点组来隔离 pods。
-
您可能无法在低信任度、多租户集群中采用此做法。
-
恰当设置 pod
ResourceRequests
和ResourceLimits
来避免资源争用。 -
使用较大的实例类型实现更优化的装箱并减少系统 pod 开销。
-
-
避免使用
NodeTaints
或NodeSelectors
来调度 pods。仅在少数情况下使用它们。 -
将区域资源定义为具有多个可用区的单个 Amazon EC2 Auto Scaling 组。
缩短扫描间隔时间
缩短扫描间隔时间(如原定设置为 10 秒)可确保 Cluster Autoscaler 在 pods 变为不可调度时尽快做出响应。但是,每次扫描都会导致对 Kubernetes API 和 Amazon EC2 Auto Scaling 组或 Amazon EKS 托管节点组 API 进行多次 API 调用。这些 API 调用可能会导致您的 Kubernetes 控制面板的速率受限甚至服务不可用。
原定设置的扫描间隔时间为十秒,但在Amazon上,启动节点需要更长的时间来启动新的实例。这意味着,可以在不显著增加整体纵向扩展时间的情况下提高扫描间隔时间。例如,如果启动节点需要两分钟时间,请不要将扫描间隔更改为一分钟,因为这可能会出现虽然 API 调用减少 6 倍但纵向扩展速度减慢 38%。
跨节点组共享
您可以将 Cluster Autoscaler 配置为对一组特定的节点组进行操作。通过使用此功能,您可以部署 Cluster Autoscaler 的多个实例。将每个实例配置为在一组不同的节点组上运行。这样,您就可以使用任意大量的节点组,从而换取可扩展性的成本。但是,我们只建议您在万不得已时才采用此做法来提高 Cluster Autoscaler 的性能。
这种配置有其缺点:可能会导致多个节点组不必要的横向扩展。在 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
确保满足以下条件。
-
每个分区都配置为指向一组唯一的 Amazon EC2 Auto Scaling 组。
-
每个分区都部署到一个单独的命名空间,以避免领导选举冲突。
成本效益和可用性
优化 Cluster Autoscaler 成本效益的主要选择与预置 Amazon EC2 实例有关。此外,成本效益必须与可用性保持平衡。本节介绍使用 Spot 实例降低成本和超额配置以减少创建新节点时的延迟等策略。
-
可用性 – 能够快速、不中断地调度 Pod。即使是在需要调度新创建的 pods 以及缩减的节点终止向其调度的任何剩余 pods 时,也能做到这一点。
-
成本 – 由横向扩展和横向缩减事件背后的决策确定。如果现有节点未充分利用,或添加的新节点对于传入的 pods 而言太大,则资源将会被浪费。根据具体的使用案例,可能会由于积极的缩减决策导致产生与过早终止 pods 相关的成本。
Spot 实例
您可以使用节点组中的 Spot 实例,按需价格最高可节省 90%。这可能会在 Amazon EC2 需要收回容量时随时中断 Spot 实例。每当您的 Amazon EC2 Auto Scaling 组由于缺乏可用容量而无法纵向扩展时,就会发生 Insufficient
Capacity Errors
。选择许多不同的实例系列有两个主要好处。首先,它可以通过利用许多 Spot 容量池来提高您实现所需扩展的机会。其次,它还可以减少 Spot 实例中断对集群可用性的影响。包含 Spot 实例的混合实例策略是在不增加节点组数量的情况下提高多样性的好方法。但是,请注意,如果您需要有保障的资源,请使用按需实例,而不要使用 Spot 实例。
当对实例的需求增加时,可能会终止 Spot 实例。有关更多信息,请参阅适用于 Linux 实例的 Amazon EC2 用户指南中的 Spot 实例中断部分。Amazon Node Termination Handler
在配置混合实例策略时,所有实例类型具有相似的资源容量至关重要。Autoscaler 的调度模拟器使用混合实例策略中的第一个实例类型。如果后续实例类型较大,在纵向扩展后可能会造成资源浪费。如果实例较小,由于容量不足,pods 可能无法在新实例上实现调度。例如,M4
、M5
、M5a,
和 M5n
实例都具有相似数量的 CPU 和内存,是混合实例策略的绝佳候选项。Amazon EC2 实例选择器工具可以帮助您识别相似的实例类型或其他重要条件,例如大小。有关更多信息,请参阅 GitHub 上的 Amazon EC2 实例选择器
我们建议您将按需实例和 Spot 实例容量分离到不同的 Amazon EC2 Auto Scaling 组中。由于按需实例和 Spot 实例的调度属性不同,我们建议使用基本容量策略。Spot 实例可以随时中断。当 Amazon EC2 需要收回容量时,抢占节点通常会受到影响,因此需要对抢占行为具有明确的 pod 容忍度。这就导致了不同的节点调度属性,因此应将它们分到多个 Amazon EC2 Auto Scaling 组中。
Cluster Autoscaler 涉及 Expander--expander=least-waste
策略是一种不错的通用型原定设置,如果您打算使用多个节点组实现 Spot 实例多样化(如前所述),那么它可以通过扩缩在扩缩活动后利用率最佳的组来进一步优化节点组的成本。
确定节点组或 Auto Scaling 组的优先级
您还可以通过使用 Priority
扩展器来配置基于优先级的弹性伸缩。--expander=priority
使您的集群能够确定节点组或 Auto Scaling 组的优先级,如果节点组由于任何原因无法扩展,则其会选择优先级列表中下一个节点组。这在某些情况下非常有用,例如您想要使用 P3
实例类型,因为它们的 GPU 为您的工作负载提供了最佳性能,但您也可以将 P2
实例类型作为第二个选择。例如:
apiVersion: v1 kind: ConfigMap metadata: name: cluster-autoscaler-priority-expander namespace: kube-system data: priorities: |- 10: - .*p2-node-group.* 50: - .*p3-node-group.*
Cluster Autoscaler 尝试纵向扩展与名称 p3-node-group
相匹配的 Amazon EC2 Auto Scaling 组。如果此操作在 --max-node-provision-time
内未成功,则其会尝试扩展与名称 p2-node-group
相匹配的 Amazon EC2 Auto Scaling 组。此值原定设置为 15 分钟,可以降低此值以选择响应更快的节点组。但是,如果此值太低,则可能会发生不必要的横向扩展。
超额配置
Cluster Autoscaler 可以确保仅在需要节点时将节点添加到集群,并在节点未使用时删除节点,以此来帮助最大限度地降低成本。这会极大地影响部署延迟,因为许多 pods 必须等待节点纵向扩展后才能进行调度。节点可能需要几分钟才能使用,这可能会将 pod 调度延迟增加一个数量级。
此问题可以通过超额配置
超额配置还有其他好处。在没有超额配置的情况下,高利用率集群中的 pods 可以使用 preferredDuringSchedulingIgnoredDuringExecution
规则做出次优调度决定。这种情况的一个常见用例是使用 AntiAffinity
跨可用区为高可用性应用程序分离 pods。超额配置可以显著提高所需区域的节点的可用性几率。
选择适当数量的超额配置容量非常重要。确保选择适当数量的一种方法是,用平均纵向扩展频率除以纵向扩展新节点所需的时间。例如,如果您平均每 30 秒需要一个新节点,而 Amazon EC2 预置新节点需要 30 秒,则超额配置单个节点可确保始终有一个额外的节点可用。这样就可以以单个额外 Amazon EC2 实例为成本将调度延迟减少 30 秒。为了做出更好的分区调度决策,您还可以超额配置节点数,使其与 Amazon EC2 Auto Scaling 组中的可用区数量相同。这样可确保调度器可以为传入 pods 选择最佳区域。
防止缩减移出
移出某些工作负载成本非常高昂。大数据分析、机器学习任务和测试运行器可能需要很长时间才能完成,而且如果这些过程被中断,必须要重新启动。Cluster Autoscaler 可以帮助缩减 scale-down-utilization-threshold
下的任意节点。此操作会中断节点上的所有剩余 pods。但是,您可以通过确保使用经 Cluster Autoscaler 认可的标注来保护移出费用较为昂贵的 pods,来防止发生这种情况。为此,请确保移出费用较为昂贵的 pods 具有标注 cluster-autoscaler.kubernetes.io/safe-to-evict=false
。
Karpenter
Amazon EKS 支持 Karpenter 开源弹性缩放项目。要部署该项目,请参阅 Karpenter
关于 Karpenter
Karpenter 是一款灵活的高性能 Kubernetes 集群自动缩放器,可帮助提高应用程序可用性和集群效率。Karpenter 只需不到一分钟时间,即可启动适当规模的计算资源(例如 Amazon EC2 实例)来响应不断变化的应用程序负载。通过将 Kubernetes 与 Amazon 相集成,Karpenter 可以即时调配精准满足工作负载需求的计算资源。Karpenter 会根据集群工作负载的具体需求来自动调配新的计算资源。这包括计算、存储、加速和调度需求。Amazon EKS 支持使用 Karpenter 的集群,但 Karpenter 可以与任何合规的 Kubernetes 集群配合使用。
Karpenter 的工作原理
Karpenter 通过在集群的整个生命周期内观察传入的 pods,与 Kubernetes 调度器协同工作。它通过启动或终止节点来最大限度提高应用程序可用性和集群利用率。当集群内有足够的容量时,Kubernetes 调度器会像往常一样部署传入的 pods。当启用无法使用集群现有容量调度的 pods 时,Karpenter 会绕过 Kubernetes 调度器,直接使用提供商的计算服务(例如 Amazon EC2)来启动满足这些 pods 所需的最少计算资源,并将 pods 绑定到所预置的节点。当 pods 被删除或重新调度到其他节点后,Karpenter 会寻找机会终止未充分利用的节点。在集群中运行数量更少、规模更大的节点可以减少 daemonsets 和 Kubernetes 系统组件的开销,并提供更多实现高效装填的机会。
先决条件
在部署 Karpenter 之前,您必须满足以下先决条件:
-
现有 Amazon EKS 集群:如果您没有集群,请参阅创建 Amazon EKS 集群。
-
集群的现有 IAM OIDC 提供商。要确定是否具有 IAM OIDC 提供商,还是需要创建一个,请参阅 为集群创建 IAM OIDC 提供商。
-
有权创建集群的 IAM 主体。
-
Amazon CLI
如果愿意,您可以使用 eksctl
部署 Karpenter。请参阅安装或更新 eksctl。