0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Amazon EKS が EKS Auto Mode および Karpenter 上での EFA・プレイスメントグループに対応

0
Posted at

はじめに

2026 年 7 月 22 日、AWS は Amazon EKS の EKS Auto Mode および Karpenter に対して、EFA(Elastic Fabric Adapter)とプレイスメントグループのサポートを発表しました。ノードプールの設定から直接、ネットワークやインスタンスの物理配置を制御できるようになったことが大きな特徴です。

EKS で GPU クラスターを運用している方の中には、EFA を使うために手動での回避策が必要だったり、VPC の IP アドレス枯渇に悩まされたりした経験がある方もいるのではないでしょうか。今回のアップデートは、その課題に直接応えるものです。

本記事では、何が変わったのか、どのような組織にとって意味のあるアップデートなのか、そしてどのようなアーキテクチャでどう有効化すればよいのかを中心に解説します。EKS 上で分散トレーニング・推論基盤を運用するインフラ・プラットフォームエンジニアの方や、これから GPU クラスター基盤の構築を検討している方を想定読者としています。


何が変わったのか

これまで EKS Auto Mode や Karpenter でノードプールを構成する際、EFA ネットワークインターフェースの詳細設定や EC2 プレイスメントグループの指定は、ノードプールのマニフェストから直接行うことができませんでした。分散トレーニングや大規模推論のように、GPU インスタンス間の物理的な配置や通信性能がジョブの成否を左右するワークロードであっても、これらを最適化するには追加の運用上の回避策が必要でした。

項目 従来 今回のアップデート
EFA ネットワークインターフェース設定 ノードプールの外で個別に構成が必要 NodeClass / NodePool から EFA-only または標準 ENI を直接指定可能
EC2 プレイスメントグループ ノードプール設定から指定不可 cluster・spread・partition の 3 戦略を直接指定可能
キャパシティタイプ 動的キャパシティ・静的キャパシティの両方に対応

従来の課題

大規模な GPU クラスターを組む際、分散トレーニングでは数百〜数千台のインスタンス間で大量のデータ通信が発生します。このとき、インスタンスを物理的に近接させる cluster プレイスメントグループのような制御は、レイテンシと帯域幅に直結する重要な要素ですが、これまでは EKS のノードプール定義の外側で EC2 側の設定として個別に行う必要がありました。

また、EFA ネットワークインターフェースは通常の ENI と同様に IP アドレスを消費するため、数百ノード規模のクラスターを運用しようとすると VPC の IP アドレスを圧迫し、CIDR 設計上のボトルネックになるケースもありました。

EFA・プレイスメントグループ対応による解決

今回のアップデートにより、EKS Auto Mode および Karpenter のノードプール設定から直接、EFA ネットワークインターフェースを EFA-only または標準 ENI として構成できるようになりました。EFA-only インターフェースは IP アドレスを消費しないため、フルインターコネクト帯域幅を確保しながら VPC の IP 利用を抑えられます。

あわせて、cluster・spread・partition のプレイスメントグループ戦略もノードプール定義から直接指定できるようになり、インスタンスの物理的な配置戦略を Kubernetes のマニフェストレベルで完結できます。これらはいずれも動的キャパシティ・静的キャパシティの両方のノードプールに対応しています。

この機能は Amazon EKS が利用可能な全リージョンで利用できます。


この機能が必要な組織

EFA・プレイスメントグループ対応は、すべての EKS ユーザーに一律で恩恵があるわけではなく、特定のワークロード特性を持つ組織にこそ価値を発揮する機能です。導入を検討する前に、自分たちのワークロードに当てはまるかどうかを整理しておくと判断がしやすくなります。

この機能が活きるのは、LLM や画像認識モデルなど数百〜数千台規模の GPU インスタンスで分散トレーニングを行う組織、可用性 SLA を重視する本番推論サービスを運用する組織、複数テナントや複数モデルを 1 つのクラスターに同居させたい組織です。GPU 間通信がボトルネックになっている、あるいは VPC の IP アドレス枯渇に直面しているといった課題があれば、特に効果を実感しやすいはずです。逆に、CPU 中心のワークロードや小規模な GPU クラスター、単一ノードで完結する検証環境であれば、無理に導入するメリットは大きくありません。

ただし、EFA-only とプレイスメントグループの組み合わせは、ワークロードの通信パターンや可用性要件に応じて最適な設定が変わります。


アーキテクチャ解説

EFA・プレイスメントグループ対応が「具体的に何を変えているのか」を、もう少し踏み込んで見ていきます。

EFA-only インターフェースの仕組み

EKS Auto Mode の NodeClass、あるいは Karpenter の EC2NodeClass では、networkInterfaces フィールドでネットワークインターフェースの構成をインスタンス起動時に静的に定義できます。各インターフェースは networkCardIndex(ネットワークカードの番号。0 がプライマリ)、deviceIndex(カード上のデバイス位置)、interfaceTypeinterface または efa-only)の 3 つで定義され、プライマリの ENI(networkCardIndex: 0deviceIndex: 0)は必ず interfaceType: interface として、通常の IP ベース通信を担う必要があります。

一方、efa-only タイプのインターフェースは IP アドレスを一切割り当てられず、RDMA 通信専用の EFA デバイスとしてのみ機能します。OS-bypass によって CPU を介さずネットワークインターフェースへ直接アクセスできるため、MPI や NCCL といった並列通信ライブラリで低レイテンシ・高帯域幅の通信が可能になります。IP アドレスを消費しないという性質上、GPU インスタンスに複数の EFA インターフェースを追加しても VPC の IP アドレス予算を圧迫しません。

なお、networkInterfaces を明示的に設定した場合、EKS Auto Mode や Karpenter はインスタンス起動後に追加の IP やプレフィックス、ENI を割り当てません。起動時に構成した IP アドレス数がそのノードで利用できる Pod 数の上限になるため、あらかじめ Pod 密度を見積もった上でプライマリ ENI の secondaryIPv4CountsecondaryIPv4PrefixCount を設計しておく必要があります。

プライマリの ENI だけが VPC の IP アドレス空間に属し、残りの efa-only インターフェースは IP を持たずに GPU 間の RDMA 通信だけを担っている、という構成がポイントです。

プレイスメントグループ 3 戦略の使い分け

cluster プレイスメントグループは、同一 AZ 内の物理的に近いラックにインスタンスを配置し、低レイテンシ・高スループットのネットワークを実現します。最初のインスタンスが起動した時点でそのプレイスメントグループは当該 AZ に固定されるため、複数 AZ にまたがる NodePool で同時にスケールアウトすると、最初に成功したインスタンスが AZ を確定させ、残りが容量エラーになることがあります。NodePool の要件で AZ を固定しておくと、こうした一時的な失敗を避けられます。

spread プレイスメントグループは、インスタンスを異なる物理ハードウェアに分散配置し、単一ハードウェア障害の影響範囲を最小化します。ただし 1 つの AZ あたり最大 7 台という制約があり、上限に達している状態でドリフト置換のためのノード入れ替えが発生すると、新しいノードの起動に失敗し、古いノードが起動したまま残り続けるケースがあります。

partition プレイスメントグループは、インスタンスを複数の独立したパーティション(1 AZ あたり最大 7 パーティション)に分散し、パーティション単位で障害を分離します。Hadoop や Cassandra のような大規模分散システム向けの戦略で、karpenter.k8s.aws/placement-group-partition ラベルを使った Pod のトポロジー分散制約と組み合わせることで、パーティションをまたいでワークロードを分散配置できます。cluster ・ spread と異なり、標準的な EC2 の制約以外に追加の制限はありません。

左から順に、cluster(単一 AZ 内で近接配置)、spread(異なる物理ホストに分散)、partition(独立したパーティションに分散)を表しています。

設定の選び方

EFA インターフェースとプレイスメントグループ戦略は独立した設定項目のため、ワークロードの特性に応じて組み合わせを選ぶことになります。

ワークロード特性 推奨インターフェース 推奨プレイスメントグループ
GPU 間通信がボトルネックになる分散トレーニング EFA-only cluster
可用性重視の本番推論サービス 標準 ENI spread
Hadoop・Cassandra 等の大規模分散システム 標準 ENI(用途に応じて EFA-only も可) partition

1 つの NodeClass・EC2NodeClass は 1 つのプレイスメントグループにのみ対応します。そのため、複数の戦略を使い分けたい場合は、ワークロードごとに NodeClass・NodePool を分けて用意することになります。また、EFA インターフェースを複数持つノードでは associatePublicIPAddress を有効にできないという制約もあるため、EFA を使うワークロードは通常のワークロードとは別の NodeClass・NodePool に切り出しておくのが安全です。


Karpenter 運用時の注意点

前章で見たプレイスメントグループの制約は、静的な構成としては理解しやすいものですが、Karpenter による動的なノードの入れ替えと組み合わさると、思わぬところで詰まることがあります。実際に運用する上で踏みやすい落とし穴を見ていきます。

ドリフト置換がスタックする

Karpenter はノードの設定がドリフトした際、既存ノードを削除する前に新しいノードを起動する replace-then-delete 方式で置き換えます。ところが spread プレイスメントグループが AZ ごとの上限(7 台)に達している状態でドリフトが発生すると、置換用の新しいノードの起動に失敗し、ドリフトしたノードは空きが出るまでそのまま残り続けます。すべての AZ が上限に達している場合は、ドリフトしたノードやコンソリデーション対象のノードが無期限に残り続けることになります。Karpenter はプレイスメントグループの外にフォールバックして置換ノードを起動することもありません。

この問題を避けるには、consolidationPolicy: WhenEmpty を設定しておくのが有効です。このポリシーでは、DaemonSet 以外の Pod がすべて退避してからノードが削除されるため、新しい置換ノードを起動せずにプレイスメントグループの空きを作れます。ただし、ドリフト自体は consolidationPolicy の設定に関わらず常に replace-then-delete 方式で行われるため、上限に達している間はドリフト置換そのものがブロックされる点は変わりません。

Consolidation でノードがプレイスメントグループの外に出てしまう

Pod にプレイスメントグループを指定するスケジューリング制約(eks.amazonaws.com/placement-group-id に対する nodeSelector など)がない場合、コンソリデーションによって Pod がプレイスメントグループ外のノードに移動してしまうことがあります。EFA を使う分散トレーニングジョブのように、プレイスメントグループへの所属が性能上重要な Pod では、この制約を明示的に設定しておく必要があります。

プレイスメントグループが削除されると新規ノードが起動しなくなる

NodeClass が参照しているプレイスメントグループが存在しない場合、新しいインスタンスは一切起動しません。プレイスメントグループ ID のフォーマット自体は admission 時に検証されますが、実在するかどうかはインスタンス起動時にしかチェックされません。運用中にプレイスメントグループを誤って削除してしまうと、既存のノードはドリフトとしてマークされたまま起動し続けます。これは前述の通り、ドリフト置換自体がプレイスメントグループの容量不足時にブロックされる仕組みのためです。

これらはいずれも、静的な設定ミスというよりも、Karpenter の動的なスケーリング・置換ロジックとプレイスメントグループの容量制約が組み合わさって初めて表面化する問題です。


有効化の手順

ここまでの内容を踏まえて、実際に設定していきます。分散トレーニング向け(EKS Auto Mode・cluster プレイスメントグループ・EFA-only)と、高可用本番サービス向け(Karpenter・spread プレイスメントグループ)の 2 パターンを見ていきます。

なお、自己管理の Karpenter で EC2NodeClass の networkInterfaces を使って EFA を設定する場合は Karpenter v1.11 以降が必要です。EKS Auto Mode の NodeClass にはこのバージョン制約はありません。

EKS Auto Mode で分散トレーニング向けに設定する

まず、EC2 側でプレイスメントグループを作成しておきます。

aws ec2 create-placement-group \
    --group-name <placement-group-name> \
    --strategy cluster \
    --region <region-code>

続けて、EFA-only インターフェースと作成したプレイスメントグループを指定した NodeClass を用意します。

apiVersion: eks.amazonaws.com/v1
kind: NodeClass
metadata:
  name: <nodeclass-name>
spec:
  role: <role-name>
  subnetSelectorTerms:
    - tags:
        Name: "<subnet-name-tag>"
  securityGroupSelectorTerms:
    - tags:
        Name: "<security-group-name-tag>"
  placementGroupSelector:
    name: "<placement-group-name>"
  advancedNetworking:
    networkInterfaces:
      - deviceIndex: 0
        interfaceType: interface
        networkCardIndex: 0
        secondaryIPv4PrefixCount: 1
      - deviceIndex: 0
        interfaceType: efa-only
        networkCardIndex: 1
kubectl apply -f nodeclass.yaml

最後に、この NodeClass を参照する NodePool を作成します。EKS Auto Mode の NodePool は Karpenter の CRD をそのまま利用しており、nodeClassRef で先ほどの NodeClass を参照します。EFA 対応インスタンスに絞り込む要件は、対象のインスタンスファミリーに応じて別途追加してください。

apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: <nodepool-name>
spec:
  template:
    spec:
      nodeClassRef:
        group: eks.amazonaws.com
        kind: NodeClass
        name: <nodeclass-name>
kubectl apply -f nodepool.yaml

Karpenter で高可用本番サービス向けに設定する

こちらも先にプレイスメントグループを作成します。

aws ec2 create-placement-group \
    --group-name <placement-group-name> \
    --strategy spread \
    --region <region-code>

Karpenter の EC2NodeClass では、EFA は使わずプレイスメントグループのみを指定します。

apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
metadata:
  name: <ec2nodeclass-name>
spec:
  role: <role-name>
  subnetSelectorTerms:
    - tags:
        karpenter.sh/discovery: "<cluster-name>"
  securityGroupSelectorTerms:
    - tags:
        karpenter.sh/discovery: "<cluster-name>"
  placementGroupSelector:
    name: "<placement-group-name>"

前章で触れた通り、spread プレイスメントグループは AZ ごとに最大 7 台という上限があるため、ドリフト置換が詰まらないよう NodePool 側で consolidationPolicy: WhenEmpty を設定しておきます。

apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: <nodepool-name>
spec:
  disruption:
    consolidationPolicy: WhenEmpty
  template:
    spec:
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: <ec2nodeclass-name>
kubectl apply -f ec2nodeclass.yaml
kubectl apply -f nodepool.yaml

設定を確認する

設定が完了したら、意図通りに反映されているかを確認します。

NodeClass・EC2NodeClass が問題なく解決されているかは、status.conditionsReady で確認できます。

kubectl get nodeclass <nodeclass-name> -o jsonpath='{.status.conditions}'

インスタンスが起動したら、実際に対象のプレイスメントグループに配置されているかを EC2 側からも確認します。

aws ec2 describe-instances \
    --filters "Name=placement-group-name,Values=<placement-group-name>" \
    --query "Reservations[].Instances[].[InstanceId,Placement.GroupName]"

EFA-only インターフェースが意図通り作成されているかは、対象インスタンスにアタッチされたネットワークインターフェースのタイプで確認できます。

aws ec2 describe-network-interfaces \
    --filters "Name=attachment.instance-id,Values=<instance-id>" "Name=interface-type,Values=efa-only" \
    --query "NetworkInterfaces[].[NetworkInterfaceId,InterfaceType]"

前章で触れたプレイスメントグループへの Pod のスケジューリング制約を使う場合は、eks.amazonaws.com/placement-group-id ラベルがノードに正しく付与されているかもあわせて確認しておくとよいでしょう。

kubectl get node <node-name> -o jsonpath='{.metadata.labels.eks\.amazonaws\.com/placement-group-id}'

活用シーン

ここまでの内容を踏まえて、実際にどのような場面でこの機能が活きるのか、具体的なシナリオで見ていきます。

LLM の分散事前学習

数百台規模の GPU インスタンスを使って LLM を事前学習するようなワークロードでは、GPU 間の通信性能がそのまま学習速度を左右します。cluster プレイスメントグループでインスタンスを同一 AZ 内の近接したラックに集約し、EFA-only インターフェースで NCCL などの並列通信ライブラリの帯域幅を最大化することで、ノード数を増やしてもスケールしやすい構成を組めます。EFA-only インターフェースは IP アドレスを消費しないため、GPU 1 枚あたり複数のインターフェースを持たせても VPC の IP アドレス予算を圧迫しない点も、大規模クラスターでは効いてきます。

可用性重視の推論エンドポイント

常時稼働が求められるオンラインの推論エンドポイントでは、通信帯域よりも単一障害の影響範囲を抑えることが優先されます。spread プレイスメントグループでノードを異なる物理ホストに分散させておけば、特定のラックやホストで障害が起きても、他のノードで処理を継続できます。この用途では EFA-only のような専用インターフェースは基本的に不要で、標準 ENI のままプレイスメントグループだけを指定する構成で十分です。

マルチテナント推論プラットフォーム

複数のテナントやモデルを 1 つのクラスターに同居させる推論プラットフォームでは、partition プレイスメントグループが有効です。テナントやモデルごとにパーティションを分けて配置しておけば、あるパーティションでハードウェア障害が発生しても他のパーティションへの影響を遮断できます。Pod 側で karpenter.k8s.aws/placement-group-partition ラベルを使った topologySpreadConstraints を設定しておくことで、特定のテナントの Pod が偏って同じパーティションに集中することも避けられます。


まとめ

EKS Auto Mode と Karpenter における EFA・プレイスメントグループ対応により、EFA ネットワークインターフェースを EFA-only として構成できるようになりました。IP アドレスを消費せずに GPU 間の高帯域通信を確保できます。cluster・spread・partition のプレイスメントグループもノードプール定義から直接指定できるため、インスタンスの物理的な配置戦略を Kubernetes のマニフェストレベルで完結できます。分散トレーニングから高可用な本番サービス、マルチテナント基盤まで、GPU クラスターを運用する上での選択肢が広がるアップデートです。

一方で、この機能はすべての EKS ユーザーに一律で必要というわけではありません。1 つの NodeClass・EC2NodeClass は 1 つのプレイスメントグループにしか対応しないこと、EFA インターフェースを持つノードでは Public IP の割り当てに制約があることは、導入前に理解しておく必要があります。Karpenter のドリフト置換やコンソリデーションは、プレイスメントグループの容量制約と組み合わさって詰まることがあるため、検証環境で動作を確認してから本番環境に適用することをおすすめします。

なお、執筆時点(2026 年 7 月)では、EKS の公式ドキュメント間で EKS Auto Mode の対応状況について記載に揺れが見られます。本記事は EKS Auto Mode の NodeClass ドキュメントに掲載された設定例をもとにしていますが、導入前に最新のドキュメントで対応状況をあわせて確認してください。


参考リンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?