このページの改善にご協力ください
このユーザーガイドに貢献するには、すべてのページの右側のペインにある「GitHub でこのページを編集する」リンクを選択してください。
Amazon EKS 用のカスタム Bottlerocket AMI バリアントを構築する
Amazon Elastic Kubernetes Service (Amazon EKS) で GPU ワークロードを実行する場合は、Bottlerocket バリアントを選択します。バリアントは、Kubernetes バージョンとアクセラレータータイプと一致する必要があります。Bottlerocket は、一般的な設定用に検証済みバリアントを提供します。ただし、次のいずれかの理由により、組織で別のバリアントが必要になる可能性があります:
-
新しい NVIDIA ドライバーブランチ
-
規制コンプライアンスのためのピン留めされたドライバーバージョン
-
モニタリング用の追加パッケージ
-
セキュリティチームが必要とする強化されたベースライン
GitHub ウェブサイトの Bottlerocket
重要
G7 EC2 インスタンスタイプには NVIDIA ドライバーバージョン 595 以降が必要です。EKS Bottlerocket NVIDIA AMI には現在、G7 インスタンスをサポートしていない NVIDIA ドライバーバージョン 580 が含まれています。
NVIDIA ドライバーバージョン 595 でバリアントを構築する手順については、GitHub ウェブサイトの「Bottlerocket リポジトリ
ビルドシステムの仕組み
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.md は liblz4-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 パッケージディレクトリ
カーネル 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.33、1.34、1.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 ドライバーブランチ |
|
|
異なるカーネルバージョン |
|
|
NVIDIA を完全に削除する |
|
|
EFA サポートを追加する |
|
|
コンテナランタイムバージョンを切り替える |
|
利用可能なパッケージの詳細については、GitHub ウェブサイトの「kernel-kit
重要
Bottlerocket ルートファイルシステムはイミュータブルです。ランタイム時にパッケージをインストールすることはできません。キット内のすべてのパッケージは、Bottlerocket 専用にクロスコンパイルされています。標準のアップストリーム RPM は機能しません。キットにまだ含まれていないソフトウェアが必要な場合は、ランタイムの代替手段として、GitHub ウェブサイトの「ブートストラップコンテナ
クリーンアップ
ビルドホストが不要になった場合は、継続的な料金が発生しないように EC2 インスタンスを終了してください。AMI はアカウント内で個別に保持されます。不要になった場合は EC2 コンソールまたは CLI で登録解除します。
概要
このトピックでは、別の NVIDIA ドライバーブランチを使用してカスタム Bottlerocket バリアントを作成する方法を示しました。このプロセスには、既存のバリアントのコピー、1 つのパッケージ参照の変更、ワークスペースと RPM 仕様への新しいバリアントの登録、およびビルドの実行が含まれます。カーネルバージョンの切り替え、パッケージの追加、新しい Kubernetes リリース向けのバリアントの作成など、あらゆるカスタマイズに同じアプローチが適用されます。