スキップしてコンテンツを表示

Amazon EKS で Karpenter オートスケーリングを使用し、クラスターのスケーリングをトラブルシューティングする方法を教えてください。

所要時間4分
0

Amazon Elastic Kubernetes Service (Amazon EKS) で Karpenter オートスケーラーを使用し、クラスターのスケーリングをトラブルシューティングしたいと考えています。

解決策

表示されたエラーメッセージに応じて、問題をトラブルシューティングしてください。

Amazon EKS ノードグループのインスタンス数が不足しており、Karpenter ポッドをスケジュールできない

注: AWS コマンドラインインターフェイス (AWS CLI) コマンドの実行中にエラーが発生した場合は、「AWS CLI で発生したエラーのトラブルシューティング」を参照してください。また、AWS CLI の最新バージョンを使用していることを確認してください。

Karpenter バージョン 0.16.0 以降では、デフォルトのレプリカ数が 1 から 2 に変更されました。詳細については、GitHub のウェブサイトで「v0.16.0」を参照してください。クラスター内のノード容量が、構成されたレプリカ数をサポートするには十分でない場合、Karpenter ポッドをスケジュールできません。Karpenter は、自身のポッドを実行するためのノードをプロビジョニングできないため、容量不足が原因で障害が発生し、結果的にポッドのスケジューリングは行われません。その場合、次のエラーメッセージが表示されます。

"Warning FailedScheduling 3m default-scheduler 0/1 nodes are available: 1 Insufficient memory."

このエラーを解決するには、次のいずれかの手順を実行します。

Karpenter デプロイのレプリカ数を 1 に削減する

Karpenter のデプロイに冗長性が不要な場合は、単一のレプリカを使用するよう設定を変更します。次のコマンドを実行します。

kubectl scale deployment karpenter --replicas=1

Karpenter ポッドのノード容量を増やす

Karpenter のレプリカを 2 つ実行する場合は、容量が 2 つのレプリカをサポートするのに十分であることを確認します。次のいずれかの方法を実施します。

Auto Scaling グループをスケールアウトする

  1. Auto Scaling グループの最小インスタンス数を増やします。次のコマンドを実行します。
    aws autoscaling update-auto-scaling-group --auto-scaling-group-name your-node-group-name --min-size 2 --desired-capacity 2
    注: your-node-group-name を Auto Scaling グループ名に置き換えてください。
  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 をノード名に置き換えてください。

ボリュームのアタッチとマウントの失敗

永続ボリュームクレーム (PVC) を使用する複数のポッドが同じノードにスケジュールされている場合、そのノードはボリュームアタッチ制限を超過する可能性があります。次に、以下のいずれかのエラーメッセージが表示される場合があります。

"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 を多用するワークロードでの、ボリューム接続とマウントに関する障害を解決するには、次の手順を実行します。

  1. topologySpreadConstraints および podAntiAffinity を適用し、PVC を多用するポッドが同一ノードにスケジュールされないようにします。詳細については、Kubernetes のウェブサイトで「topologySpreadConstraints フィールド」および「ポッドアフィニティの例」を参照してください。このアクションは、PVC を多用するポッドを複数ノードに分散することで、単一ノードにボリュームのアタッチが集中しないようにします。
  2. Amazon Elastic Block Store (Amazon EBS) Container Storage Interface (CSI) ドライバー (aws-ebs-csi-driver) などの CSI ドライバーを使用し、NodePool にスタートアップテイントを追加します。これらの手順を実行すると、ポッドの準備が完了する前に、早期にノードでスケジュールされることを防止できます。
    Amazon EBS のスタートアップテイント構成例:
    --yaml--
    apiVersion: karpenter.sh/v1
    kind: NodePool
    spec:
      template:
        spec:
          startupTaints:
            - key: ebs.csi.aws.com/agent-not-ready
              effect: NoExecute
    

非推奨ストレージプラグインに関するエラー

Karpenter は、非推奨のインツリーストレージプラグイン (例: Amazon EBS) をサポートしていません。インツリープラグインで静的プロビジョニングされた永続ボリューム (PV) を使用する場合、Karpenter はノードのボリュームアタッチ制限を検出できません。このシナリオでは、スケジュールの失敗につながる可能性があり、次のエラーメッセージが表示されることがあります。

"ERROR controller.node_state PersistentVolume source 'AWSElasticBlockStore' uses an in-tree storage plugin which is unsupported by Karpenter and is deprecated by Kubernetes." (使用しているインツリープラグインは Karpenter でサポートされず、Kubernetes では非推奨です)

この問題を解決するには、Amazon EBS 用の CSI ドライバーを使用し、PV 構成では、その CSI ドライバーを使用するよう設定します。

リソースリクエストが指定されていないことが原因で、スケジュールまたはビンパッキングが失敗する

Karpenter は、リソースリクエストに基づいてポッドをビンパッキングします。リクエスト数が少なすぎるか、欠けがある場合、Karpenter は同一ノードに過剰にポッドを割り当てる可能性があります。このシナリオでは、リソースの競合や CPU のスロットリングにつながる可能性があります。また、メモリ制限が設定されており、ポッドがその制限を上回るメモリを利用しようとした場合、メモリ不足 (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 構成により最大制限を確立することで、過剰消費を防ぐことができます。また、未指定のポッドに対するデフォルト制限も適用されます。詳細については、「LimitRanges を使用してリソースリクエスト数と制限にデフォルト値を設定する」を参照してください。

Windows ポッドがイメージプルエラーで起動できない

コンテナのオペレーティングシステム (OS) バージョンが Windows OS のバージョンと整合しない場合、ポッドは起動に失敗します。次の例に類似したエラーメッセージが表示されます。

"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"

この問題を解決するには、ポッドの nodeSelector を定義することで、コンテナのスケジュールが互換 OS ホストバージョンで行われるようにします。詳細については、Microsoft のウェブサイトで「Windows コンテナバージョンの互換性」を参照してください。

ノードが適切に初期化されていない

システムは、ノードの準備状況、予想されるリソース登録、および NodePool のスタートアップテイント削除に基づいてノードの初期化を判断します。上記いずれかの条件が満たされない場合、Karpenter ノードは適切に初期化されず、そのノードは NotReady ステータスに留まります。結果的に、システムはこのノードを使用してワークロードのスケジュールや統合を行うことはできません。次のエラーメッセージが表示される場合があります。

"Nodes provisioned by Karpenter are in a NotReady state"

ノードのステータスが Ready であることを確認します。そうでない場合は、Kubelet ログを調査し、権限、セキュリティグループ、ネットワークに関する潜在的な問題を特定します。

すべての必須リソース (例: nvidia.com/gpuvpc.amazonaws.com/pod-eni) がノードに適切に登録されていることを確認します。

ノード上の nvidia.com/gpu リソースを確認するには、次のコマンドを実行します。

kubectl describe node your-node-name

注: your-node-name をノード名に置き換えてください。

出力例:

...
Capacity:
  nvidia.com/gpu.shared: 80
...

これらのリソースが見つからない場合は、適切なデーモンセットまたはプラグインが実行されていることを確認します。デーモンセットが存在するかどうかを確認するには、次のコマンドを実行します。

kubectl get ds -n your-daemonset-namespace

注: your-daemonset-namespace をデーモンセットの名前空間に置き換えてください。。

複数の制約や制限に起因するスケジューリング失敗

アフィニティ、アンチアフィニティ、またはトポロジー拡散の制約が原因で、ポッドをスケジュールできない

アフィニティ、アンチアフィニティ、またはトポロジー拡散の制約は、特定のノードまたはゾーンを必要とするものの、適切なノードが必要な場所に存在しない場合は、ポッドをスケジュールできません。ノードまたはゾーンの要件が満たされないことが原因で、システムがポッドを配置できない場合、次のエラーメッセージが表示されることがあります。

"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."

このエラーを解決するには、ポッドのアフィニティおよびアンチアフィニティ設定、またはトポロジー拡散の制約を確認して調整し、使用可能なノードと整合させます。これらの制約を緩和するか、必要なゾーン内に追加のノードをプロビジョニングします。

リソース不足が原因でポッドをスケジュールできない

リソースリクエスト数が利用可能なノード容量を上回っていることが原因で、ポッドが未スケジュール状態に留まっています。ポッドを受け入れるのに十分な CPU、メモリ、またはその他のリソースを持つノードが存在しない場合、次のエラーメッセージが表示されることがあります。

"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."

この問題を解決するには、ポッドの仕様では、実際の使用状況を反映したリソースリクエスト数を指定する必要があります。必要に応じてリソースリクエスト数と制限を調整するか、大容量を備えた、より大規模なノードをプロビジョニングすることでリソース需要に対応します。

テイントが原因でポッドのスケジュールが妨げられる

クラスター管理者により、特定のノードにカスタムテイントが適用されている場合、ポッドにはそれに対応するトレレーションが必要です。対応するトレレーションが設定されていない場合、システムはそれらのノードではポッドをスケジュールできません。次のエラーメッセージが表示されます。

"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."

このエラーを解決するには、ポッドの仕様に適切なトレレーションを追加し、テイントを許容できるよう設定します。または、ノードに対するカスタムテイントの制限が厳しすぎる場合は、そのテイントを削除するか変更します。

ノードからテイントを削除するには、次のコマンドを実行します。

kubectl taint nodes your-node-name your-custom-taint-

注: your-node-name をノード名に、your-custom-taint カスタムテイント名に置き換えてください。

NodeAffinity または NodeSelector の制約が満たされていない

ノードアフィニティまたはノードセレクターの制約がクラスター内の利用可能なノードと一致しない場合、スケジューラーはポッドを配置できません。次のエラーメッセージが表示されます。

"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."

このエラーを解決するには、ポッドのノードアフィニティまたはノードセレクターの要件を緩和します。または、必要に応じて、ポッドの条件を満たすノードを追加でプロビジョニングします。詳細については、Kubernetes のウェブサイトで「ノードアフィニティ」および「nodeSelector」を参照してください。

サブネット内の IP アドレス数不足

サブネット内に十分な数の IP アドレスが存在しないことが原因で、Karpenter は新しいノードをプロビジョニングできません。このシナリオは、サブネットの Classless Inter-Domain Routing (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 ブロックをセカンダリ CIDR として、Amazon Virtual Private Cloud (Amazon VPC) に追加します。

または、

カスタムネットワークを使用し、ポッドとノードに別々の IP アドレス空間を割り当てます。カスタムネットワークを有効にするには、次のコマンドを実行します。

kubectl set env daemonset aws-node -n kube-system AWS_VPC_K8S_CNI_CUSTOM_NETWORK_CFG=true

カスタムネットワークに関する詳細については、「Amazon EKS 内のポッドに、特定の IP アドレスサブネットを選択する方法を教えてください」を参照してください。

要件の非互換が原因でポッドをスケジュールできない

ノードプールの構成で定義された値に一致しないノードグループのラベル (例: eks.amazonaws.com/nodegroup) をポッドが指定している場合、Karpenter はそのポッドをスケジュールできません。このミスマッチが発生すると、必要なノードラベルが存在しないことが原因で、Karpenter はポッドをノードに配置できません。次のいずれかのエラーメッセージが表示されます。

"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 でスケジュールできるようにするには、マネージドノードグループ固有の nodeSelector を削除してこのエラーを解決します。

例:

kubectl edit pod your-pod-name
or  
kubectl edit deployment your-deployment-name
or
kubectl edit daemonset your-daemonset-name

注: your-pod-nameyour-deployment-nameyour-daemonset-name をそれぞれ、目的のポッド、デプロイ、またはデーモンセットに置き換えてください。

ノード統合の失敗

Karpenter のノード統合は、スケジュールの制約、または Pod の移行を妨げる特定のポッド構成が原因で失敗する可能性があります。

スケジュールの制約

次の原因でポッドを移行できない場合、ノード統合は失敗します。

  • ポッド間のアフィニティまたはアンチアフィニティ: 他のポッドと同じ場所に配置する必要があるポッド、または配置できないポッド。
  • トポロジー拡散の制約: 複数のゾーン、ノード、またはラックにわたり分散する必要があるポッド。
  • その他のスケジュール制限: ポッドが他のノードに移動できない原因となる、その他の制約。

ポッドのアフィニティとアンチアフィニティのルールをレビューして調整することで、制限を緩和します。トポロジー拡散制約、および制限が厳しすぎる可能性があるその他のスケジュール制限を調整し、柔軟性を高めます。

ポッド固有の失敗要因

ノード上で特定の種類のポッドが実行されている場合、Karpenter はノードを統合できない可能性があります。アノテーション、スケジュールの制限、ポッド中断予算 (PDB)、コントローラーの所有者不在などの原因で、Karpenter はこれらのポッドをエビクトできません。kube-scheduler は技術的にはポッドを他の場所に配置できる場合も、Karpenter はこれらのプリファレンスに違反できないことが原因で、統合に失敗する可能性があります。

AWS公式更新しました 2ヶ月前
コメントはありません

関連するコンテンツ