如何在 Amazon EKS 中使用 Karpenter 自動擴縮來對叢集擴充進行疑難排解?
我想要使用 Amazon Elastic Kubernetes Service (Amazon EKS) 中的 Karpenter 自動擴縮器對叢集擴充進行疑難排解。
解決方法
根據您收到的錯誤訊息進行疑難排解。
無法排程 Karpenter Pod,因為 Amazon EKS 節點群組執行個體不足
**注意:**如果您在執行 AWS Command Line Interface (AWS CLI) 命令時收到錯誤訊息,請參閱對 AWS CLI 錯誤進行疑難排解。此外,請確定您使用的是最新的 AWS CLI 版本。
在 Karpenter 版本 0.16.0 及更新版本中,預設複本數已從 1 改為 2。如需更多資訊,請參閱 GitHub 網站上的 v0.16.0 。如果叢集中的節點容量不足以支援設定的複本數,則無法排程 Karpenter Pod。因為 Karpenter 無法佈建節點來執行其自身的 Pod,所以會因容量不足而失敗,導致 Pod 無法排程。然後您會收到以下錯誤訊息:
「Warning FailedScheduling 3m default-scheduler 0/1 nodes are available: 1 Insufficient memory.」
若要解決此錯誤,請執行下列其中一個動作:
將 Karpenter 部署複本數減少到 1
如果您的 Karpenter 部署不需要備援,請將其更改為使用單一複本。執行以下命令:
kubectl scale deployment karpenter --replicas=1
增加 Karpenter Pod 的節點容量
若要執行兩個 Karpenter 複本,請確保有足夠容量支援兩個複本。選擇下列其中一個選項:
橫向擴充 Auto Scaling 群組
- 增加 Auto Scaling 群組中的最小執行個體數量。執行以下命令:
**注意:**將 your-node-group-name 替換為您的 Auto Scaling 群組名稱。aws autoscaling update-auto-scaling-group --auto-scaling-group-name your-node-group-name --min-size 2 --desired-capacity 2 - 確保有 Karpenter 未管理的節點。檢查節點標籤是否有 Karpenter 標籤,例如 karpenter.sh/nodepool。執行以下命令:
kubectl get nodes --show-labels | grep karpenter.sh/nodepool
使用現有節點
如果目標現有節點或節點具有 Karpenter 標籤 (例如 karpenter.sh/nodepool),請移除這些標籤。執行以下命令:
kubectl label nodes your-node-name karpenter.sh/nodepool-
**注意:**將 your-node-name 替換為您的節點名稱。
磁碟區附加與掛載失敗
當多個具有 Persistent Volume Claims (PVC) 的 Pod 排程到同一節點時,該節點可能會超過其磁碟區附加限制。然後,您可能會收到以下其中一個錯誤訊息:
「Warning FailedAttachVolume pod/example-pod AttachVolume.Attach failed for volume " " : rpc error: code = Internal desc = Could not attach volume " " to node " ": attachment of disk " " failed, expected device to be attached but was attaching」
「Warning FailedMount pod/example-pod Unable to attach or mount volumes: unmounted volumes=[], unattached volumes=[]: timed out waiting for the condition」
若要解決 PVC 密集型工作負載的磁碟區附加與掛載失敗,請完成以下步驟:
- 套用 topologySpreadConstraints 和 podAntiAffinity,以防止 PVC 密集型 Pod 排程到同一節點。如需更多資訊,請參閱 Kubernetes 網站上的 topologySpreadConstraints field 及 Pod affinity example。此操作可將 PVC 密集型 Pod 分散到不同節點,以避免磁碟區附加集中在單一節點。
- 使用 CSI 驅動程式,例如 Amazon Elastic Block Store (Amazon EBS) Container Storage Interface (CSI) 驅動程式 (aws-ebs-csi-driver),並為您的 NodePool 新增啟動污點。這些操作可確保 Pod 在節點完全準備好之前,不會過早排程到節點上。
Amazon EBS 中啟動污點組態範例:--yaml-- apiVersion: karpenter.sh/v1 kind: NodePool spec: template: spec: startupTaints: - key: ebs.csi.aws.com/agent-not-ready effect: NoExecute
已棄用的儲存外掛程式錯誤
Karpenter 不支援已棄用的 in-tree 儲存外掛程式,例如 Amazon EBS。如果您使用靜態佈建的 Persistent Volume (PV) 並搭配 in-tree 外掛程式,Karpenter 將無法發現節點的磁碟區附加限制。此情況可能導致排程失敗,您可能會收到以下錯誤訊息:
「ERROR controller.node_state PersistentVolume source 'AWSElasticBlockStore' uses an in-tree storage plugin which is unsupported by Karpenter and is deprecated by Kubernetes.」
若要解決此問題,請使用 Amazon EBS 的 CSI 驅動程式,並更新 PV 組態以使用 CSI 驅動程式。
因未指定資源請求而導致的排程或裝箱失敗
Karpenter 會根據資源請求進行 Pod 裝箱。如果請求過低或缺失,Karpenter 可能會將過多 Pod 分配到同一節點。此情況可能導致資源爭用與 CPU 限流。此外,如果設定了記憶體限制,而 Pod 嘗試使用超過限制的記憶體,則可能會發生記憶體不足 (OOM) 終止。您可能會收到以下錯誤訊息:
「Warning OOMKilled pod/your-pod-name Container "container-name" was killed due to OOM (Out of Memory).Memory limit: 512Mi, Memory usage: 513Mi」
若要避免這些問題,請使用 LimitRange 組態來設定最小資源需求,以確保精確的裝箱。LimitRange 組態可協助建立最大限制,以防止過度消耗。它們也會為未指定的 Pod 提供預設限制。如需更多資訊,請參閱使用 LimitRanges 來設定資源需求與限制的預設值。
Windows Pod 無法啟動且出現映像檔提取錯誤
若 Pod 的容器作業系統 (OS) 版本與 Windows OS 版本不符,Pod 將無法啟動。您會收到類似下列內容的錯誤訊息:
「Failed to pull image "mcr.microsoft.com/windows/servercore:xxx": rpc error: code = NotFound desc = failed to pull and unpack image "mcr.microsoft.com/windows/servercore:xxx": no match for platform in manifest: not found」
若要解決此問題,請定義 Pod 的 nodeSelector,以確保容器排程至相容的 OS 主機版本。如需更多資訊,請參閱 Microsoft 網站上的 Windows 容器版本相容性。
節點未正確初始化
系統會根據節點的準備度、預期資源註冊,以及 NodePool 啟動污點移除來判定節點是否初始化。如果未達成這些條件中的任何一個,Karpenter 節點將無法正確初始化,節點將保持在 NotReady 狀態。因此,系統無法使用該節點來排程或整合工作負載。您可能會收到以下錯誤訊息:
「Nodes provisioned by Karpenter are in a NotReady state」
請確認節點狀態為 Ready。如果不是,請檢查 Kubelet 日誌,以識別可能的權限、安全群組或網路問題。
確認所有必要資源,例如 nvidia.com/g.pu 或 vpc.amazonaws.com/pod-eni,是否已在節點上正確註冊。
若要檢查節點上的 nvidia.com/gpu 資源,請執行以下命令:
kubectl describe node your-node-name
**注意:**將 your-node-name 替換為您的節點名稱。
輸出範例:
... Capacity: nvidia.com/gpu.shared: 80 ...
如果這些資源缺失,請確認相關的 daemonset 或外掛程式是否正在執行。若要檢查 daemonset,請執行以下命令:
kubectl get ds -n your-daemonset-namespace
**注意:**將 your-daemonset-namespace 替換為您的 daemonset 命名空間。
因各種限制與約束而排程失敗
由於親和性、反親和性或拓撲分散限制,Pod 無法排程
若親和性、反親和性或拓撲分散限制要求特定節點或區域,但在所需位置不存在適合的節點,Pod 將無法排程。如果系統因節點或區域需求未達成而無法放置 Pod,您可能會收到以下錯誤訊息:
「Warning FailedScheduling pod/"pod-name" 0/3 nodes are available: 1 node(s) didn't match pod affinity rules, 2 node(s) didn't match pod topology spread constraints rules, 3 nodes(s) didn't match inter-pod anti-affinity rules.」
若要解決此錯誤,請檢查並調整 Pod 的親和性與反親和性設定或拓撲分散限制,使其與可用節點相符。您可以放寬這些限制,或在所需區域佈建更多節點。
由於資源不足,Pod 排程失敗
Pod 因資源需求超過可用節點容量而保持未排程。如果沒有任何節點具有足夠的 CPU、記憶體或其他資源來接收 Pod,您可能會收到以下錯誤訊息:
「Warning FailedScheduling 30s (x13 over 60m) default-scheduler 0/5 nodes are available: 1 Insufficient memory. preemption: 0/5 nodes are available: 5 No preemption victims found for incoming pod.」
若要解決此問題,請確保 Pod 規格中的資源需求反映實際使用量。如有必要,請調整資源需求與限制,或佈建容量更大的節點以滿足資源需求。
污點阻止 Pod 排程
當叢集管理員對特定節點套用自訂污點時,Pod 必須具有相符的容忍度。若沒有相符的容忍度,系統將無法在這些節點上排程 Pod。您會收到以下錯誤訊息:
「0/5 nodes are available: 3 node(s) had taint {dedicated: gpu}, that the pod didn't tolerate, 2 node(s) had taint {dedicated: non-gpu}, that the pod didn't tolerate.」
若要解決此錯誤,請在 Pod 規格中新增適當的容忍度,以允許 Pod 容忍該污點。或者,如果節點上的自訂污點過於嚴格,您也可以移除或修改不必要的污點。
若要從節點移除污點,請執行以下命令:
kubectl taint nodes your-node-name your-custom-taint-
**注意:**將 your-node-name 替換為您的節點名稱,將 your-custom-taint 替換為您自訂污點的名稱。
NodeAffinity 或 NodeSelector 限制未滿足
若存在與叢集內任何可用節點不相符的節點親和性或節點選擇器限制,則排程器無法放置 Pod。您會收到以下錯誤訊息:
「Warning FailedScheduling 3m default-scheduler 0/4 nodes are available: 1 node(s) didn't match Pod's node affinity/selector, 3 node(s) didn't satisfy existing pods anti-affinity rules, 4 node(s) didn't match Pod's node affinity rules.」
若要解決此錯誤,請修改 Pod 的節點親和性或節點選擇器要求,使其更具彈性。或者,如有必要,您也可以佈建符合 Pod 條件的額外節點。如需更多資訊,請參閱 Kubernetes 網站上的 Node affinity 與 nodeSelector。
子網路中 IP 位址不足
當 Karpenter 嘗試佈建新節點時,如果子網路中的 IP 位址不足,將會失敗。當子網路的無類別域間路由 (CIDR) 範圍已耗盡,無法容納新的 Amazon Elastic Compute Cloud (Amazon EC2) 執行個體,就會發生這種情況。您會收到以下錯誤訊息:
「error": "creating machine, creating instance, with fleet error(s), InsufficientFreeAddressesInSubnet: There are not enough free addresses in subnet 'subnet-a to satisfy the requested number of instances.」
若要解決此錯誤,可採取以下任一措施:
若子網路的 IP 位址已耗盡,請新增額外的 IPv4 CIDR 區塊,作為 Amazon Virtual Private Cloud (Amazon VPC) 的次要 CIDR。
-或-
使用自訂網路為您的 Pod 與節點指派獨立的 IP 位址空間。若要啟用自訂網路,請執行以下命令:
kubectl set env daemonset aws-node -n kube-system AWS_VPC_K8S_CNI_CUSTOM_NETWORK_CFG=true
如需更多自訂網路資訊,請參閱如何為 Amazon EKS 叢集中的 Pod 選擇特定的 IP 位址子網路?
因需求不相容,Pod 無法排程
Karpenter 無法排程指定節點群組標籤(如 eks.amazonaws.com/nodegroup),因為這些標籤與節點集區組態中定義的任何值都不符。若發生此不相符的情況,Karpenter 將因缺少所需節點標籤而無法將 Pod 放置在節點上。您會收到下列其中一個錯誤訊息:
「incompatible requirements, label \"eks.amazonaws.com/nodegroup\" does not have known values"」
「incompatible requirements, key topology.kubernetes.io/zone, topology.kubernetes.io/zone In [us-east-1a] not in topology.kubernetes.io/zone In [us-east-1b us-east-1c]」
「incompatible requirements, key nodes.ktp.io/role, nodes.ktp.io/role In [ktp-atom-apps] not in nodes.ktp.io/role In [kube-apps]」
若希望 Karpenter 能排程 Pod,請移除受管節點群組特定的 nodeSelector,以解決此錯誤。
範例:
kubectl edit pod your-pod-name or kubectl edit deployment your-deployment-name or kubectl edit daemonset your-daemonset-name
**注意:**將 your-pod-name、your-deployment-name 或 your-daemonset-name 替換為您的 Pod、部署或 daemonset 名稱。
節點整合失敗
Karpenter 的節點整合可能因排程限制或特定 Pod 組態而失敗,這些限制會阻止 Pod 遷移。
排程限制
當 Pod 無法遷移時,節點整合將失敗,原因可能包括:
- Pod 間親和性或反親和性: 需要與其他 Pod 同置或避免同置的 Pod。
- 拓撲分散限制: 必須分散到不同區域、節點或機架的 Pod。
- 其他排程限制: 任何其他阻止 Pod 移動到其他節點的限制。
請檢查並調整 Pod 的親和性與反親和性規則,使其不那麼嚴格。調整拓撲分散限制,以允許更多彈性,並檢查其他可能過於嚴格的排程限制。
特定 Pod 的預防措施
如果節點上執行某些類型的 Pod,Karpenter 可能無法整合節點。由於註解、排程限制、Pod 中斷預算 (PDB) 或缺乏控制器擁有者,Karpenter 無法移出這些 Pod。即使 kube-scheduler 技術上可以將 Pod 安置在其他位置,整合可能仍會失敗,因為 Karpenter 不會違反這些偏好設定。
- 語言
- 中文 (繁體)
