View a markdown version of this page

Amazon EKS 用のカスタム Bottlerocket AMI バリアントを構築する - Amazon EKS

このページの改善にご協力ください

このユーザーガイドに貢献するには、すべてのページの右側のペインにある「GitHub でこのページを編集する」リンクを選択してください。

Amazon EKS 用のカスタム Bottlerocket AMI バリアントを構築する

Amazon Elastic Kubernetes Service (Amazon EKS) で GPU ワークロードを実行する場合は、Bottlerocket バリアントを選択します。バリアントは、Kubernetes バージョンとアクセラレータータイプと一致する必要があります。Bottlerocket は、一般的な設定用に検証済みバリアントを提供します。ただし、次のいずれかの理由により、組織で別のバリアントが必要になる可能性があります:

  • 新しい NVIDIA ドライバーブランチ

  • 規制コンプライアンスのためのピン留めされたドライバーバージョン

  • モニタリング用の追加パッケージ

  • セキュリティチームが必要とする強化されたベースライン

GitHub ウェブサイトの Bottlerocket は完全なオープンソースであるため、これらのニーズを満たすカスタムバリアントを作成できます。このトピックでは、既存のバリアントのクローンを作成し、NVIDIA ドライバーを R580 ブランチから R595 (バージョン 595.71.05) にスワップする方法について説明します。次に、イメージを構築し、それをプライベート AMI として登録します。

重要

G7 EC2 インスタンスタイプには NVIDIA ドライバーバージョン 595 以降が必要です。EKS Bottlerocket NVIDIA AMI には現在、G7 インスタンスをサポートしていない NVIDIA ドライバーバージョン 580 が含まれています。

NVIDIA ドライバーバージョン 595 でバリアントを構築する手順については、GitHub ウェブサイトの「Bottlerocket リポジトリ」を参照してください。このトピックでは、ステップ 1 から始まる完全なプロセスについて説明します。

ビルドシステムの仕組み

cargo make -e BUILDSYS_VARIANT=aws-k8s-1.36-nvidia を実行すると、次の 3 つのことが発生します:

  • 依存関係を取得する。Twoliter (Bottlerocket ビルドオーケストレーター) は Twoliter.toml を読み取り、public.ecr.aws/bottlerocket から 3 つの Open Container Initiative (OCI) アーティファクトをプルします:

    • bottlerocket-sdk – 完全なクロスコンパイルツールチェーン (GCC、Rust、Go、RPM マクロ) を持つコンテナイメージ。

    • bottlerocket-kernel-kit – カーネル、カーネルモジュール (NVIDIA kmod パッケージを含む)、およびファームウェア用の構築済み RPM。

    • bottlerocket-core-kit – ユーザースペース用の構築済み RPM: kubelet、containerd、NVIDIA デバイスプラグインとコンテナツールキット、設定プラグイン、システムサービス。

      Twoliter.toml はバージョンをピン留めし、Twoliter.lock はダイジェストをロックします。いずれかを変更するには、./tools/twoliter/twoliter update を実行して再解決します。

  • バリアントを構築する。Twoliter は SDK コンテナ内で Docker ビルドを起動します。バリアントの設定デフォルトクレートをコンパイルし、キットから RPM 依存関係ツリーを解決し、すべてをディスクイメージにアセンブルします。

  • 出力する。Twoliter は最終 .img.lz4 ファイルを build/images/ に書き込みます。ビルドは決定論的な出力を生成します: ホストに関係なく、同じ Twoliter.toml ピンとバリアント Cargo.toml は常に同じイメージを生成します。

リポジトリレイアウト

次のディレクトリはバリアント作業に関連しています:

bottlerocket/ ├── Cargo.toml # workspace: lists every variant ├── Twoliter.toml # pins SDK + kit versions ├── Twoliter.lock # locked digests for the above ├── Licenses.toml # you create this (NVIDIA license acknowledgement) ├── Infra.toml # you create this (AMI publish regions) │ ├── variants/ │ ├── aws-k8s-1.36-nvidia/ # example variant you'll copy │ │ ├── Cargo.toml # package list + kernel params │ │ └── amispec.toml # symlink → ../shared/amispec-split.toml │ └── shared/ # shared AMI spec templates │ ├── sources/ │ ├── Cargo.toml # workspace: lists every settings-defaults crate │ ├── shared-defaults/ # the actual defaults (symlink targets) │ └── settings-defaults/ │ └── aws-k8s-1.36-nvidia/ │ ├── Cargo.toml │ └── defaults.d/ # 30+ symlinks into shared-defaults/ │ └── packages/ ├── settings-defaults/ │ └── settings-defaults.spec # RPM: declares which variants exist └── settings-plugins/ └── settings-plugins.spec # RPM: maps variants to settings plugins

リポジトリ構造に関する次の注意事項をレビューします:

  • バリアントは主にメタデータです。外部キットは、カーネル、ドライバー、ユーザースペースを提供します。

  • Settings-defaults ファイルは、コピーではなくシンボリックリンクです。cp -R (macOS の cp -r ではなく) を使用してそれらを保持します。

  • バリアントを追加するには、次の 5 つの場所で編集する必要があります: 2 つのワークスペース Cargo.toml ファイル、2 つの .spec ファイル、および README.md

前提条件

このチュートリアルを完了するには、以下が必要になります:

  • EC2 インスタンスを起動して AMI を登録するアクセス許可を持つ AWS アカウント

  • 少なくとも 8 コア、16 GiB メモリ、および 150 GB ディスクを持つ EC2 インスタンス (または同等の Linux x86_64 ホスト)

  • Ubuntu 24.04 LTS (または Fedora。macOS はビルドホストとしてサポートされていません)

  • Docker 20.10 以降

  • Rust (安定ツールチェーン、rustup 経由でインストールされている)

  • cargo-make (最新バージョン)

  • Git、Rust の Cargo、RPM パッケージングの概念に精通していること

注記

このチュートリアルを完了したら、EC2 インスタンスを終了し、継続的な料金が発生しないよう不要になった AMI を登録解除します。クリーンアップ手順については、クリーンアップ を参照してください。

ステップ 1: ビルドホストを準備する

EC2 インスタンスを起動します – 例えば、c7i.8xlarge (32 vCPU、64 GiB メモリ)。150 GB の gp3 ルートボリュームを使用し、SSM アクセス用の AmazonSSMManagedInstanceCore マネージドポリシーをアタッチします。

AWS Systems Manager (SSM) Session Manager を使用してインスタンスに接続します:

aws ssm start-session --target <instance-id> cd ~

必要なオペレーティングシステムパッケージをインストールします:

apt-get update apt-get install -y build-essential openssl libssl-dev pkg-config lz4 \ git ca-certificates curl gnupg
注記

公式の BUILDING.mdliblz4-tool を参照します。最近の Ubuntu バージョンでは、パッケージは lz4 という名前です。

次のコマンドを使用して Docker をインストールします:

install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg \ -o /etc/apt/keyrings/docker.asc chmod a+r /etc/apt/keyrings/docker.asc echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \ https://download.docker.com/linux/ubuntu noble stable" \ > /etc/apt/sources.list.d/docker.list apt-get update apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin systemctl enable --now docker

次のコマンドを使用して Rust と cargo-make をインストールします:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y . "$HOME/.cargo/env" cargo install cargo-make

ステップ 2: リポジトリのクローンを作成する

GitHub ウェブサイトの Bottlerocket リポジトリのクローンを作成し、ディレクトリに移動します:

cd ~/bottlerocket

再現可能なビルドを作成するには、タグ付けされたリリース (git checkout v1.62.1 など) をチェックアウトします。最新のパッケージを使用するには、develop ブランチに留まります。

ステップ 3: キットのバージョンを確認する

Twoliter.toml を開き、キットのバージョンを確認します。R595 をサポートするには、bottlerocket-kernel-kit バージョン 6.2.2 以降が必要です。

[[kit]] name = "bottlerocket-kernel-kit" version = "6.2.2" vendor = "bottlerocket"

バージョンが古い場合は、更新してロックを再生成します:

./tools/twoliter/twoliter update

ステップ 4: cargo-make パスの問題を回避する

Twoliter は CARGO_HOME~/bottlerocket/.cargo に設定します。これにより、内部の Cargo プロセスが、グローバルにインストールされた cargo-make を検索できなくなります。シンボリックリンクを作成します。

mkdir -p ~/bottlerocket/.cargo/bin ln -sf /root/.cargo/bin/cargo-make ~/bottlerocket/.cargo/bin/cargo-make

このステップを行わないと、ビルドは error: no such command: make で失敗します。

ステップ 5: 使用可能なドライバーブランチを検索する

NVIDIA kmod パッケージは bottlerocket-kernel-kit 内に含まれています。使用可能なドライバーパッケージの詳細については、GitHub ウェブサイトの「kernel-kit パッケージディレクトリ」、または GitHub ウェブサイトの「リリースノート」を参照してください。

カーネル 6.18 (aws-k8s-1.36 バリアントで使用) の場合:

kmod-6.18-nvidia-r580 ← driver 580.159.03 (current default) kmod-6.18-nvidia-r595 ← driver 595.71.05

カーネル 6.12 (aws-k8s-1.331.341.35 で使用) の場合:

kmod-6.12-nvidia-r580 kmod-6.12-nvidia-r595
注記

各 kmod パッケージにはサブパッケージ (-tesla-open-gpu-grid-fabricmanager-imex) が含まれています。公式 Bottlerocket NVIDIA バリアントは -tesla を参照します。これは、RPM 依存関係を介して必要なすべてのサブパッケージをプルします。起動時に、Bottlerocket はインスタンスタイプに基づいて適切なドライバーフレーバーを自動的に選択します。

ステップ 6: 新しいバリアントを作成する

既存のバリアントをコピーします。シンボリックリンクを保持するには、cp -R を使用します:

cp -R variants/aws-k8s-1.36-nvidia variants/aws-k8s-1.36-nvidia-595 cp -R sources/settings-defaults/aws-k8s-1.36-nvidia \ sources/settings-defaults/aws-k8s-1.36-nvidia-595

variants/aws-k8s-1.36-nvidia-595/Cargo.toml を編集します:

- name = "aws-k8s-1_36-nvidia" + name = "aws-k8s-1_36-nvidia-595" - "kmod-6.18-nvidia-r580-tesla", + "kmod-6.18-nvidia-r595-tesla",

sources/settings-defaults/aws-k8s-1.36-nvidia-595/Cargo.toml を編集します:

- name = "settings-defaults-aws-k8s-1_36-nvidia" + name = "settings-defaults-aws-k8s-1_36-nvidia-595"

ステップ 7: バリアントを登録する

新しいバリアントを 5 つのファイルに登録します:

1. Cargo.toml – ワークスペースメンバーを追加します:

"variants/aws-k8s-1.36-nvidia", + "variants/aws-k8s-1.36-nvidia-595", "variants/aws-k8s-1.36-nvidia-fips",

2. sources/Cargo.toml – settings-defaults メンバーを追加します:

"settings-defaults/aws-k8s-1.36-nvidia", + "settings-defaults/aws-k8s-1.36-nvidia-595",

3. packages/settings-defaults/settings-defaults.spec %package ブロック、両方のビルドループのエントリ、および %files セクションを追加します:

%package aws-k8s-1.36-nvidia-595 Summary: Settings defaults for the aws-k8s 1.36 nvidia-595 variant Requires: %{_cross_os}variant(aws-k8s-1.36-nvidia-595) Provides: %{_cross_os}settings-defaults(any) Provides: %{_cross_os}settings-defaults(aws-k8s-1.36-nvidia-595) Conflicts: %{_cross_os}settings-defaults(any) %description aws-k8s-1.36-nvidia-595 %{summary}.

両方の for defaults in ループに追加します:

aws-k8s-1.36-nvidia \ + aws-k8s-1.36-nvidia-595 \ metal-dev \

%files セクションを追加します:

%files aws-k8s-1.36-nvidia-595 %{_cross_defaultsdir}/aws-k8s-1.36-nvidia-595.toml %{_cross_tmpfilesdir}/storewolf-defaults-aws-k8s-1.36-nvidia-595.conf

4. packages/settings-plugins/settings-plugins.spec %package aws-k8s-nvidia の下に Provides: 行を追加します:

Provides: %{_cross_os}settings-plugin(aws-k8s-1.36-nvidia) +Provides: %{_cross_os}settings-plugin(aws-k8s-1.36-nvidia-595) Conflicts: %{_cross_os}settings-plugin(any)

ステップ 8: ロックファイルを更新する

ワークスペースメンバーを追加すると、sources/Cargo.lock が無効になります。それを更新します:

cd ~/bottlerocket/sources cargo update --workspace
重要

cargo generate-lockfile を使用しないでください。これにより、ロックファイル全体が書き換えられ、推移的な依存関係がバンプされ、cargo-deny バージョンが重複するエラーが発生します。

ステップ 9: NVIDIA ライセンスファイルを作成する

NVIDIA はドライバーソースの再配布を制限します。以下を構築する前に、明示的なライセンス確認を追加する必要があります:

cat > ~/bottlerocket/Licenses.toml <<'EOF' [nvidia] spdx-id = "LicensesRef-NVIDIA-Customer-Use" licenses = [ { path = "LICENSE", license-url = "https://www.nvidia.com/en-us/drivers/nvidia-license/" } ] EOF

ステップ 10: AMI を構築して発行する

ターゲットリージョンで Infra.toml を作成します:

cat > ~/bottlerocket/Infra.toml <<'EOF' [aws] regions = ["us-west-2", "us-east-1", "us-east-2"] EOF

イメージを構築する:

cd ~/bottlerocket cargo make \ -e BUILDSYS_VARIANT=aws-k8s-1.36-nvidia-595 \ -e BUILDSYS_UPSTREAM_SOURCE_FALLBACK=true \ -e BUILDSYS_UPSTREAM_LICENSE_FETCH=true \ -e BUILDSYS_JOBS=32

最初のビルドでは、SDK イメージとキットイメージ (合計約 2 GB) をプルします。それ以降のビルドは、32 コアホストで 3~5 分かかります。

AMI を発行します:

cargo make \ -e BUILDSYS_VARIANT=aws-k8s-1.36-nvidia-595 \ -e PUBLISH_REGIONS=us-west-2,us-east-1,us-east-2 \ ami

ビルドは AMI ID を build/images/x86_64-aws-k8s-1.36-nvidia-595/latest/*-amis.json に書き込みます。EKS マネージドノードグループ、Karpenter EC2NodeClass、または起動テンプレートでこれらを使用します。

構築できるその他の組み合わせ

このチュートリアルでは NVIDIA ドライバーブランチをスワップしますが、アップストリームキットで利用可能なパッケージでも同じアプローチを使用できます。次の例は、キットをフォークせずにアセンブルできる内容を示しています:

必要なもの バリアント Cargo.toml の変更点

異なる NVIDIA ドライバーブランチ

kmod-6.18-nvidia-r580-teslakmod-6.18-nvidia-r595-tesla

異なるカーネルバージョン

kernel-6.18kernel-6.12 (それに応じて kmod を調整する)

NVIDIA を完全に削除する

included-packages から 3 つの nvidia-* 行を削除する

EFA サポートを追加する

included-packageskmod-6.18-efa を追加する

コンテナランタイムバージョンを切り替える

containerd-2.2containerd-2.1

利用可能なパッケージの詳細については、GitHub ウェブサイトの「kernel-kit」と GitHub ウェブサイトの「core-kit」を参照してください。

重要

Bottlerocket ルートファイルシステムはイミュータブルです。ランタイム時にパッケージをインストールすることはできません。キット内のすべてのパッケージは、Bottlerocket 専用にクロスコンパイルされています。標準のアップストリーム RPM は機能しません。キットにまだ含まれていないソフトウェアが必要な場合は、ランタイムの代替手段として、GitHub ウェブサイトの「ブートストラップコンテナ」または GitHub ウェブサイトの「ホストコンテナ」を検討してください。

クリーンアップ

ビルドホストが不要になった場合は、継続的な料金が発生しないように EC2 インスタンスを終了してください。AMI はアカウント内で個別に保持されます。不要になった場合は EC2 コンソールまたは CLI で登録解除します。

概要

このトピックでは、別の NVIDIA ドライバーブランチを使用してカスタム Bottlerocket バリアントを作成する方法を示しました。このプロセスには、既存のバリアントのコピー、1 つのパッケージ参照の変更、ワークスペースと RPM 仕様への新しいバリアントの登録、およびビルドの実行が含まれます。カーネルバージョンの切り替え、パッケージの追加、新しい Kubernetes リリース向けのバリアントの作成など、あらゆるカスタマイズに同じアプローチが適用されます。