

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 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 的排程需求 （資源請求、節點選擇器、親和性、公差等）。
+ 佈建符合這些 Pod 需求的新節點。
+ 不再需要節點時將其移除。

透過 Karpenter，您可以定義具有節點佈建限制的 NodePools，例如污點、標籤、需求 （執行個體類型、區域等），以及佈建資源總數的限制。部署工作負載時，您可以在 Pod 規格中指定各種排程限制，例如資源請求/限制、節點選擇器、節點/Pod 親和性、容錯能力和拓撲分散限制。然後，Karpenter 將根據這些規格佈建適當大小的節點。

 **使用 Karpenter 的原因** 

在 Karpenter 推出之前，Kubernetes 使用者主要依賴 [Amazon EC2 Auto Scaling 群組](https://docs.aws.amazon.com/autoscaling/ec2/userguide/AutoScalingGroup.html)和 [Kubernetes Cluster Autoscaler](https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler) (CAS) 動態調整其叢集的運算容量。使用 Karpenter，您不需要建立數十個節點群組，即可透過 Karpenter 實現彈性和多樣性。與 CAS 不同，Karpenter 不會與 Kubernetes 版本緊密結合，也不需要您在 AWS 和 Kubernetes APIs 之間跳躍。

Karpenter 會將執行個體協同運作責任合併到單一系統中，這更簡單、更穩定且能感知叢集。Karpenter 旨在透過提供簡化方法來克服 Cluster Autoscaler 帶來的一些挑戰：
+ 根據工作負載需求佈建節點。
+ 使用靈活的 NodePool 選項，依執行個體類型建立多樣化的節點組態。Karpenter 可以讓您使用單一、靈活的 NodePool 管理各種工作負載容量，而不是管理許多特定的自訂節點群組。
+ 透過快速啟動節點和排程 Pod，大規模實現改善的 Pod 排程。

如需有關使用 Karpenter 的資訊和文件，請造訪 https：//[karpenter.sh](https://karpenter.sh/) 網站。

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

最佳實務分為 Karpenter 本身、NodePools 和 Pod 排程的區段。

## Karpenter 最佳實務
<a name="_karpenter_best_practices"></a>

下列最佳實務涵蓋與 Karpenter 本身相關的主題。

### 鎖定生產叢集中的 AMIs
<a name="_lock_down_amis_in_production_clusters"></a>

我們強烈建議您鎖定 Karpenter 用於生產叢集的已知 Amazon Machine Image (AMIs)。使用 `amiSelector`搭配設為 的別名`@latest`，或使用一些其他方法，導致在發行未測試AMIs 時部署， 會在您的生產叢集中提供工作負載失敗和停機的風險。因此，強烈建議您在非生產叢集中測試較新版本的生產叢集時，鎖定生產叢集的 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>

相較於 [Autoscaling Groups](https://aws.amazon.com/blogs/containers/amazon-eks-cluster-multi-zone-auto-scaling-groups/) (ASGs) 和 [Managed Node Groups](https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html) (MNGs)，Karpenter 讓擴展管理更接近 Kubernetes 原生 APIs。ASGs 和 MNGs 是 AWS 原生抽象，其中會根據 EC2 CPU 負載等 AWS 層級指標觸發擴展。[Cluster 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>

使用 [Helm Chart](https://karpenter.sh/docs/getting-started/getting-started-with-karpenter/#4-install-karpenter) 安裝 Karpenter。Helm Chart 會將 Karpenter 控制器和 Webhook Pod 安裝為需要執行的部署，才能使用控制器擴展叢集。我們建議至少有一個小型節點群組，其中至少有一個工作者節點。或者，您可以透過為`karpenter`命名空間建立 Fargate 設定檔，在 EKS Fargate 上執行這些 Pod。這樣做會導致部署到此命名空間的所有 Pod 在 EKS Fargate 上執行。請勿在由 Karpenter 管理的節點上執行 Karpenter。

### Karpenter 不支援自訂啟動範本
<a name="_no_custom_launch_templates_support_with_karpenter"></a>

v1 APIs 沒有自訂啟動範本支援。您可以使用自訂使用者資料和/或直接在 EC2NodeClass 中指定自訂 AMIs。如需如何執行此操作的詳細資訊，請參閱 [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)，可以處理非自願中斷事件，例如 Spot 執行個體中斷、排定的維護事件、執行個體終止/停止可能中斷工作負載的事件。當 Karpenter 偵測到節點的此類事件時，它會自動預先污點、耗盡和終止受影響的節點，以在中斷之前開始正常清理工作負載。對於 2 分鐘通知的 Spot 中斷，Karpenter 會快速啟動新的節點，以便在回收執行個體之前移動 Pod。若要啟用中斷處理，您可以使用為此目的佈建的 SQS 佇列名稱來設定 `--interruption-queue` CLI 引數。不建議搭配 Node Termination Handler 使用 Karpenter 中斷處理，如[此處](https://karpenter.sh/docs/faq/#interruption-handling)所述。

需要檢查點或其他形式正常耗盡的 Pod，在關機前需要 2 分鐘，應該會在其叢集中啟用 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 控制器使用服務帳戶的 IAM 角色 (IRSA)。使用 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"}
```

請參閱[本文件](https://karpenter.sh/docs/getting-started/getting-started-with-karpenter/#private-clusters)以在完全私有 EKS 叢集中使用 Karpenter，並了解要建立的 VPC 端點。

## 建立 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 會隨機選擇要使用的節點Pools，從而導致非預期的結果。建立多個 NodePools 的實用範例包括下列項目：

使用 GPU 建立 NodePool，並僅允許在這些 （昂貴） 節點上執行特殊工作負載：

```
# 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 會使用 [Price Capacity Optimized](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-fleet-allocation-strategy.html) 配置策略來佈建 EC2 執行個體。此策略會指示 EC2 從最深的集區佈建執行個體，以取得您啟動的執行個體數量，並具有最低的中斷風險。EC2 機群接著會從這些集區的最低價格請求 Spot 執行個體。您允許 Karpenter 利用的執行個體類型越多，EC2 就越能最佳化 Spot 執行個體的執行時間。根據預設，Karpenter 將使用叢集部署所在區域和可用區域中的所有執行個體類型 EC2 優惠。Karpenter 會根據待定 Pod 以智慧方式從所有執行個體類型中選擇，以確保您的 Pod 已排程在適當大小且配備的執行個體上。例如，如果您的 Pod 不需要 GPU，Karpenter 不會將您的 Pod 排程到支援 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 將保持待定狀態，直到已設定執行個體類型的 Spot 容量被補充為止。您可以將執行個體分散到不同的可用區域，以減少容量不足錯誤的風險，因為 Spot 集區在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，以防嘗試移出或刪除 Pod。

### 使用分層限制條件來限制雲端供應商提供的運算功能
<a name="_use_layered_constraints_to_constrain_the_compute_features_available_from_your_cloud_provider"></a>

Karpenter 的分層限制模型可讓您建立一組複雜的 NodePool 和 Pod 部署限制，以取得 Pod 排程的最佳可能相符項目。Pod 規格可以請求的限制範例包括下列項目：
+ 需要在只有特定應用程式可用的可用區域中執行。例如，假設您的 Pod 必須與位於特定可用區域的 EC2 執行個體上執行的另一個應用程式通訊。如果您的目標是減少 VPC 中的跨可用區流量，您可能想要在 EC2 執行個體所在的可用區中共同放置 Pod。這種類型的目標通常是使用節點選擇器來完成。如需[節點選擇器](https://karpenter.sh/docs/concepts/scheduling/#selecting-nodes)的詳細資訊，請參閱 Kubernetes 文件。
+ 需要特定類型的處理器或其他硬體。如需需要在 GPU 上執行 Pod 的 Pod 規格範例，請參閱 Karpenter 文件的[加速](https://karpenter.sh/docs/concepts/scheduling/#acceleratorsgpu-resources)器一節。

### 建立帳單警示以監控您的運算支出
<a name="_create_billing_alarms_to_monitor_your_compute_spend"></a>

當您將叢集設定為自動擴展時，您應該建立帳單警示，在支出超過閾值時提醒您，並將資源限制新增至 Karpenter 組態。使用 Karpenter 設定資源限制類似於設定 AWS Autoscaling 群組的最大容量，因為它代表 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 已過期，則該應用程式會在執行個體終止時中斷。透過將`karpenter.sh/do-not-disrupt`註釋新增至 Pod，您可以指示 Karpenter 保留節點，直到 Pod 終止或移除`karpenter.sh/do-not-disrupt`註釋為止。如需詳細資訊，請參閱[中斷](https://karpenter.sh/docs/concepts/disruption/#node-level-controls)文件。

如果節點上唯一留下的非協助程式集 Pod 是與任務相關聯的 Pod，只要任務狀態成功或失敗，Karpenter 就能夠鎖定和終止這些節點。

### 設定請求 = 使用整合時所有非 CPU 資源的限制
<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 的容器請求總數或 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 的整合功能，這尤其重要。

請參閱[設定和調整所有工作負載的資源請求/限制](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 Pod 時，考慮到 Karpenter 在快速終止/建立新節點以符合需求的動態本質，建議遵循下列最佳實務：

 [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 藍圖](https://github.com/aws-ia/terraform-aws-eks-blueprints-addons)是一種儲存庫，其中包含遵循此處所述最佳實務的常見工作負載案例清單。您甚至可以擁有建立已設定 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 與 Cluster Autoscaler](https://youtu.be/FIBc8GkjFU0) 
+  [於 re：Invent 2023 的 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) 