選取您的 Cookie 偏好設定

我們使用提供自身網站和服務所需的基本 Cookie 和類似工具。我們使用效能 Cookie 收集匿名統計資料,以便了解客戶如何使用我們的網站並進行改進。基本 Cookie 無法停用,但可以按一下「自訂」或「拒絕」以拒絕效能 Cookie。

如果您同意,AWS 與經核准的第三方也會使用 Cookie 提供實用的網站功能、記住您的偏好設定,並顯示相關內容,包括相關廣告。若要接受或拒絕所有非必要 Cookie,請按一下「接受」或「拒絕」。若要進行更詳細的選擇,請按一下「自訂」。

Karpenter

焦點模式
Karpenter - Amazon EKS

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

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

Karpenter 是一種開放原始碼專案,旨在增強 Kubernetes 叢集內的節點生命週期管理。它會根據 Pod 的特定排程需求,自動佈建和取消佈建節點,從而實現高效的擴展和成本最佳化。其主要函數為:

  • 監控 Kubernetes 排程器因為資源限制而無法排程的 Pod。

  • 評估不可排程 Pod 的排程需求 (資源請求、節點選擇器、親和性、容錯能力等)。

  • 佈建符合這些 Pod 要求的新節點。

  • 不再需要節點時,請將其移除。

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

使用 Karpenter 的原因

在 Karpenter 推出之前,Kubernetes 使用者主要依賴 Amazon EC2 Auto Scaling 群組Kubernetes Cluster Autoscaler (CAS) 動態調整其叢集的運算容量。使用 Karpenter,您不需要建立數十個節點群組,即可透過 Karpenter 實現彈性和多樣性。與 CAS 不同,Karpenter 不會與 Kubernetes 版本緊密結合,也不需要您在 AWS 和 Kubernetes APIs 之間跳躍。

Karpenter 將執行個體協同運作責任合併在單一系統中,這更簡單、更穩定且能感知叢集。Karpenter 旨在透過提供簡化的方式,克服 Cluster Autoscaler 帶來的一些挑戰:

  • 根據工作負載需求佈建節點。

  • 使用靈活的 NodePool 選項,依執行個體類型建立多樣化的節點組態。Karpenter 可以讓您使用單一、靈活的 NodePool 管理各種工作負載容量,而不是管理許多特定的自訂節點群組。

  • 透過快速啟動節點和排程 Pod,大規模實現改善的 Pod 排程。

如需有關使用 Karpenter 的資訊和文件,請造訪 https:// https:// karpenter.sh.healthnet.com。

建議

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

Karpenter 最佳實務

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

鎖定生產叢集中的 AMIs

強烈建議您鎖定 Karpenter 用於生產叢集的已知 Amazon Machine Image (AMIs)。使用 amiSelector搭配 別名設為 @latest,或使用一些其他方法,導致在發佈未測試AMIs 時部署, 會在您的生產叢集中提供工作負載失敗和停機的風險。因此,強烈建議您在非生產叢集中測試較新版本時,鎖定生產叢集的 AMIs 測試工作版本。例如,您可以在 NodeClass 中設定別名,如下所示:

amiSelectorTerms - alias: al2023@v20240807

如需在 Karpenter 中管理和鎖定 AMIs 的資訊,請參閱 Karpenter 文件中的管理 AMIs

針對容量需求不斷變化的工作負載使用 Karpenter

相較於 Autoscaling Groups (ASGs) 和受管節點群組 (MNGs),Karpenter 讓擴展管理更接近 Kubernetes 原生 APIs。ASGs 和 MNGs 是 AWS 原生抽象,其中會根據 AWS 層級指標觸發擴展,例如 EC2 CPU 負載。Cluster Autoscaler 會將 Kubernetes 抽象化為 AWS 抽象,但會因此失去一些彈性,例如為特定可用區域排程。

Karpenter 會移除 AWS 抽象層,將一些彈性直接帶入 Kubernetes。Karpenter 最適合用於工作負載遇到高峰值需求或有多樣化運算需求的叢集。MNGs 和 ASGs 適用於執行工作負載的叢集,這些工作負載往往更靜態且一致。您可以根據您的需求,混合使用動態和靜態受管節點。

考慮其他自動擴展專案,當...

您需要仍在 Karpenter 中開發的功能。由於 Karpenter 是相對較新的專案,如果您需要尚未屬於 Karpenter 的功能,請考慮目前其他的自動擴展專案。

在 EKS Fargate 或屬於節點群組的工作者節點上執行 Karpenter 控制器

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

Karpenter 不支援自訂啟動範本

v1 APIs 沒有自訂啟動範本支援。您可以使用自訂使用者資料和/或直接在 EC2NodeClass 中指定自訂 AMIs。如需如何執行此操作的詳細資訊,請參閱 NodeClasses

排除不符合工作負載的執行個體類型

如果叢集中執行的工作負載不需要特定執行個體類型,請考慮使用 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 時啟用中斷處理

Karpenter 支援原生中斷處理,並可以處理非自願中斷事件,例如 Spot 執行個體中斷、排定的維護事件、執行個體終止/停止可能中斷工作負載的事件。當 Karpenter 偵測到節點的此類事件時,會自動事先污點、耗盡和終止受影響的節點,以在中斷之前開始正常清理工作負載。對於 2 分鐘通知的 Spot 中斷,Karpenter 會快速啟動新的節點,以便在回收執行個體之前移動 Pod。若要啟用中斷處理,您可以使用為此目的佈建的 SQS 佇列名稱來設定 --interruption-queue CLI 引數。不建議搭配 Node Termination Handler 使用 Karpenter 中斷處理,如此處所述。

需要檢查點或其他形式正常耗盡的 Pod,在關機前需要 2 分鐘的 Pod,應該會在其叢集中啟用 Karpenter 中斷處理。

沒有傳出網際網路存取的 Amazon EKS 私有叢集

將 EKS 叢集佈建至沒有網際網路路由的 VPC 時,您必須確定已根據 EKS 文件中出現的私有叢集需求來設定環境。此外,您需要確定已在 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 Roles for Service Accounts (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 沒有 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 端點。

建立 NodePools

下列最佳實務涵蓋與建立 NodePools 相關的主題。

建立多個 NodePools 時...

當不同的團隊共用叢集,且需要在不同的工作者節點上執行工作負載,或具有不同的作業系統或執行個體類型需求時,請建立多個 NodePools 例如,一個團隊可能想要使用 Bottlerocket,而另一個團隊可能想要使用 Amazon Linux。同樣地,一個團隊可能可以存取另一個團隊不需要的昂貴 GPU 硬體。使用多個 NodePools 可確保每個團隊都能使用最適當的資產。

建立互斥或加權NodePools

建議建立互斥或加權的 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) 從叢集自動刪除節點

您可以在已佈建節點上使用計時器來設定何時刪除沒有工作負載 Pod 或已達到過期時間的節點。節點過期可用作升級方式,以便淘汰節點並以更新版本取代。如需使用 spec.template.spec 設定節點過期的資訊,請參閱 Karpenter 文件中的過期。

避免過度限制 Karpenter 可以佈建的執行個體類型,尤其是在使用 Spot 時

使用 Spot 時,Karpenter 會使用 Price Capacity Optimized 配置策略來佈建 EC2 執行個體。此策略會指示 EC2 從最深的集區佈建執行個體,以取得您啟動的執行個體數量,且中斷風險最低。EC2 機群接著會從這些集區的最低價格請求 Spot 執行個體。您允許 Karpenter 利用的執行個體類型越多,EC2 就越能最佳化 Spot 執行個體的執行時間。根據預設,Karpenter 將使用叢集部署所在區域和可用區域中的所有執行個體類型 EC2 優惠。Karpenter 會根據待定 Pod 以智慧方式從所有執行個體類型中選擇,以確保您的 Pod 已排程在適當大小且配備的執行個體上。例如,如果您的 Pod 不需要 GPU,Karpenter 不會將您的 Pod 排程到支援 GPU 的 EC2 執行個體類型。當您不確定要使用的執行個體類型時,可以執行 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

下列最佳實務與使用 Karpenter 在叢集中部署 Pod 進行節點佈建相關。

遵循 EKS 最佳實務以獲得高可用性

如果您需要執行高可用性應用程式,請遵循一般 EKS 最佳實務建議。如需如何跨節點和區域分散 Pod 的詳細資訊,請參閱 Karpenter 中的拓撲分散文件。使用中斷預算來設定需要維護的最小可用 Pod,以防嘗試移出或刪除 Pod。

使用分層限制條件來限制雲端供應商提供的運算功能

Karpenter 的分層限制模型可讓您建立一組複雜的 NodePool 和 Pod 部署限制,以取得 Pod 排程的最佳可能相符項目。Pod 規格可以請求的限制範例包括:

  • 需要在只有特定應用程式可用的可用區域中執行。例如,假設您有 Pod 必須與位於特定可用區域的 EC2 執行個體上執行的另一個應用程式通訊。如果您的目標是減少 VPC 中的跨可用區流量,您可能想要在 EC2 執行個體所在的可用區域中,共同放置 Pod。這種類型的目標通常是使用節點選擇器來完成。如需節點選取器的詳細資訊,請參閱 Kubernetes 文件。

  • 需要特定類型的處理器或其他硬體。如需需要在 GPU 上執行 Pod 的 Pod 規格範例,請參閱 Karpenter 文件的加速器一節。

建立帳單警示以監控您的運算支出

當您將叢集設定為自動擴展時,您應該建立帳單警示,在支出超過閾值時警告您,並將資源限制新增至 Karpenter 組態。使用 Karpenter 設定資源限制類似於設定 AWS Autoscaling 群組的最大容量,因為它代表 Karpenter NodePool 可執行個體化的運算資源數量上限。

注意

無法設定整個叢集的全域限制。限制適用於特定 NodePools。

以下程式碼片段會告知 Karpenter 最多只能佈建 1000 個 CPU 核心和 1000Gi 記憶體。只有在達到或超過限制時,Karpenter 才會停止新增容量。超過限制時,Karpenter 控制器會將 memory resource usage of 1001 exceeds limit of 1000或類似的注視訊息寫入控制器的日誌。如果您要將容器日誌路由到 CloudWatch 日誌,您可以建立指標篩選條件來尋找日誌中的特定模式或詞彙,然後建立 CloudWatch 警示,以便在您設定的指標閾值違反時提醒您。

如需使用限制搭配 Karpenter 的詳細資訊,請參閱 Karpenter 文件中的設定資源限制

spec: limits: cpu: 1000 memory: 1000Gi

如果您未使用限制或限制 Karpenter 可以佈建的執行個體類型,Karpenter 會視需要繼續將運算容量新增至您的叢集。雖然以這種方式設定 Karpenter 可讓您的叢集自由擴展,但它也可能具有重大的成本影響。因此,我們建議您設定帳單警示。帳單警示可讓您在帳戶中計算的預估費用超過定義的閾值時收到提醒並主動通知您 (這些費用)。如需詳細資訊,請參閱設定 Amazon CloudWatch 帳單警示以主動監控預估費用

您可能也想要啟用成本異常偵測,這是一種 AWS 成本管理功能,使用機器學習持續監控您的成本和用量,以偵測不尋常的支出。如需詳細資訊,請參閱 AWS 成本異常偵測入門指南。如果您已經在 AWS Budgets 中建立預算,您也可以設定 動作,以便在超過特定閾值時通知您。透過預算動作,您可以傳送電子郵件、將訊息發佈至 SNS 主題,或將訊息傳送至 Slack 之類的聊天機器人。如需詳細資訊,請參閱設定 AWS Budgets 動作

使用 karpenter.sh/do-not-disrupt 註釋來防止 Karpenter 取消佈建節點

如果您在 Karpenter 佈建的節點上執行關鍵應用程式,例如長時間執行的批次任務或具狀態應用程式,節點的 TTL 已過期,則執行個體終止時,應用程式將會中斷。透過將karpenter.sh/do-not-disrupt註釋新增至 Pod,您可以指示 Karpenter 保留節點,直到 Pod 終止或移除karpenter.sh/do-not-disrupt註釋為止。如需詳細資訊,請參閱中斷文件。

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

使用整合時,設定所有非 CPU 資源的 request=limits

透過比較 Pod 資源請求與節點上可配置資源的數量,進行一般性的合併和排程。不會考慮資源限制。例如,記憶體限制大於記憶體請求的 Pod 可能會爆量超過請求。如果同一節點上的多個 Pod 同時爆量,這可能會導致某些 Pod 因記憶體不足 (OOM) 條件而終止。合併可能會使這種情況更可能發生,因為它可以只考慮其請求,將 Pod 封裝到節點上。

使用 LimitRanges 設定資源請求和限制的預設值

由於 Kubernetes 不會設定預設請求或限制,因此容器對基礎主機、CPU 和記憶體資源的耗用不受限制。Kubernetes 排程器會查看 Pod 的請求總數 (Pod 容器的請求總數或 Pod Init 容器的資源總數較高),以決定要排程 Pod 的工作者節點。同樣地,Karpenter 會考慮 Pod 的請求,以判斷其佈建的執行個體類型。您可以使用限制範圍來套用命名空間的合理預設值,以防某些 Pod 未指定資源請求。

請參閱設定命名空間的預設記憶體請求和限制

將準確的資源請求套用至所有工作負載

當 Karpenter 的工作負載需求相關資訊準確無誤時,其能夠啟動最適合您工作負載的節點。如果使用 Karpenter 的合併功能,這尤其重要。

請參閱設定和調整所有工作負載的資源請求/限制

CoreDNS 建議

更新 CoreDNS 的組態以維護可靠性

在 Karpenter 管理的節點上部署 CoreDNS Pod 時,考慮到 Karpenter 在快速終止/建立新節點以符合需求的動態本質,建議遵循下列最佳實務:

CoreDNS lameduck 持續時間

CoreDNS 整備探測

這將確保 DNS 查詢不會導向尚未就緒或已終止的 CoreDNS Pod。

Karpenter 藍圖

由於 Karpenter 採取應用程式優先的方法,將 的運算容量佈建至 Kubernetes 資料平面,因此您可能想知道如何正確設定它們。Karpenter 藍圖是一種儲存庫,其中包含遵循此處所述最佳實務的常見工作負載案例清單。您甚至可以擁有建立已設定 Karpenter 的 EKS 叢集所需的所有資源,並測試儲存庫中包含的每個藍圖。您可以結合不同的藍圖 (最後) 來建立工作負載所需的藍圖。

其他資源

隱私權網站條款Cookie 偏好設定
© 2025, Amazon Web Services, Inc.或其附屬公司。保留所有權利。