

 **協助改進此頁面** 

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

若要為本使用者指南貢獻內容，請點選每個頁面右側面板中的**在 GitHub 上編輯此頁面**連結。

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 為 Amazon EKS 建置自訂 Bottlerocket AMI 變體
<a name="bottlerocket-custom-variant"></a>

當您在 Amazon Elastic Kubernetes Service (Amazon EKS) 上執行 GPU 工作負載時，您可以選擇 Bottlerocket 變體。變體必須符合您的 Kubernetes 版本和加速器類型。Bottlerocket 為常見組態提供經過驗證的變體。不過，您的組織可能因下列任何原因而需要不同的變體：
+ 較新的 NVIDIA 驅動程式分支
+ 符合法規的固定驅動程式版本
+ 用於監控的其他套件
+ 安全團隊所需的強化基準

由於 GitHub 網站上的 [Bottlerocket](https://github.com/bottlerocket-os/bottlerocket) 是完全開放原始碼，因此您可以建立符合這些需求的自訂變體。本主題說明如何複製現有的變體，並將 NVIDIA 驅動程式從 R580 分支交換為 R595 (595.71.05 版）。然後，您可以建置映像並將其註冊為私有 AMI。

**重要**  
G7 EC2 執行個體類型需要 NVIDIA 驅動程式 595 版或更新版本。EKS Bottlerocket NVIDIA AMIs 目前包含不支援 G7 執行個體的 NVIDIA 驅動程式 580 版。  
如需使用 NVIDIA 驅動程式 595 版建置變體的說明，請參閱 GitHub 網站上的 [Bottlerocket 儲存庫](https://github.com/bottlerocket-os/bottlerocket)。本主題會逐步解說從[步驟 1 ](#bottlerocket-custom-variant-step1)開始的完整程序。

## 建置系統的運作方式
<a name="bottlerocket-custom-variant-build-system"></a>

當您執行 時`cargo make -e BUILDSYS_VARIANT=aws-k8s-1.36-nvidia`，會發生三件事：
+  **擷取相依性。**Twoliter ( Bottlerocket 組建協調器） 會從 讀取`Twoliter.toml`和提取三個開放容器計畫 (OCI) 成品`public.ecr.aws/bottlerocket`：
  +  **bottlerocket-sdk** — 具有完整跨編譯工具鏈 (GCC、Rust、Go、RPM 巨集） 的容器映像。
  +  **bottlerocket-kernel-kit** — 適用於核心、核心模組 （包括 NVIDIA kmod 套件） 和韌體的預先建置 RPMs。
  +  **bottlerocket-core-kit**：預先建置的使用者空間 RPMs：kubelet、 containerd、NVIDIA 裝置外掛程式和容器工具組、設定外掛程式和系統服務。

     `Twoliter.toml` 釘選版本並`Twoliter.lock`鎖定其摘要。若要變更其中一項，請執行 `./tools/twoliter/twoliter update`以重新解決。
+  **建置 變體。**Twoliter 會在 SDK 容器內啟動 Docker 組建。它會編譯變體的設定預設木箱、從套件解析 RPM 相依性樹狀結構，並將所有項目組合成磁碟映像。
+  **輸出。**Twoliter 會將最終`.img.lz4`檔案寫入 `build/images/`。建置會產生決定性輸出：無論主機為何，相同的`Twoliter.toml`接腳和變體`Cargo.toml`一律會產生相同的映像。

## 儲存庫配置
<a name="bottlerocket-custom-variant-repo-layout"></a>

下列目錄與變體工作相關：

```
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`上） 來保留它們。
+ 新增變體需要編輯五個位置：兩個工作區`Cargo.toml`檔案、兩個`.spec`檔案和 `README.md`。

## 先決條件
<a name="bottlerocket-custom-variant-prereqs"></a>

若要完成演練，您需要：
+ 具有啟動 EC2 執行個體和註冊 AMIs許可 AWS 的帳戶
+ 具有至少 8 個核心、16 GiB 記憶體和 150 GB 磁碟的 EC2 執行個體 （或同等 Linux x86\_64 主機）
+ Ubuntu 24.04 LTS （或 Fedora；不支援 macOS 做為建置主機）
+ Docker 20.10 或更新版本
+ Rust （穩定工具鏈，透過 rustup 安裝）
+ 貨物製造 （最新版本）
+ 熟悉 Git、Rust 的 Cargo 和 RPM 封裝概念

**注意**  
當您完成本演練時，請終止 EC2 執行個體並取消註冊任何不再需要的 AMIs，以避免持續收費。如需清除的指示，請參閱 [清除](#bottlerocket-custom-variant-cleanup)。

## 步驟 1：準備建置主機
<a name="bottlerocket-custom-variant-step1"></a>

啟動 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：複製儲存庫
<a name="bottlerocket-custom-variant-step2"></a>

複製 GitHub 網站上的 [Bottlerocket 儲存庫](https://github.com/bottlerocket-os/bottlerocket)並導覽至 目錄：

```
cd ~/bottlerocket
```

若要建立可重現的組建，請查看已標記的版本 （例如 `git checkout v1.62.1`)。若要使用最新的套件，請保留在`develop`分支上。

## 步驟 3：驗證套件版本
<a name="bottlerocket-custom-variant-step3"></a>

開啟`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：解決貨物製造路徑問題
<a name="bottlerocket-custom-variant-step4"></a>

兩升`CARGO_HOME`設定為 `~/bottlerocket/.cargo`，可防止內部貨運程序尋找您全域安裝的貨運製造。創建 symlink：

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

如果沒有此步驟，建置會失敗並顯示 `error: no such command: make`。

## 步驟 5：尋找可用的驅動程式分支
<a name="bottlerocket-custom-variant-step5"></a>

NVIDIA kmod 套件會在 內運送`bottlerocket-kernel-kit`。如需可用驅動程式套件的相關資訊，請參閱 GitHub 網站上的[核心套件目錄](https://github.com/bottlerocket-os/bottlerocket-kernel-kit)，或 GitHub 網站上的[版本備註](https://github.com/bottlerocket-os/bottlerocket-kernel-kit/releases)。

對於核心 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：建立新的變體
<a name="bottlerocket-custom-variant-step6"></a>

複製現有的變體。使用 `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：註冊變體
<a name="bottlerocket-custom-variant-step7"></a>

在五個檔案中註冊新的變體：

 **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` ** — 在建置迴圈和`%files`區段中新增`%package`區塊、項目：

```
%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` ** — 在 下新增一`Provides:`行`%package aws-k8s-nvidia`：

```
 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：重新整理 lockfile
<a name="bottlerocket-custom-variant-step8"></a>

新增工作區成員會使 失效`sources/Cargo.lock`。重新整理它：

```
cd ~/bottlerocket/sources
cargo update --workspace
```

**重要**  
請勿使用 `cargo generate-lockfile`。它會重寫整個 lockfile 並碰撞傳輸相依性，這會導致`cargo-deny`重複版本錯誤。

## 步驟 9：建立 NVIDIA 授權檔案
<a name="bottlerocket-custom-variant-step9"></a>

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
<a name="bottlerocket-custom-variant-step10"></a>

`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 IDs寫入 `build/images/x86_64-aws-k8s-1.36-nvidia-595/latest/*-amis.json`。在 EKS 受管節點群組、Karpenter `EC2NodeClass`或啟動範本中使用這些節點群組。

## 您可以建置的其他組合
<a name="bottlerocket-custom-variant-other-combinations"></a>

此演練會交換 NVIDIA 驅動程式分支，但您可以針對上游套件中提供的任何套件使用相同的方法。下列範例顯示您可以組裝哪些項目，而無需偽造套件：


| 您想要的內容 | 變體中的變更內容 `Cargo.toml`  | 
| --- | --- | 
| 不同的 NVIDIA 驅動程式分支 |  `kmod-6.18-nvidia-r580-tesla` → `kmod-6.18-nvidia-r595-tesla`  | 
| 不同的核心版本 |  `kernel-6.18` → `kernel-6.12`（相應地調整 kmod) | 
| 完全移除 NVIDIA | 從 刪除三`nvidia-*`行 `included-packages`  | 
| 新增 EFA 支援 | `kmod-6.18-efa` 新增至 `included-packages`  | 
| 切換容器執行時間版本 |  `containerd-2.2` → `containerd-2.1`  | 

如需可用套件的相關資訊，請參閱 GitHub 網站上的 [kernel-kit](https://github.com/bottlerocket-os/bottlerocket-kernel-kit) 和 GitHub 網站上的 [core-kit](https://github.com/bottlerocket-os/bottlerocket-core-kit)。

**重要**  
Bottlerocket 根檔案系統不可變。您無法在執行時間安裝套件。套件中的每個套件都是專門針對 Bottlerocket 進行交叉編譯，標準上游 RPMs無法運作。如果您需要尚未在套件中的軟體，請考慮使用 GitHub 網站上的[引導容器](https://github.com/bottlerocket-os/bottlerocket#bootstrap-containers-settings)或 GitHub 網站上的[主機容器](https://github.com/bottlerocket-os/bottlerocket#host-containers)作為執行期替代方案。

## 清除
<a name="bottlerocket-custom-variant-cleanup"></a>

如果您不再需要建置主機，請終止 EC2 執行個體以避免持續收費。AMIs 會獨立保留在您的帳戶中；如果您不再需要，請透過 EC2 主控台或 CLI 取消註冊這些 AMI。

## 摘要
<a name="bottlerocket-custom-variant-summary"></a>

本主題說明如何使用不同的 NVIDIA 驅動程式分支建立自訂 Bottlerocket 變體。此程序涉及複製現有的變體、變更一個套件參考、在工作區和 RPM 規格中註冊新的變體，以及執行建置。相同的方法適用於任何自訂：交換核心版本、新增套件，或為新的 Kubernetes 版本建立變體。