

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

# 计算和自动缩放
<a name="cost-opt-compute"></a>

作为开发人员，您需要估算应用程序的资源需求，例如CPU和内存，但是如果您不不断调整它们，它们可能会过时，这可能会增加您的成本并降低性能和可靠性。持续调整应用程序的资源需求比第一次就正确调整它们更为重要。

下面提到的最佳实践将帮助您构建和运营成本感知型工作负载，从而实现业务成果，同时最大限度地降低成本，并使您的组织能够最大限度地提高投资回报。优化集群计算成本的高级重要性顺序是：

1. 适当调整工作负载规模

1. 减少未使用的容量

1. 优化计算容量类型（例如 Spot）和加速器（例如 GPUs）

## 正确调整工作负载规模
<a name="_right_size_your_workloads"></a>

在大多数 EKS 集群中，大部分成本来自用于运行容器化工作负载的 EC2 实例。如果不了解自己的工作负载需求，您将无法调整计算资源的大小。因此，您必须使用适当的请求和限制，并根据需要对这些设置进行调整。此外，实例大小和存储选择等依赖关系可能会影响工作负载性能，从而对成本和可靠性产生各种意想不到的后果。

 *请求*应与实际利用率保持一致。如果容器的请求过高，就会出现未使用的容量，这是集群总成本的一个重要因素。Pod 中的每个容器（例如应用程序和 sidecar）都应设置自己的请求和限制，以确保集合 pod 限制尽可能准确。

使用 [Goldilocks](https://www.youtube.com/watch?v=DfmQWYiwFDk)、[KRR 和 K](https://www.youtube.com/watch?v=uITOzpf82RY) [ubecost](https://aws.amazon.com/blogs/containers/aws-and-kubecost-collaborate-to-deliver-cost-monitoring-for-eks-customers/) 等工具来估算容器的资源请求和限制。根据应用程序的性质、 performance/cost 要求和复杂性，您需要评估哪些指标最适合扩展，应用程序性能在什么时候下降（饱和点），以及如何相应地调整请求和限制。有关此主题的进一步指导，请参阅[应用程序的正确尺寸](https://docs.aws.amazon.com/eks/latest/best-practices/node_and_workload_efficiency.html)。

我们建议使用水平容器自动扩缩器 (HPA) 来控制应运行应用程序的副本数量，使用垂直容器自动扩缩器 (VPA) 来调整应用程序每个副本所需的请求数量和限制，使用像 [Karpent](http://karpenter.sh/) er 或 Cluster Autoscaler 这样的节点自动扩缩器来持续调整[集群中的](https://github.com/kubernetes/autoscaler)节点总数。本文档的后面部分将记录使用 Karpenter 和 Cluster Autoscaler 的成本优化技术。

Vertical Pod Autoscaler 可以调整分配给容器的请求和限制，从而使工作负载以最佳方式运行。你应该在审计模式下运行 VPA，这样它就不会自动进行更改和重启你的 pod。它将根据观察到的指标提出更改建议。对于影响生产工作负载的任何更改，您都应先在非生产环境中查看和测试这些更改，因为这些更改可能会影响应用程序的可靠性和性能。

## 减少消费
<a name="_reduce_consumption"></a>

节省资金的最佳方法是配置更少的资源。实现这一目标的一种方法是根据工作负载的当前需求调整工作负载。在开始任何成本优化工作时，您都应确保您的工作负载定义其要求并动态扩展。这将需要从您的应用程序中获取指标并设置配置（例如[https://kubernetes.io/docs/tasks/run-application/configure-pdb/](https://kubernetes.io/docs/tasks/run-application/configure-pdb/)和 [Pod Readiness Gates](https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.5/deploy/pod_readiness_gate/)），以确保您的应用程序可以安全地动态地向上和向下扩展。重要的是要考虑到，限制 PodDisruptionBudgets 会阻止 Cluster Autoscaler 和 Karpenter 缩小节点规模，因为集群自动扩缩器和 Karpenter 都尊重。 PodDisruptionBudgets中的 “minAvailable” 值 PodDisruptionBudget 应始终低于部署中的容器数量，并且应在两者之间保持良好的缓冲区。例如，在 6 个 pod 的部署中，您希望始终至少运行 4 个 pod，请将您 PodDisruptionBidget 的 “minAvailable” 设置为 4。这将允许 Cluster Autoscaler 和 Karpenter 在节点缩减事件期间安全地从未充分利用的节点中排出 Pod 并将其驱逐出去。请参阅[集群自动扩缩器常见问题解答文档](https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/FAQ.md#what-types-of-pods-can-prevent-ca-from-removing-a-node)。

Horistant Pod Autoscaler 是一款灵活的工作负载自动扩缩器，可以调整需要多少副本来满足应用程序的性能和可靠性要求。它有一个灵活的模型，可以根据各种指标（例如 CPU、内存或自定义指标（例如队列深度、与 Pod 的连接数等）来定义何时向上和向下扩展。

[Kubernetes Metrics Server 支持根据内置指标（例如 CPU 和内存使用情况）进行扩展，但是如果您想根据其他指标（例如 Amazon CloudWatch 或 SQS 队列深度）进行扩展，则应考虑事件驱动的自动扩展项目，例如 KEDA。](https://keda.sh/)请参阅[此博客文章](https://aws.amazon.com/blogs/mt/proactive-autoscaling-of-kubernetes-workloads-with-keda-using-metrics-ingested-into-amazon-cloudwatch/)，了解如何将 KEDA 与 CloudWatch 指标配合使用。如果您不确定要根据哪些指标进行监控和扩展，请查看有关[重要监控指标的最佳实践](https://aws-observability.github.io/observability-best-practices/guides/#monitor-what-matters)。

减少工作负载消耗会在集群中造成容量过剩，通过适当的自动扩展配置，您可以自动缩减节点并减少总支出。我们建议您不要尝试手动优化计算容量。Kubernetes 调度器和节点自动扩缩器旨在为您处理此过程。

## 减少未使用的容量
<a name="_reduce_unused_capacity"></a>

在确定了应用程序的正确大小并减少了多余的请求之后，就可以开始减少预配置的计算容量了。如果您已经花时间根据上面的部分正确调整工作负载的大小，则应该能够动态地执行此操作。AWS 中有两个主节点自动扩缩器与 Kubernetes 配合使用。

### Karpenter 和 Cluster 自动扩缩器
<a name="_karpenter_and_cluster_autoscaler"></a>

随着 Pod 的创建或移除以及计算要求的变化，Karpenter 和 Kubernetes 集群自动扩缩器都会扩展集群中的节点数量。两者的主要目标是一样的，但是 Karpenter 在节点管理配置和取消配置方面采用了不同的方法，这有助于降低成本并优化集群范围的使用率。

随着集群规模的扩大和工作负载种类的增加，预配置节点组和实例变得越来越困难。就像处理工作负载请求一样，设定初始基准并根据需要不断调整非常重要。

如果您使用的是集群自动扩缩器，它将尊重每个 Auto Scaling 组 (ASG) 的 “最小” 和 “最大” 值，并且只调整 “所需值”。在为底层 ASG 设置这些值时务必注意，因为 Cluster Autoscaler 无法将超出 “最小” 数量的 ASG 缩小规模。将 “期望” 计数设置为正常工作时间所需的节点数，将 “最小” 设置为非工作时间所需的节点数。请参阅[集群自动扩缩器常见问题解答文档](https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md#auto-discovery-setup)。

### 集群自动扩缩器优先级扩展器
<a name="_cluster_autoscaler_priority_expander"></a>

Kubernetes Cluster Autoscaler 的工作原理是在应用程序向上和向下扩展时向上和向下扩展节点组（称为节点组）。如果您没有动态扩展工作负载，那么集群自动扩缩器将无法帮助您节省资金。Cluster Autoscaler 要求集群管理员提前创建节点组以供工作负载使用。节点组需要配置为使用具有相同 “配置文件” 的实例，即大致相同的 CPU 和内存量。

您可以有多个节点组，并且可以将 Cluster Autoscaler 配置为设置优先级扩展级别，并且每个节点组可以包含不同大小的节点。节点组可以有不同的容量类型，优先级扩展器可以先扩展成本较低的组。

以下是集群配置片段的示例，该片段在使用按需实例之前使用`ConfigMap``来确定预留容量的优先级。您可以使用相同的方法将 Graviton 或 Spot 实例优先于其他类型。

```
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
  name: my-cluster
managedNodeGroups:
  - name: managed-ondemand
    minSize: 1
    maxSize: 7
    instanceType: m5.xlarge
  - name: managed-reserved
    minSize: 2
    maxSize: 10
    instanceType: c5.2xlarge
```

```
apiVersion: v1
kind: ConfigMap
metadata:
  name: cluster-autoscaler-priority-expander
  namespace: kube-system
data:
  priorities: |-
    10:
      - .*ondemand.*
    50:
      - .*reserved.*
```

默认情况下，使用节点组可以帮助底层计算资源完成预期的事情，例如将节点分布在各处 AZs，但并非所有工作负载都有相同的要求或期望，最好让应用程序明确声明其需求。有关集群自动扩缩器的更多信息，请参阅[最佳实践部分](https://docs.aws.amazon.com/eks/latest/best-practices/cas.html)。

### Descheduler
<a name="_descheduler"></a>

Cluster Autoscaler 可以根据需要调度的新 Pod 或未充分利用的节点来增加和移除集群中的节点容量。在将 pod 调度到节点后，它不会全面了解 pod 的放置情况。如果您使用的是集群自动扩缩程序，则还应查看 [Kubernetes 解调器，以避免浪费集群中的容](https://github.com/kubernetes-sigs/descheduler)量。

如果您的集群中有 10 个节点，并且每个节点的利用率为 60%，则您使用的容量不会占集群中预置容量的 40%。使用 Cluster Autoscaler，您可以将每个节点的利用率阈值设置为 60%，但只有在利用率降至 60% 以下之后，才会尝试缩小单个节点。

使用解调器，它可以在调度 pod 或将节点添加到集群后查看集群容量和利用率。它会尝试将集群的总容量保持在指定的阈值以上。它还可以根据节点污点或加入集群的新节点移除 Pod，以确保 Pod 在其最佳计算环境中运行。请注意，descheduler 不会安排更换已驱逐的 pod，而是依赖默认的调度器来完成此操作。

### Karpenter 整合
<a name="_karpenter_consolidation"></a>

Karpenter 采用 “无组” 方法进行节点管理。这种方法对于不同的工作负载类型更加灵活，并且需要更少的集群管理员预先配置。Karpenter 没有预先定义组并根据工作负载的需要扩展每个组，而是使用配置器和节点模板来广泛定义可以创建的 EC2 实例类型以及创建实例时的设置。

Bin packing 是一种通过将更多工作负载打包到更少、大小最优的实例上来利用更多实例资源的做法。虽然这仅通过配置工作负载使用的资源来帮助降低计算成本，但它需要权衡取舍。启动新工作负载可能需要更长时间，因为必须向集群添加容量，尤其是在大规模扩展活动期间。设置垃圾箱包装时，请考虑成本优化、性能和可用性之间的平衡。

Karpenter 可以持续监控和装箱，以提高实例资源利用率并降低计算成本。Karpenter 还可以为您的工作负载选择更具成本效益的工作节点。这可以通过在配置器中将 “合并” 标志设置为 true 来实现（下面的示例代码片段）。以下示例显示了一个支持整合的置备程序示例。在撰写本指南时，Karpenter 不会将正在运行的竞价型实例替换为更便宜的竞价型实例。有关 Karpenter 整合的更多详细信息，请参阅[此](https://aws.amazon.com/blogs/containers/optimizing-your-kubernetes-compute-costs-with-karpenter-consolidation/)博客。

```
apiVersion: karpenter.sh/v1
kind: Provisioner
metadata:
  name: enable-binpacking
spec:
  consolidation:
    enabled: true
```

对于可能无法中断的工作负载，例如没有检查点的长时间运行的批处理作业，可以考虑使用注释为 pod 添加注释。`do-not-evict`通过选择 pod 退出驱逐，你是在告诉 Karpenter 它不应该自愿移除包含这个 pod 的节点。但是，如果在节点耗尽时将 `do-not-evict` Pod 添加到该节点，则其余的 pod 仍会被驱逐，但是该 Pod 在被移除之前会阻止终止。无论哪种情况，都将封锁该节点，以防止在该节点上安排其他工作。以下是显示如何设置注释的示例：

```
apiVersion: v1
kind: Pod
metadata:
  name: label-demo
  labels:
    environment: production
  annotations: +
    "karpenter.sh/do-not-evict": "true"
spec:
  containers:

* name: nginx
image: nginx
ports:
 ** containerPort: 80
```

### 通过调整集群自动扩缩程序参数来移除未充分利用的节点
<a name="_remove_under_utilized_nodes_by_adjusting_cluster_autoscaler_parameters"></a>

节点利用率定义为请求的资源总和除以容量。默认情况下`scale-down-utilization-threshold`，设置为 50%。此参数可以与和一起使用`scale-down-unneeded-time`，后者决定了节点在有资格缩减之前应该不需要多长时间，默认值为 10 分钟。Kube-scheduler 会将仍在缩减的节点上运行的 Pod 调度到其他节点上。调整这些设置可以帮助移除未充分利用的节点，但请务必先测试这些值，这样就不会强迫集群过早缩小规模。

您可以确保驱逐成本高昂的 Pod 受到集群自动扩缩器识别的标签的保护，从而防止缩小规模的发生。为此，请确保驱逐成本高昂的 pod 具有注释`cluster-autoscaler.kubernetes.io/safe-to-evict=false`。以下是设置注释的 yaml 示例：

```
apiVersion: v1
kind: Pod
metadata:
  name: label-demo
  labels:
    environment: production
  annotations: +
    "cluster-autoscaler.kubernetes.io/safe-to-evict": "false"
spec:
  containers:

* name: nginx
image: nginx
ports:
 ** containerPort: 80
```

### 使用集群自动扩缩器和 Karpenter 标记节点
<a name="_tag_nodes_with_cluster_autoscaler_and_karpenter"></a>

AWS 资源[标签](https://docs.aws.amazon.com/tag-editor/latest/userguide/tagging.html)用于组织您的资源，并详细跟踪您的 AWS 成本。它们不与 Kubernetes 标签直接关联以进行成本跟踪。建议从 Kubernetes 资源标签开始，然后使用 Kubecos [t 之类的工具根据容器、命名空间等上的 K](https://aws.amazon.com/blogs/containers/aws-and-kubecost-collaborate-to-deliver-cost-monitoring-for-eks-customers/) ubernetes 标签来获取基础设施成本报告。

工作节点需要有标签才能在 AWS Cost Explorer 中显示账单信息。使用 Cluster Autoscaler，使用[启动](https://docs.aws.amazon.com/eks/latest/userguide/launch-templates.html)模板在托管节点组中标记您的工作节点。对于自我管理的节点组，请使用 a [EC2 uto Scaling 组](https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto-scaling-tagging.html)标记您的实例。对于 Karpenter 配置的实例，请在节点模板中使用 [spec.tags对其进行标记。](https://karpenter.sh/docs/concepts/nodeclasses/#spectags)

### 多租户集群
<a name="_multi_tenant_clusters"></a>

在处理由不同团队共享的集群时，您可能无法看到在同一节点上运行的其他工作负载。虽然资源请求可以帮助隔离一些 “邻居噪音大” 的问题，例如 CPU 共享，但它们可能无法隔离所有资源边界，例如磁盘 I/O 耗尽。并非每个工作负载消耗的资源都可以被隔离或限制。应通过节点[污点和容忍](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/)度来隔离以比其他工作负载更高的速率消耗共享资源的工作负载。处理此类工作负载的另一种高级技术是 [CPU 固定](https://kubernetes.io/docs/tasks/administer-cluster/cpu-management-policies/#static-policy)，它可确保容器专用 CPU 而不是共享 CPU。

[在节点级别隔离工作负载可能会更昂贵，但可以通过使用[预留实例](https://aws.amazon.com/ec2/pricing/reserved-instances/)、[Graviton 处理器](https://aws.amazon.com/ec2/graviton/)或 Spot 来安排[BestEffort](https://kubernetes.io/docs/concepts/workloads/pods/pod-qos/#besteffort)任务或利用额外节省的费用。](https://aws.amazon.com/ec2/spot/)

共享集群还可能存在集群级别的资源限制，例如 IP 耗尽、Kubernetes 服务限制或 API 扩展请求。您应查看[可扩展性最佳实践指南](https://docs.aws.amazon.com/eks/latest/best-practices/scale-control-plane.html)，确保您的集群规避这些限制。

您可以在命名空间或 Karpenter 配置器级别隔离资源。[资源配额](https://kubernetes.io/docs/concepts/policy/resource-quotas/)提供了一种设置命名空间中工作负载可以消耗的资源数量限制的方法。这可能是一个不错的初始防护栏，但应不断对其进行评估，以确保它不会人为地限制工作负载的扩展。

Karpenter Provisioners 可以[对集群中的某些消耗资源（例如 CPU、GPU）设置限制](https://karpenter.sh/docs/concepts/nodepools/#speclimitsresources)，但您需要配置租户应用程序才能使用相应的配置器。这可以防止单个配置器在集群中创建太多节点，但应持续对其进行评估，以确保限制设置得不太低，从而防止工作负载扩展。

### 定时自动缩放
<a name="_scheduled_autoscaling"></a>

您可能需要在周末和非工作时间缩小集群。这对于测试和非生产集群尤其重要，在这些集群中，您希望在不使用时将其缩小到零。诸如[集群关闭之类](https://github.com/kubecost/cluster-turndown)的解决方案可以根据cron计划将副本缩小到零。[您也可以使用 Karpenter 实现这一目标，下面的 AWS 博客对此进行了概述。](https://aws.amazon.com/blogs/containers/manage-scale-to-zero-scenarios-with-karpenter-and-serverless/)

## 优化计算容量类型
<a name="_optimize_compute_capacity_types"></a>

在优化了集群中的总计算容量并利用垃圾箱打包后，您应该查看在集群中预配置了哪种类型的计算以及如何为这些资源付费。AWS 的[计算节省计划](https://aws.amazon.com/savingsplans/compute-pricing/)可以降低您的计算成本，我们会将其归类为以下容量类型：
+ Spot
+ 节省计划
+ 按需型
+ Fargate

每种容量类型在管理开销、可用性和长期承诺方面都有不同的权衡，您需要决定哪种容量类型适合您的环境。任何环境都不应依赖单一容量类型，您可以在单个集群中混合使用多种运行类型，以优化特定的工作负载要求和成本。

### Spot
<a name="_spot"></a>

[Spot](https://aws.amazon.com/ec2/spot/) 容量类型利用可用区的备用容量配置 EC2 实例。Spot 提供的折扣最大，最高可达 90%，但是当其他地方需要这些实例时，这些实例可能会被中断。此外，可能并不总是有容量来配置新的竞价型实例，并且只要[发出中断通知 2 分钟](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-interruptions.html)，就可以回收现有的竞价型实例。如果您的应用程序启动或关闭过程很长，则竞价型实例可能不是最佳选择。

竞价计算应使用各种各样的实例类型，以降低竞价容量不可用的可能性。需要处理实例中断才能安全关闭节点。使用 Karpenter 或托管节点组的一部分配置的节点会自动支持[实例](https://docs.aws.amazon.com/eks/latest/best-practices/karpenter.html)中断通知。如果您使用的是自管理节点，则需要单独运行[节点终止处理程序](https://github.com/aws/aws-node-termination-handler)以优雅地关闭竞价型实例。

可以在单个集群中平衡竞价实例和按需实例。借助 Karpenter，您可以创建[加权配置器](https://karpenter.sh/docs/concepts/scheduling/#on-demandspot-ratio-split)以实现不同容量类型的平衡。借助 Cluster Autoscaler，您可以创建[包含竞价型实例和按需实例或预留实例的混合节点组](https://aws.amazon.com/blogs/containers/amazon-eks-now-supports-provisioning-and-managing-ec2-spot-instances-in-managed-node-groups/)。

以下是使用 Karpenter 将竞价型实例优先于按需实例的优先级的示例。创建置备程序时，您可以指定竞价型、按需型或两者兼而有之（如下所示）。[当您同时指定两者时，如果 pod 没有明确指定需要使用 Spot 还是按需，则在使用分配策略配置节点时，Karpenter 会优先考虑 Spot。price-capacity-optimization ](https://aws.amazon.com/blogs/compute/introducing-price-capacity-optimized-allocation-strategy-for-ec2-spot-instances/)

```
apiVersion: karpenter.sh/v1
kind: Provisioner
metadata:
  name: spot-prioritized
spec:
  requirements:
    - key: "karpenter.sh/capacity-type"
      operator: In
        values: ["spot", "on-demand"]
```

### Savings Plans、预留实例和 AWS EDP
<a name="_savings_plans_reserved_instances_and_aws_edp"></a>

您可以使用计算[节省计划来减少计算](https://aws.amazon.com/savingsplans/compute-pricing/)支出。节省计划为 1 年或 3 年的计算使用承诺提供更低的价格。该用法可以适用于 EKS 集群中的 EC2 实例，但也适用于任何计算用量，例如 Lambda 和 Fargate。通过节省计划，您可以降低成本，并且仍然可以在承诺期内选择任何 EC2 实例类型。

计算节省计划可以将 EC2 成本降低多达 66%，而无需承诺要使用的实例类型、系列或区域。在您使用实例时，节省的费用会自动应用于实例。

EC2 Instance Savings Plans 承诺使用特定地区和 EC2 系列（例如 C 系列的实例），可节省高达 72% 的计算费用。您可以将使用量转移到该区域内的任何可用区，使用任何一代的实例系列，例如 c5 或 c6，并使用该系列中任意大小的实例。折扣将自动应用于您账户中符合储蓄计划标准的任何实例。

 [预留实例](https://aws.amazon.com/ec2/pricing/reserved-instances/)与 Instance EC2 Savings Plan 类似，但与按需实例相比，它们还可以保证可用区或区域的容量，并可降低高达 72% 的成本。计算出需要多少预留容量后，您可以选择要保留多长时间（1 年或 3 年）。当您在账户中运行这些 EC2 实例时，折扣将自动生效。

客户还可以选择与 AWS 签订企业协议。企业协议让客户可以选择定制最适合其需求的协议。客户可以享受基于 AWS EDP（企业折扣计划）的定价折扣。有关企业协议的更多信息，请联系您的 AWS 销售代表。

### 按需型
<a name="_on_demand"></a>

与现货相比，按需 EC2 实例具有无中断可用性的优势，而且与储蓄计划相比，无需长期承诺。如果您想降低集群成本，则应减少按需 EC2 实例的使用量。

优化工作负载要求后，您应该能够计算出集群的最小和最大容量。这个数字可能会随着时间的推移而变化，但很少会下降。考虑对低于最低限额的所有内容使用 Savings Plan，并选择不会影响应用程序可用性的容量。任何其他可能无法持续使用或可用性所必需的东西都可以按需使用。

如本节所述，减少使用量的最佳方法是消耗更少的资源，并最大限度地利用您配置的资源。使用集群自动扩缩器，您可以使用该设置删除未充分利用的节点。`scale-down-utilization-threshold`使用 Karpenter 时，建议启用整合。

要手动识别可用于您的工作负载的 EC2 实例类型，您应该使用 [ec2-instance-selec](https://github.com/aws/amazon-ec2-instance-selector) tor，它可以显示每个区域中可用的实例以及与 EKS 兼容的实例。具有 x86 进程架构、4 Gb 内存、2 v CPUs 且在 us-east-1 区域可用的实例的用法示例。

```
ec2-instance-selector --memory 4 --vcpus 2 --cpu-architecture x86_64 \
  -r us-east-1 --service eks
c5.large
c5a.large
c5ad.large
c5d.large
c6a.large
c6i.large
t2.medium
t3.medium
t3a.medium
```

对于非生产环境，您可以在夜间和周末等未使用的时间自动缩小集群。kubecost 项目[集群关闭就是](https://github.com/kubecost/cluster-turndown)控制器的一个示例，它可以根据设定的时间表自动缩小集群。

### Fargate 计算
<a name="_fargate_compute"></a>

Fargate 计算是 EKS 集群的完全托管计算选项。它通过在 Kubernetes 集群中为每个节点调度一个容器来提供容器隔离。它允许您根据工作负载的 CPU 和 RAM 要求调整计算节点的大小，从而严格控制集群中的工作负载使用情况。

Fargate 可以将工作负载扩展到 0.25 vCPU，内存为 0.5 GB，内存为 120 GB，内存可扩展至 16 个 vCPU。[容器大小可用的变体](https://docs.aws.amazon.com/eks/latest/userguide/fargate-pod-configuration.html)数量有限制，您需要了解您的工作负载如何最适合 Fargate 配置。例如，如果您的工作负载需要 1 个 vCPU 和 0.5 GB 内存，那么最小的 Fargate 容器将是 1 个 vCPU 和 2 GB 内存。

尽管 Fargate 有许多好处，例如无需 EC2 实例或操作系统管理，但由于每个部署的 Pod 都作为集群中的单独节点隔离，因此它可能需要比传统 EC2 实例更多的计算容量。这需要对诸如 Kubelet、日志代理以及通常 DaemonSets 要部署到节点的任何东西进行更多的复制。 DaemonSets 在 Fargate 中不支持它们，需要将其转换为 pod “`sidecars” 并与应用程序一起运行。

Fargate 无法从 bin 打包或 CPU 过度配置中受益，因为工作负载的边界是一个不可突发的节点，也不能在工作负载之间共享。Fargate 将为您节省 EC2 实例管理时间，而这本身就是有成本的，但是 CPU 和内存成本可能比其他 EC2 容量类型更昂贵。Fargate pod 可以利用计算节省计划来降低按需成本。

## 优化计算使用率
<a name="_optimize_compute_usage"></a>

在计算基础设施上节省资金的另一种方法是为工作负载使用更高效的计算。这可能来自性能更高的通用计算，例如 [Graviton处理器](https://aws.amazon.com/ec2/graviton/)，它比x86便宜20％，能效高60％，或者工作负载特定的加速器，例如和。 GPUs [FPGAs](https://aws.amazon.com/ec2/instance-types/f1/)你需要构建可以[在 arm 架构上运行](https://aws.amazon.com/blogs/containers/how-to-build-your-containers-for-arm-and-save-with-graviton-and-spot-instances-on-amazon-ecs/)的容器，并为你的工作负载[设置带有正确加速器的节点](https://aws.amazon.com/blogs/compute/running-gpu-accelerated-kubernetes-workloads-on-p3-and-p2-ec2-instances-with-amazon-eks/)。

EKS 能够运行混合架构的集群（例如 amd64 和 arm64），如果您的容器是针对多个架构编译的，则可以通过在配置器中允许这两种架构来利用带有 Karpenter 的 Graviton 处理器。但是，为了保持稳定的性能，建议您将每个工作负载保持在单个计算架构上，并且仅在没有额外容量可用时才使用不同的架构。

Provisioner 可以配置多个架构，工作负载也可以在其工作负载规格中请求特定的架构。

```
apiVersion: karpenter.sh/v1
kind: Provisioner
metadata:
  name: default
spec:
  requirements:
  - key: "kubernetes.io/arch"
    operator: In
    values: ["arm64", "amd64"]
```

使用 Cluster Autoscaler，你需要为 Graviton 实例创建一个节点组，并[对工作负载设置节点容忍度才能利用新的容量](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/)。

GPUs 并 FPGAs 可以大大提高工作负载的性能，但是需要优化工作负载才能使用加速器。机器学习和人工智能的许多工作负载类型 GPUs 可用于计算，并且可以使用资源请求将实例添加到集群并安装到工作负载中。

```
spec:
  template:
    spec:
    - containers:
      ...
      resources:
          limits:
            nvidia.com/gpu: "1"
```

某些 GPU 硬件可以在多个工作负载之间共享，因此可以配置和使用单个 GPU。要了解如何配置工作负载 GPU 共享，请参阅[虚拟 GPU 设备插件](https://aws.amazon.com/blogs/opensource/virtual-gpu-device-plugin-for-inference-workload-in-kubernetes/)了解更多信息。您也可以参考以下博客：
+  [使用 NVIDIA 时间切片和加速实例在 Amazon EKS 上共享 GPU EC2 ](https://aws.amazon.com/blogs/containers/gpu-sharing-on-amazon-eks-with-nvidia-time-slicing-and-accelerated-ec2-instances/) 
+  [在 Amazon EKS 上使用 NVIDIA 的多实例 GPU（MIG），最大限度地提高 GPU 利用率：让每个 GPU 运行更多容器组（pod）以增强性能](https://aws.amazon.com/blogs/containers/maximizing-gpu-utilization-with-nvidias-multi-instance-gpu-mig-on-amazon-eks-running-more-pods-per-gpu-for-enhanced-performance/) 