

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

# Karpenter
<a name="karpenter"></a>

**提示**  
 通过 Amazon EKS 研讨会@@ [探索](https://aws-experience.com/emea/smb/events/series/get-hands-on-with-amazon-eks?trk=4a9b4147-2490-4c63-bc9f-f8a84b122c8c&sc_channel=el)最佳实践。

 [Karpenter](https://karpenter.sh/) 是一个开源项目，旨在增强 Kubernetes 集群中的节点生命周期管理。它可以根据 Pod 的特定调度需求自动配置和取消配置节点，从而实现高效的扩展和成本优化。它的主要功能是：
+ 监控 Kubernetes 调度器由于资源限制而无法调度的容器。
+ 评估不可调度 Pod 的调度要求（资源请求、节点选择器、亲和力、容忍度等）。
+ 配置满足这些 Pod 要求的新节点。
+ 不再需要节点时将其移除。

使用 Karpenter，您可以定义 NodePools 对节点配置的限制，例如污点、标签、要求（实例类型、区域等），以及对总预配置资源的限制。部署工作负载时，您可以在 Pod 规格中指定各种调度限制，例如资源requests/limits, node selectors, node/pod亲和力、容忍度和拓扑分布限制。然后，Karpenter 将根据这些规格配置大小合适的节点。

 **使用 Karpenter 的理由** 

在 Karpenter 推出之前，Kubernetes 用户主要依靠 [Amazon EC2 Auto Scaling 组和 Kubernetes 集群自动扩缩](https://docs.aws.amazon.com/autoscaling/ec2/userguide/AutoScalingGroup.html)[器 (CAS) 来动态调整其集群](https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler)的计算容量。使用 Karpenter，您无需创建数十个节点组即可实现 Karpenter 所获得的灵活性和多样性。与 CAS 不同，Karpenter 与 Kubernetes 版本的耦合不那么紧密，也不需要你在 AWS 和 Kubernetes 之间切换。 APIs

Karpenter 将实例编排职责整合到一个系统中，该系统更简单、更稳定且支持集群。Karpenter 旨在通过提供简化的方法来克服集群自动扩缩器带来的一些挑战：
+ 根据工作负载要求配置节点。
+ 使用灵活的NodePool 选项，按实例类型创建不同的节点配置。Karpenter 可以让您通过单个灵活的方式管理不同的工作负载容量，而不是管理许多特定的自定义节点组。 NodePool
+ 通过快速启动节点和调度 Pod，实现大规模改进 Pod 调度。

有关使用 Karpenter 的信息和文档，请访问 [karpenter.sh](https://karpenter.sh/) 网站。

## 建议
<a name="_recommendations"></a>

最佳实践分为关于 Karpenter 本身和 pod 调 NodePools度的部分。

## Karpenter 最佳实践
<a name="_karpenter_best_practices"></a>

以下最佳实践涵盖了与 Karpenter 本身相关的主题。

### 锁定 AMIs 生产集群
<a name="_lock_down_amis_in_production_clusters"></a>

我们强烈建议您固定 Karpenter 用于生产集群的知名亚马逊系统映像 (AMIs)。将别名设置为`@latest`，或者使用其他方法导致在发布时部署未经测试 AMIs ，会给生产集群带来工作负载故障和停机的风险。`amiSelector`因此，我们强烈建议您在非生产集群中测试较新版本时， AMIs 为生产集群固定经过测试的工作版本。例如，您可以按 NodeClass 如下方式在中设置别名：

```
amiSelectorTerms
  - alias: al2023@v20240807
```

有关在 Karpenter AMIs 中管理和锁定的信息，请参阅 Karpenter [文档 AMIs中的管理](https://karpenter.sh/docs/tasks/managing-amis/)。

### 使用 Karpenter 处理容量需求不断变化的工作负载
<a name="_use_karpenter_for_workloads_with_changing_capacity_needs"></a>

与[自动扩缩组 () 和[托](https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html)管节点组 (MNGASGs) APIs 相比，Karpenter 使扩展](https://aws.amazon.com/blogs/containers/amazon-eks-cluster-multi-zone-auto-scaling-groups/)管理更接近 Kubernetes 原生。ASG 和 MNG 是 AWS 原生抽象，其中扩展是基于 AWS 级别的指标（例如 EC2 CPU 负载）触发的。Clu@@ [ster Autoscaler](https://docs.aws.amazon.com/eks/latest/userguide/autoscaling.html#cluster-autoscaler) 将 Kubernetes 抽象与 AWS 抽象联系起来，但因此失去了一些灵活性，例如为特定可用区调度。

Karpenter 删除了一层 AWS 抽象，将部分灵活性直接带入 Kubernetes。Karpenter 最适合工作负载处于高峰期、高峰期或计算要求不同的集群。 MNGs 并且 ASGs 适用于运行往往更具静态性和一致性的工作负载的集群。根据您的要求，您可以混合使用动态和静态管理的节点。

### 当... 时，可以考虑其他自动缩放项目
<a name="_consider_other_autoscaling_projects_when"></a>

你需要在 Karpenter 中仍在开发的功能。由于 Karpenter 是一个相对较新的项目，因此如果您需要尚未包含在 Karpenter 中的功能，请暂时考虑其他自动缩放项目。

### 在 EKS Fargate 或属于节点组的工作节点上运行 Karpenter 控制器
<a name="_run_the_karpenter_controller_on_eks_fargate_or_on_a_worker_node_that_belongs_to_a_node_group"></a>

Karpenter 是使用 [Helm](https://karpenter.sh/docs/getting-started/getting-started-with-karpenter/#4-install-karpenter) 图表安装的。Helm 图表将 Karpenter 控制器和 webhook pod 安装为部署，需要先运行该部署，然后才能使用控制器扩展集群。我们建议至少有一个包含至少一个工作节点的小型节点组。或者，你可以通过为命名空间创建 Fargate 配置文件在 EKS Fargate 上运行这些 pod。`karpenter`这样做会导致部署到这个命名空间中的所有 pod 都在 EKS Fargate 上运行。不要在由 Karpenter 管理的节点上运行 Karpenter。

### Karpenter 不支持自定义启动模板
<a name="_no_custom_launch_templates_support_with_karpenter"></a>

v1 APIs 不支持自定义启动模板。您可以使用自定义用户数据， and/or 直接 AMIs 在中指定自定义 EC2NodeClass。有关如何执行此操作的更多信息，请访问[NodeClasses](https://karpenter.sh/docs/concepts/nodeclasses/)。

### 排除不适合您的工作负载的实例类型
<a name="_exclude_instance_types_that_do_not_fit_your_workload"></a>

如果集群中运行的工作负载不需要特定实例类型，请考虑使用`node.kubernetes.io/instance-type`密钥排除这些实例类型。

以下示例显示了如何避免配置大型 Graviton 实例。

```
- key: node.kubernetes.io/instance-type
  operator: NotIn
  values:
  - m6g.16xlarge
  - m6gd.16xlarge
  - r6g.16xlarge
  - r6gd.16xlarge
  - c6g.16xlarge
```

### 使用 Spot 时启用中断处理
<a name="_enable_interruption_handling_when_using_spot"></a>

Karpenter 支持[原生中断处理](https://karpenter.sh/docs/concepts/disruption/#interruption)，可以处理非自愿中断事件，例如竞价型实例中断、计划维护事件、实例终止/停止事件，这些事件可能会中断您的工作负载。当 Karpenter 检测到节点的此类事件时，它会自动提前污染、清空和终止受影响的节点，以便在中断之前开始优雅地清理工作负载。如果 Spot 中断，提醒 2 分钟，Karpenter 会快速启动一个新节点，这样就可以在回收实例之前移动 Pod。要启用中断处理，请使用为此目的配置的 SQS 队列的名称来配置 `--interruption-queue` CLI 参数。[不建议将 Karpenter 中断处理与节点终止处理程序一起使用，如下所述。](https://karpenter.sh/docs/faq/#interruption-handling)

需要检查点或其他形式的优雅排水、需要在关闭前 2 分钟的 Pod 应在集群中启用 Karpenter 中断处理。

### **没有出站互联网访问权限的 Amazon EKS 私有集群**
<a name="_amazon_eks_private_cluster_without_outbound_internet_access"></a>

将 EKS 集群配置到没有互联网路由的 VPC 时，必须确保已根据 EKS 文档中显示的私有集群[要求](https://docs.aws.amazon.com/eks/latest/userguide/private-clusters.html#private-cluster-requirements)配置环境。此外，您需要确保已在您的 VPC 中创建了 STS VPC 区域终端节点。否则，您将看到与下面显示的错误相似的错误。

```
{"level":"FATAL","time":"2024-02-29T14:28:34.392Z","logger":"controller","message":"Checking EC2 API connectivity, WebIdentityErr: failed to retrieve credentials\ncaused by: RequestError: send request failed\ncaused by: Post \"https://sts.<region>.amazonaws.com/\": dial tcp 54.239.32.126:443: i/o timeout","commit":"596ea97"}
```

这些更改在私有集群中是必要的，因为 Karpenter Controller 使用服务账户 (IRSA) 的 IAM 角色。配置了 IRSA 的 Pod 通过调用 AWS Security Token Service (AWS STS) API 获取证书。如果没有出站互联网接入，则必须在 VPC ***中创建和使用 AWS STS VPC 终端节点***。

私有集群还要求您为 ***SSM 创建 VPC 终端节点***。当 Karpenter 尝试配置新节点时，它会查询启动模板配置和 SSM 参数。如果您的 VPC 中没有 SSM VPC 终端节点，则会导致以下错误：

```
{"level":"ERROR","time":"2024-02-29T14:28:12.889Z","logger":"controller","message":"Unable to hydrate the AWS launch template cache, RequestCanceled: request context canceled\ncaused by: context canceled","commit":"596ea97","tag-key":"karpenter.k8s.aws/cluster","tag-value":"eks-workshop"}
...
{"level":"ERROR","time":"2024-02-29T15:08:58.869Z","logger":"controller.nodeclass","message":"discovering amis from ssm, getting ssm parameter \"/aws/service/eks/optimized-ami/1.27/amazon-linux-2/recommended/image_id\", RequestError: send request failed\ncaused by: Post \"https://ssm.<region>.amazonaws.com/\": dial tcp 67.220.228.252:443: i/o timeout","commit":"596ea97","ec2nodeclass":"default","query":"/aws/service/eks/optimized-ami/1.27/amazon-linux-2/recommended/image_id"}
```

***[价目表查询 API](https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/using-pelong.html) 没有 VPC 终端节点***。因此，定价数据将随着时间的推移而过时。Karpenter通过在其二进制文件中包含按需定价数据来解决这个问题，但只有在Karpenter升级时才会更新这些数据。定价数据请求失败将导致出现以下错误消息：

```
{"level":"ERROR","time":"2024-02-29T15:08:58.522Z","logger":"controller.pricing","message":"retreiving on-demand pricing data, RequestError: send request failed\ncaused by: Post \"https://api.pricing.<region>.amazonaws.com/\": dial tcp 18.196.224.8:443: i/o timeout; RequestError: send request failed\ncaused by: Post \"https://api.pricing.<region>.amazonaws.com/\": dial tcp 18.185.143.117:443: i/o timeout","commit":"596ea97"}
```

要在完全私有的 EKS 集群中使用 Karpenter，并了解要创建哪些 VPC 终端节点，请参阅此[文档](https://karpenter.sh/docs/getting-started/getting-started-with-karpenter/#private-clusters)。

## 正在创建 NodePools
<a name="_creating_nodepools"></a>

以下最佳实践涵盖了与创建相关的主题 NodePools。

### 在... NodePools 时创建多个
<a name="_create_multiple_nodepools_when"></a>

当不同的团队共享一个集群并需要在不同的工作节点上运行其工作负载，或者对操作系统或实例类型有不同的要求时，可以创建多个集群 NodePools。例如，一个团队可能想使用 Bottlerocket，而另一个团队可能想要使用 Amazon Linux。同样，一个团队可能可以使用昂贵的 GPU 硬件，而另一个团队不需要这些硬件。使用多项 NodePools 可以确保每个团队都可以使用最合适的资产。

### 相互排 NodePools 斥或加权创作
<a name="_create_nodepools_that_are_mutually_exclusive_or_weighted"></a>

 NodePools 建议创建互斥或加权的，以提供一致的调度行为。如果它们不匹配并且 NodePools 有多个匹配，Karpenter 将随机选择使用哪个，从而导致意想不到的结果。创建多个有用的示例 NodePools 包括：

 NodePool 使用 GPU 创建并仅允许特殊工作负载在以下（昂贵的）节点上运行：

```
# NodePool for GPU Instances with Taints
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: gpu
spec:
  disruption:
    consolidateAfter: 1m
    consolidationPolicy: WhenEmptyOrUnderutilized
  template:
    metadata: {}
    spec:
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: default
      expireAfter: Never
      requirements:
      - key: node.kubernetes.io/instance-type
        operator: In
        values:
        - p3.8xlarge
        - p3.16xlarge
      - key: kubernetes.io/os
        operator: In
        values:
        - linux
      - key: kubernetes.io/arch
        operator: In
        values:
        - amd64
      - key: karpenter.sh/capacity-type
        operator: In
        values:
        - on-demand
      taints:
      - effect: NoSchedule
        key: nvidia.com/gpu
        value: "true"
```

在可容忍污点的情况下部署：

```
# Deployment of GPU Workload will have tolerations defined
apiVersion: apps/v1
kind: Deployment
metadata:
  name: inflate-gpu
spec:
    spec:
      tolerations:
      - key: "nvidia.com/gpu"
        operator: "Exists"
        effect: "NoSchedule"
```

对于其他团队的常规部署，该 NodePool 规范可能包括 NodeAffinity。然后可以用部署 nodeSelectorTerms 来匹配`billing-team`。

```
# NodePool for regular EC2 instances
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: generalcompute
spec:
  template:
    metadata:
      labels:
        billing-team: my-team
    spec:
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: default
      expireAfter: Never
      requirements:
      - key: node.kubernetes.io/instance-type
        operator: In
        values:
        - m5.large
        - m5.xlarge
        - m5.2xlarge
        - c5.large
        - c5.xlarge
        - c5a.large
        - c5a.xlarge
        - r5.large
        - r5.xlarge
      - key: kubernetes.io/os
        operator: In
        values:
        - linux
      - key: kubernetes.io/arch
        operator: In
        values:
        - amd64
      - key: karpenter.sh/capacity-type
        operator: In
        values:
        - on-demand
```

使用 NodeAffinity 进行部署：

```
# Deployment will have spec.affinity.nodeAffinity defined
kind: Deployment
metadata:
  name: workload-my-team
spec:
  replicas: 200
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                - key: "billing-team"
                  operator: "In"
                  values: ["my-team"]
```

### 使用计时器 (TTL) 自动从集群中删除节点
<a name="_use_timers_ttl_to_automatically_delete_nodes_from_the_cluster"></a>

您可以在已配置的节点上使用计时器来设置何时删除没有工作负载 Pod 或已达到过期时间的节点。节点过期可用作升级手段，这样节点就会停用并替换为更新的版本。有关使用`spec.template.spec`配置节点[到期](https://karpenter.sh/docs/concepts/disruption/)的信息，请参阅 Karpenter 文档中的过期时间。

### 避免过度限制 Karpenter 可以配置的实例类型，尤其是在使用 Spot 时
<a name="_avoid_overly_constraining_the_instance_types_that_karpenter_can_provision_especially_when_utilizing_spot"></a>

使用 Spot 时，Karpenter 使用[价格容量优化的](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-fleet-allocation-strategy.html)分配策略来配置 EC2 实例。此策略指示 EC2 根据您正在启动的实例数量从最深的池中配置实例，并且中断风险最低。然后，EC2 队列请求这些池中价格最低的竞价型实例。您允许 Karpenter 使用的实例类型越多，EC2 就越能更好地优化您的竞价型实例的运行时间。默认情况下，Karpenter 将使用 EC2 在您的集群部署所在的区域和可用区中提供的所有实例类型。Karpenter 会根据待处理的 pod 从所有实例类型中进行智能选择，以确保您的 Pod 被调度到大小适当、配备合适的实例上。例如，如果您的容器不需要 GPU，Karpenter 就不会将您的容器调度到支持 GPU 的 EC2 实例类型。当您不确定要使用哪些实例类型时，可以运行 Amazon [ec2-instance-selector](https://github.com/aws/amazon-ec2-instance-selector) 来生成符合您的计算要求的实例类型列表。例如，CLI 将内存 vCPU、架构和区域作为输入参数，并为您提供满足这些限制的 EC2 实例列表。

```
$ ec2-instance-selector --memory 4 --vcpus 2 --cpu-architecture x86_64 -r ap-southeast-1
c5.large
c5a.large
c5ad.large
c5d.large
c6i.large
t2.medium
t3.medium
t3a.medium
```

在使用 Spot 实例时，不应对 Karpenter 设置太多限制，因为这样做会影响应用程序的可用性。例如，假设特定类型的所有实例都被回收了，没有合适的替代方案可以替换它们。在配置的实例类型的竞价容量补充完毕之前，您的 Pod 将保持待处理状态。您可以通过将实例分散到不同的可用区来降低容量不足错误的风险，因为竞价池各不相同 AZs。也就是说，一般的最佳做法是允许 Karpenter 在使用 Spot 时使用不同的实例类型。

## 调度 Pod
<a name="_scheduling_pods"></a>

以下最佳实践与使用 Karpenter 进行节点配置的集群中部署 pod 有关。

### 遵循 EKS 最佳实践以实现高可用性
<a name="_follow_eks_best_practices_for_high_availability"></a>

如果您需要运行高可用性应用程序，请遵循一般的 EKS 最佳实践[建议](https://docs.aws.amazon.com/eks/latest/best-practices/application.html#_recommendations)。有关如何跨节点和区域分[布 Pod 的详细信息，请参阅 Karpenter 文档中的拓扑](https://karpenter.sh/docs/concepts/scheduling/#topology-spread)分布。使用[中断预算](https://karpenter.sh/docs/troubleshooting/#disruption-budgets)来设置需要维护的最低可用容量，以防有人试图驱逐或删除 Pod。

### 使用分层约束限制云提供商提供的计算功能
<a name="_use_layered_constraints_to_constrain_the_compute_features_available_from_your_cloud_provider"></a>

Karpenter 的分层约束模型允许您创建一组复杂的 pod 部署约束，以获得最匹配的 pod 调度。 NodePool Pod 规范可以请求的约束条件示例包括以下内容：
+ 需要在只有特定应用程序可用的可用区中运行。例如，假设您的 pod 必须与在位于特定可用区的 EC2 实例上运行的另一个应用程序通信。如果您的目标是减少 VPC 中的跨可用区流量，则可能需要将 Pod 托管在 EC2 实例所在的可用区中。这种定位通常使用节点选择器来完成。有关[节点选择器的](https://karpenter.sh/docs/concepts/scheduling/#selecting-nodes)更多信息，请参阅 Kubernetes 文档。
+ 需要某些类型的处理器或其他硬件。有关要求 pod 在 GPU 上运行的 pod 规格示例，请参阅 Karpenter 文档的[加速器](https://karpenter.sh/docs/concepts/scheduling/#acceleratorsgpu-resources)部分。

### 创建账单警报以监控您的计算支出
<a name="_create_billing_alarms_to_monitor_your_compute_spend"></a>

当您将集群配置为自动扩展时，您应该创建账单警报，以便在支出超过阈值时向您发出警告，并在 Karpenter 配置中添加资源限制。使用 Karpenter 设置资源限制与设置 AWS 自动扩展组的最大容量类似，因为它代表了 Karpenter 可以实例化的最大计算资源量。NodePool

**注意**  
无法为整个集群设置全局限制。限制适用于特定 NodePools。

下面的片段告诉 Karpenter 最多只能配置 1000 个 CPU 内核和 1000Gi 的内存。只有在达到或超过限制时，Karpenter 才会停止添加容量。当超过限制时，Karpenter 控制器将在控制器的日志中写入`memory resource usage of 1001 exceeds limit of 1000`或类似的消息。[如果您要将容器日志路由到 CloudWatch 日志，则可以创建[指标筛选器](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/MonitoringLogData.html)来查找日志中的特定模式或术语，然后创建警报，在您配置的指标阈值被突破时提醒您。CloudWatch](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html)

有关使用 Karpenter 限制的更多信息，请参阅 Karpenter [文档中的设置资源限制](https://karpenter.sh/docs/concepts/nodepools/#speclimits)。

```
spec:
  limits:
    cpu: 1000
    memory: 1000Gi
```

如果您不使用限制或限制 Karpenter 可以配置的实例类型，Karpenter 将继续根据需要向您的集群添加计算容量。虽然以这种方式配置 Karpenter 可以让您的集群自由扩展，但也可能带来显著的成本影响。正是出于这个原因，我们建议配置账单警报。账单警报允许您在账户中计算出的预估费用超过定义的阈值时收到提醒和主动通知。有关更多信息，请参阅[设置 Amazon CloudWatch 账单警报以主动监控预估费用](https://aws.amazon.com/blogs/mt/setting-up-an-amazon-cloudwatch-billing-alarm-to-proactively-monitor-estimated-charges/)。

您可能还需要启用成本异常检测，这是一项 AWS 成本管理功能，它使用机器学习来持续监控您的成本和使用情况，以检测异常支出。更多信息可在 [AWS 成本异常检测入门](https://docs.aws.amazon.com/cost-management/latest/userguide/getting-started-ad.html)指南中找到。如果您已经在 AWS Budgets 中创建预算，还可以配置一项操作，以便在突破特定阈值时通知您。通过预算操作，您可以发送电子邮件、向 SNS 主题发布消息或向 Slack 等聊天机器人发送消息。有关更多信息，请参阅[配置 AWS Budgets 操作](https://docs.aws.amazon.com/cost-management/latest/userguide/budgets-controls.html)。

### 使用 karpenter.sh/ do-not-disrupt 注解来防止 Karpenter 取消配置节点
<a name="_use_the_karpenter_shdo_not_disrupt_annotation_to_prevent_karpenter_from_deprovisioning_a_node"></a>

如果您在 Karpenter 配置的节点上运行关键应用程序，例如*长时间运行*的批处理作业或有状态的应用程序，*并且*该节点的 TTL 已过期，则该应用程序将在实例终止时中断。通过向 Pod 添加`karpenter.sh/do-not-disrupt`注解，您就是在指示 Karpenter 保留该节点，直到 Pod 终止或`karpenter.sh/do-not-disrupt`注释被移除。有关更多信息，请参[阅 Distruption](https://karpenter.sh/docs/concepts/disruption/#node-level-controls) 文档。

如果节点上唯一剩下的非守护程序集容器是那些与任务关联的 pod，那么只要任务状态为成功或失败，Karpenter 就可以瞄准和终止这些节点。

### 使用整合时，为所有非 CPU 资源配置 requests=limits
<a name="_configure_requestslimits_for_all_non_cpu_resources_when_using_consolidation"></a>

整合和调度通常是通过比较节点上的 pod 资源请求和可分配的资源量来进行的。不考虑资源限制。例如，内存限制大于内存请求的 Pod 可能会突增到请求之上。如果同一节点上的多个 Pod 同时爆裂，则可能导致某些 Pod 因内存不足 (OOM) 情况而终止。整合可以使这种情况更有可能发生，因为只有考虑节点的请求才能将 pod 打包到节点上。

### LimitRanges 用于配置资源请求和限制的默认值
<a name="_use_limitranges_to_configure_defaults_for_resource_requests_and_limits"></a>

由于 Kubernetes 不设置默认请求或限制，因此容器对底层主机、CPU 和内存的资源消耗不受限制。Kubernetes 调度器会查看 Pod 的总请求数（来自 Pod 容器的请求总数或容器的 Init 容器的总资源中较高者），以确定将 Pod 调度到哪个工作节点上。同样，Karpenter 会考虑 pod 的请求，以确定其提供的实例类型。你可以使用限制范围为命名空间应用合理的默认值，以防某些 pod 未指定资源请求。

请参见[为命名空间配置默认内存请求和限制](https://kubernetes.io/docs/tasks/administer-cluster/manage-resources/memory-default-namespace/) 

### 将准确的资源请求应用于所有工作负载
<a name="_apply_accurate_resource_requests_to_all_workloads"></a>

当有关您的工作负载要求的信息准确时，Karpenter 能够启动最适合您的工作负载的节点。如果使用 Karpenter 的合并功能，这一点尤其重要。

请参见[为所有工作负载配置和调整资源 Requests/Limits 大小](https://docs.aws.amazon.com/eks/latest/best-practices/data-plane.html#_recommendations) 

## CoreDNS 推荐
<a name="_coredns_recommendations"></a>

### 更新 CoreDNS 的配置以保持可靠性
<a name="_update_the_configuration_of_coredns_to_maintain_reliability"></a>

在由 Karpenter 管理的节点上部署 CoreDNS 容器时，鉴于 Karpenter 在 terminating/creating 快速新建节点中具有动态特性以适应需求，因此建议遵循以下最佳实践：

 [CoreDNS lameduck 时长](https://docs.aws.amazon.com/eks/latest/best-practices/scale-cluster-services.html#_coredns_lameduck_duration) 

 [CoreDNS 就绪情况调查](https://docs.aws.amazon.com/eks/latest/best-practices/scale-cluster-services.html#_coredns_readiness_probe) 

这将确保 DNS 查询不会被定向到尚未准备就绪或已终止的 CoreDNS Pod。

## Karpenter 蓝图
<a name="_karpenter_blueprints"></a>

由于 Karpenter 采用应用程序优先的方法为 Kubernetes 数据平面配置计算容量，因此您可能想知道如何正确配置常见的工作负载场景。[Karpenter Blueprin](https://github.com/aws-ia/terraform-aws-eks-blueprints-addons) ts 是一个存储库，其中包含遵循此处描述的最佳实践的常见工作负载场景列表。您将拥有所需的所有资源，甚至可以创建配置了 Karpenter 的 EKS 集群，并测试存储库中包含的每个蓝图。您可以组合不同的蓝图，最终创建工作负载所需的蓝图。

## 其他资源
<a name="_additional_resources"></a>
+  [Karpenter 沉浸式日工作坊](https://catalog.workshops.aws/karpenter/en-US) 
+  [Karpenter 成本优化研讨会](https://ec2spotworkshops.com/karpenter.html) 
+  [EKS 研讨会——Karpenter](https://www.eksworkshop.com/docs/autoscaling/compute/karpenter/) 
+  [Karpenter vs 集群自动扩缩器](https://youtu.be/FIBc8GkjFU0) 
+  [2023 年 re: Invent 上的 Karpenter 会议](https://youtu.be/lkg_9ETHeks) 
+  [教程：使用 Amazon EC2 Spot 和 Karpenter 以更低的价格运行 Kubernetes 集群](https://community.aws/tutorials/run-kubernetes-clusters-for-less-with-amazon-ec2-spot-and-karpenter#step-6-optional-simulate-spot-interruption) 