View a markdown version of this page

Creación de una variante de AMI de Bottlerocket personalizada para Amazon EKS - Amazon EKS

Ayude a mejorar esta página

Para contribuir a esta guía del usuario, elija el enlace Edit this page on GitHub que se encuentra en el panel derecho de cada página.

Creación de una variante de AMI de Bottlerocket personalizada para Amazon EKS

Al ejecutar cargas de trabajo de GPU en Amazon Elastic Kubernetes Service (Amazon EKS), elija una variante de Bottlerocket. La variante debe coincidir con la versión de Kubernetes y el tipo de acelerador. Bottlerocket envía variantes validadas para las configuraciones comunes. Sin embargo, es posible que su organización necesite una variante distinta por cualquiera de los siguientes motivos:

  • Una ramificación de controladores de NVIDIA más reciente

  • Una versión de controlador fija para cumplir con la normativa

  • Paquetes adicionales para la supervisión

  • Una línea de base sólida que su equipo de seguridad necesita

Como Bottlerocket en el sitio web de GitHub es completamente de código abierto, puede crear una variante personalizada que satisfaga estas necesidades. En este tema, se muestra cómo clonar una variante existente y cambiar el controlador de NVIDIA de la ramificación R580 a la R595 (versión 595.71.05). A continuación, se crea la imagen y se registra como una AMI privada.

importante

El tipo de instancia de EC2 G7 requiere la versión 595 o posterior del controlador de NVIDIA. Las AMI de NVIDIA de Bottlerocket de EKS incluyen actualmente la versión 580 del controlador de NVIDIA, que no es compatible con las instancias G7.

Consulte el repositorio de Bottlerocket en el sitio web de GitHub para obtener instrucciones sobre cómo crear una variante con la versión 595 del controlador de NVIDIA. En este tema, se explica todo el proceso a partir del paso 1.

Cómo funciona el sistema de creación

Al ejecutar cargo make -e BUILDSYS_VARIANT=aws-k8s-1.36-nvidia, suceden tres cosas:

  • Extracción de dependencias. Twoliter (el orquestador de creación de Bottlerocket) lee Twoliter.toml y extrae tres artefactos de Open Container Initiative (OCI) de public.ecr.aws/bottlerocket:

    • bottlerocket-sdk: una imagen de contenedor con toda la cadena de herramientas de compilación cruzada (macros de RMP, Go, Rust y GCC).

    • bottlerocket-kernel-kit: RPM prediseñados para kernels, módulos de kernel (incluidos los paquetes kmod de NVIDIA) y firmware.

    • bottlerocket-core-kit: RPM prediseñados para el espacio de usuario: kubelet, containerd, el complemento para dispositivos y el kit de herramientas para contenedores de NVIDIA, complementos de configuración y servicios del sistema.

      Twoliter.toml fija las versiones y Twoliter.lock bloquea sus resúmenes. Para cambiarlos, ejecute ./tools/twoliter/twoliter update para volver a resolverlos.

  • Creación de la variante. Twoliter lanza una compilación de Docker dentro del contenedor del SDK. Compila la caja de configuración predeterminada de la variante, resuelve el árbol de dependencias de RPM de los kits y lo ensambla todo en una imagen de disco.

  • Salida. Twoliter escribe el archivo .img.lz4 final en build/images/. La compilación produce una salida determinista: los mismos pines de Twoliter.toml y la misma variante de Cargo.toml siempre generan la misma imagen, independientemente del host.

Diseño del repositorio

Los siguientes directorios son pertinentes para el trabajo con variantes:

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

Revise las siguientes notas sobre la estructura del repositorio:

  • Una variante consiste principalmente en metadatos. Los kits externos proporcionan el kernel, los controladores y el espacio de usuario.

  • Los archivos de valores predeterminados de configuración son symlinks, no copias. Utilice cp -R (no cp -r en macOS) para conservarlos.

  • Para agregar una variante, es necesario llevar a cabo ediciones en cinco lugares: dos archivos Cargo.toml del espacio de trabajo, dos archivos .spec y README.md.

Requisitos previos

Para completar este tutorial, necesitará lo siguiente:

  • Una cuenta de AWS con permisos para lanzar instancias de EC2 y registrar AMI

  • Una instancia de EC2 (o un host de Linux x86_64 equivalente) con al menos 8 núcleos, 16 GiB de memoria y 150 GB de disco

  • Ubuntu 24.04 LTS (o Fedora; macOS no es compatible como host de compilación)

  • Docker 20.10 o posterior

  • Rust (cadena de herramientas estable, instalada mediante rustup)

  • cargo-make (versión más reciente)

  • Familiaridad con los conceptos de empaquetado de Git, Cargo de Rust y RPM

nota

Cuando complete este tutorial, termine la instancia de EC2 y anule el registro de cualquier AMI que ya no necesite para evitar cargos continuos. Para obtener instrucciones sobre la limpieza, consulte Limpieza.

Paso 1: preparación del host de compilación

Lance una instancia de EC2, por ejemplo, c7i.8xlarge (32 vCPU, 64 GiB de memoria). Utilice un volumen raíz gp3 de 150 GB y adjunte la política administrada AmazonSSMManagedInstanceCore para el acceso a SSM.

Conéctese a la instancia mediante el Administrador de sesiones de AWS Systems Manager (SSM):

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

Instale los paquetes del sistema operativo obligatorios:

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

El archivo BUILDING.md oficial hace referencia a liblz4-tool. En las versiones recientes de Ubuntu, el paquete se llama lz4.

Instale Docker con los siguientes comandos:

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

Instale Rust y cargo-make con los siguientes comandos:

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

Paso 2: Clonar el repositorio

Clone el repositorio de Bottlerocket del sitio web de GitHub y vaya al directorio:

cd ~/bottlerocket

Para crear una compilación reproducible, consulte una versión etiquetada (por ejemplo, git checkout v1.62.1). Para usar los paquetes más recientes, permanezca en la ramificación develop.

Paso 3: verificación de las versiones del kit

Abra Twoliter.toml y confirme las versiones del kit. Para que sea compatible con R595, necesita la versión 6.2.2 o posterior de bottlerocket-kernel-kit:

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

Si la versión es anterior, actualízala y vuelva a generar el bloqueo:

./tools/twoliter/twoliter update

Paso 4: solución del problema de ruta de cargo-make

Twoliter establece CARGO_HOME en ~/bottlerocket/.cargo, lo que evita que el proceso interno de Cargo encuentre el cargo-make instalado globalmente. Cree un enlace simbólico

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

Sin este paso, la compilación falla con el error: no such command: make.

Paso 5: búsqueda de las ramificaciones de controladores disponibles

Los paquetes kmod de NVIDIA se incluyen dentro de bottlerocket-kernel-kit. Para obtener información sobre los paquetes de controladores disponibles, consulte el directorio de paquetes de kernel-kit en el sitio web de GitHub o las notas de la versión en el sitio web de GitHub.

Para el kernel 6.18 (usado por las variantes aws-k8s-1.36):

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

Para el kernel 6.12 (usado por aws-k8s-1.33, 1.34, 1.35):

kmod-6.12-nvidia-r580 kmod-6.12-nvidia-r595
nota

Cada paquete kmod envía subpaquetes (-tesla, -open-gpu, -grid, -fabricmanager, -imex). Las variantes de NVIDIA de Bottlerocket oficiales hacen referencia a -tesla, que incluye todos los subpaquetes necesarios mediante dependencias de RPM. Al arrancar, Bottlerocket selecciona automáticamente el tipo de controlador adecuado en función del tipo de instancia.

Paso 6: creación de la nueva variante

Copie la variante existente. Utilice cp -R para conservar los symlinks:

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

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

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

Paso 7: registro de la variante

Registre la nueva variante en cinco archivos:

1. Cargo.toml, agregue el miembro del espacio de trabajo:

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

2. sources/Cargo.toml, agregue el miembro de settings-defaults:

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

3. packages/settings-defaults/settings-defaults.spec, agregue un bloque %package, entradas en ambos bucles de compilación y una sección %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}.

Agregue lo siguiente a ambos bucles for defaults in:

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

Agregue la sección %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, agregue una línea Provides: debajo de %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)

Paso 8: actualización del archivo de bloqueo

Al agregar un miembro del espacio de trabajo, se invalida sources/Cargo.lock. Actualícelo:

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

No utilice cargo generate-lockfile. Reescribe todo el archivo de bloqueo y aumenta las dependencias transitivas, lo que provoca errores de versiones duplicadas de cargo-deny.

Paso 9: creación del archivo de licencia de NVIDIA

NVIDIA restringe la redistribución de los orígenes de los controladores. Debe agregar una confirmación de licencia explícita antes de compilar:

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

Paso 10: creación y publicación de la AMI

Cree Infra.toml con las regiones de destino:

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

Compile la imagen:

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

La primera compilación extrae las imágenes del SDK y del kit (aproximadamente 2 GB en total). Las compilaciones posteriores tardan entre 3 y 5 minutos en un host de 32 núcleos.

Publique la 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

La compilación escribe los ID de AMI en build/images/x86_64-aws-k8s-1.36-nvidia-595/latest/*-amis.json. Úselos en los grupos de nodos administrados de EKS, en EC2NodeClass de Karpenter o en las plantillas de lanzamiento.

Otras combinaciones que puede compilar

Este tutorial cambia la ramificación de controladores de NVIDIA, pero puede usar el mismo enfoque para cualquier paquete disponible en los kits originales. En los siguientes ejemplos, se muestra lo que se puede ensamblar sin necesidad de bifurcar un kit:

Qué desea Qué cambiar en Cargo.toml de la variante

Diferente ramificación de controladores de NVIDIA

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

Versión del kernel diferente

kernel-6.18kernel-6.12 (ajuste kmod en consecuencia)

Eliminación de NVIDIA por completo

Eliminación de las tres líneas nvidia-* de included-packages

Agregación de compatibilidad con EFA

Agregación de kmod-6.18-efa a included-packages.

Cambio de la versión en tiempo de ejecución del contenedor

containerd-2.2containerd-2.1

Para obtener información sobre los paquetes de controladores disponibles, consulte kernel-kit en el sitio web de GitHub o core-kit en el sitio web de GitHub.

importante

El sistema de archivos raíz de Bottlerocket es inmutable. No puede instalar paquetes en tiempo de ejecución. Todos los paquetes de los kits se compilan de forma cruzada específicamente para Bottlerocket; los RPM ascendentes estándar no funcionan. Si necesita un software que aún no se ha incluido en un kit, considere la posibilidad de utilizar usar contenedores de arranque del sitio web de GitHub o contenedores de host del sitio web de GitHub como alternativa de tiempo de ejecución.

Limpieza

Si ya no necesita el host de compilación, termine la instancia de EC2 para evitar cargos continuos. Las AMI persisten de forma independiente en su cuenta: anule su registro con la consola de EC2 o la CLI si ya no las necesita.

Resumen

En este tema, se muestra cómo crear una variante de Bottlerocket personalizada con una ramificación de controladores de NVIDIA diferente. El proceso implica copiar una variante existente, cambiar la referencia de un paquete, registrar la nueva variante en el espacio de trabajo y en las especificaciones de RPM y ejecutar la compilación. El mismo enfoque se aplica a cualquier personalización: cambio de versiones del kernel, adición de paquetes o creación de variantes para nuevas versiones de Kubernetes.