Ajudar a melhorar esta página
Para contribuir com este guia de usuário, escolha o link Editar esta página no GitHub, disponível no painel direito de cada página.
Criar uma variante personalizada da AMI Bottlerocket para o Amazon EKS
Ao executar workloads de GPU no Amazon Elastic Kubernetes Service (Amazon EKS), você escolhe uma variante do Bottlerocket. A variante deve corresponder à sua versão do Kubernetes e ao tipo de acelerador. O Bottlerocket oferece nativamente variantes validadas para configurações comuns. No entanto, sua organização pode precisar de uma variante diferente por qualquer um dos seguintes motivos:
-
Uma ramificação mais recente de drivers da NVIDIA
-
Uma versão fixa de driver para conformidade regulatória
-
Pacotes adicionais para monitoramento
-
Uma linha de base reforçada exigida por sua equipe de segurança
Como o Bottlerocket
Importante
O tipo de instância G7 do EC2 requer a versão 595 ou posterior do driver NVIDIA. Atualmente, as AMIs Bottlerocket NVIDIA para EKS incluem a versão 580 do driver NVIDIA, que não é compatível com instâncias G7.
Consulte o repositório do Bottlerocket
Como o sistema de compilação funciona
Quando você executa cargo make -e BUILDSYS_VARIANT=aws-k8s-1.36-nvidia, ocorrem três coisas:
-
Busca dependências. O Twoliter (o orquestrador de compilação do Bottlerocket) lê
Twoliter.tomle extrai três artefatos da Open Container Initiative (OCI) depublic.ecr.aws/bottlerocket:-
bottlerocket-sdk: uma imagem de contêiner com a cadeia de ferramentas de compilação cruzada completa (GCC, Rust, Go, macros RPM).
-
bottlerocket-kernel-kit: RPMs pré-compilados para kernels, módulos de kernel (incluindo pacotes kmod da NVIDIA) e firmware.
-
bottlerocket-core-kit: RPMs pré-compilados para o espaço do usuário: kubelet, containerd, plug-in de dispositivo e kit de ferramentas de contêineres da NVIDIA, plug-ins de configurações e serviços do sistema.
O
Twoliter.tomlfixa as versões e oTwoliter.lockbloqueia seus resumos. Para alterar qualquer um deles, execute./tools/twoliter/twoliter updatepara resolver novamente.
-
-
Cria a variante. O Twoliter inicializa uma compilação do Docker dentro do contêiner do SDK. Ele compila a crate settings-defaults da sua variante, resolve a árvore de dependências RPM dos kits e monta tudo em uma imagem de disco.
-
Saída. O Twoliter grava o arquivo final
.img.lz4embuild/images/. A compilação produz uma saída determinística: as mesmas fixaçõesTwoliter.tomle oCargo.tomlda variante sempre geram a mesma imagem, independentemente do host.
Layout do repositório
Os seguintes diretórios são relevantes para o trabalho de 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
Analise as seguintes observações sobre a estrutura do repositório:
-
Uma variante consiste principalmente em metadados. Os kits externos fornecem o kernel, os drivers e o espaço do usuário.
-
Os arquivos settings-defaults são links simbólicos, não cópias. Use
cp -R(nãocp -rno macOS) para preservá-los. -
Adicionar uma variante requer edições em cinco lugares: dois arquivos
Cargo.tomldo espaço de trabalho, dois arquivos.speceREADME.md.
Pré-requisitos
Para concluir este passo a passo, você precisa de:
-
Uma conta da AWS com permissões para inicializar instâncias do EC2 e registrar AMIs
-
Uma instância do EC2 (ou um host Linux x86_64 equivalente) com pelo menos 8 núcleos, 16 GiB de memória e 150 GB de disco
-
Ubuntu 24.04 LTS (ou Fedora; o macOS não é compatível como host de compilação)
-
Docker 20.10 ou posterior
-
Rust (cadeia de ferramentas estável, instalada via rustup)
-
cargo-make (versão mais recente)
-
Familiaridade com Git, o Cargo do Rust e conceitos de empacotamento RPM
nota
Ao concluir este passo a passo, encerre a instância do EC2 e cancele o registro de todas as AMIs de que você não precisa mais para evitar cobranças contínuas. Para obter instruções de limpeza, consulte Liberar.
Etapa 1: preparar o host de compilação
Inicialize uma instância do EC2: por exemplo, uma c7i.8xlarge (32 vCPU, 64 GiB de memória). Use um volume raiz gp3 de 150 GB e anexe a política gerenciada AmazonSSMManagedInstanceCore para acesso do SSM.
Conecte-se à instância usando o Gerenciador de Sessões do AWS Systems Manager (SSM):
aws ssm start-session --target <instance-id> cd ~
Instale os pacotes necessários do sistema operacional:
apt-get update apt-get install -y build-essential openssl libssl-dev pkg-config lz4 \ git ca-certificates curl gnupg
nota
O BUILDING.md oficial faz referência ao liblz4-tool. Nas versões recentes do Ubuntu, o pacote é denominado lz4.
Instale o Docker usando os seguintes 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 o Rust e o cargo-make usando os seguintes comandos:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y . "$HOME/.cargo/env" cargo install cargo-make
Etapa 2: clonar o repositório
Clone o repositório do Bottlerocket
cd ~/bottlerocket
Para criar uma compilação reproduzível, confira uma versão marcada (por exemplo, git checkout v1.62.1). Para usar os pacotes mais recentes, permaneça na ramificação develop.
Etapa 3: verificar as versões dos kits
Abra Twoliter.toml e confirme as versões dos kits. Para compatibilidade com o R595, você precisa da versão 6.2.2 ou posterior do bottlerocket-kernel-kit:
[[kit]] name = "bottlerocket-kernel-kit" version = "6.2.2" vendor = "bottlerocket"
Se a versão for mais antiga, atualize-a e gere o bloqueio novamente:
./tools/twoliter/twoliter update
Etapa 4: contornar o problema de caminho do cargo-make
O Twoliter define CARGO_HOME como ~/bottlerocket/.cargo, o que impede que o processo interno do Cargo encontre o cargo-make instalado globalmente. Criar um symlink:
mkdir -p ~/bottlerocket/.cargo/bin ln -sf /root/.cargo/bin/cargo-make ~/bottlerocket/.cargo/bin/cargo-make
Sem essa etapa, a compilação falhará com error: no such command: make.
Etapa 5: encontrar ramificações de driver disponíveis
Os pacotes kmod da NVIDIA são disponibilizados dentro do bottlerocket-kernel-kit. Para obter informações sobre os pacotes de drivers disponíveis, consulte o diretório de pacotes do kernel-kit
Para o kernel 6.18 (usado por 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 o 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 pacote kmod disponibiliza subpacotes (-tesla, -open-gpu, -grid, -fabricmanager, -imex). As variantes oficiais NVIDIA do Bottlerocket fazem referência ao -tesla, que inclui todos os subpacotes necessários por meio de dependências RPM. Durante a inicialização, o Bottlerocket seleciona automaticamente o tipo de driver apropriado com base no tipo de instância.
Etapa 6: criar a nova variante
Copie a variante existente. Use cp -R para preservar os links simbólicos:
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 o 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 o 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"
Etapa 7: registrar a variante
Registre a nova variante em cinco arquivos:
1. Cargo.toml : adicione o membro do espaço de trabalho:
"variants/aws-k8s-1.36-nvidia", + "variants/aws-k8s-1.36-nvidia-595", "variants/aws-k8s-1.36-nvidia-fips",
2. sources/Cargo.toml : adicione o membro settings-defaults:
"settings-defaults/aws-k8s-1.36-nvidia", + "settings-defaults/aws-k8s-1.36-nvidia-595",
3. packages/settings-defaults/settings-defaults.spec : adicione um bloco %package, entradas nos dois loops de compilação e uma seção %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}.
Adicione aos dois loops for defaults in:
aws-k8s-1.36-nvidia \ + aws-k8s-1.36-nvidia-595 \ metal-dev \
Adicione a seção %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 : adicione uma linha Provides: abaixo 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)
Etapa 8: atualizar o arquivo de bloqueio
Adicionar um membro do espaço de trabalho invalida o sources/Cargo.lock. Atualize-o:
cd ~/bottlerocket/sources cargo update --workspace
Importante
Não use o cargo generate-lockfile. Ele reescreve todo o arquivo de bloqueio e incrementa as versões das dependências transitivas, o que causa erros de versão duplicada no cargo-deny.
Etapa 9: criar o arquivo de licença da NVIDIA
A NVIDIA restringe a redistribuição das fontes de drivers. Você deve adicionar uma confirmação explícita da licença 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
Etapa 10: compilar e publicar a AMI
Crie um Infra.toml com suas regiões de destino:
cat > ~/bottlerocket/Infra.toml <<'EOF' [aws] regions = ["us-west-2", "us-east-1", "us-east-2"] EOF
Compilar a imagem:
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
A primeira compilação extrai as imagens do SDK e do kit (aproximadamente 2 GB no total). As compilações subsequentes levam de 3 a 5 minutos em um host de 32 núcleos.
Publicar a 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
A compilação grava os IDs das AMIs em build/images/x86_64-aws-k8s-1.36-nvidia-595/latest/*-amis.json. Use-os em seus grupos de nós gerenciados pelo EKS, no EC2NodeClass do Karpenter ou em modelos de inicialização.
Outras combinações que você pode compilar
Este passo a passo troca a ramificação do driver NVIDIA, mas você pode usar a mesma abordagem para qualquer pacote disponível nos kits upstream. Os seguintes exemplos mostram o que você pode montar sem bifurcar um kit:
| O que você quer | O que alterar no Cargo.toml da variante |
|---|---|
|
Outra ramificação de driver NVIDIA |
|
|
Outra versão do kernel |
|
|
Remover o NVIDIA por completo |
Exclua as três linhas |
|
Adicionar suporte ao EFA |
Adicionar |
|
Alternar a versão do runtime do container |
|
Para obter informações sobre os pacotes disponíveis, consulte o kernel-kit
Importante
O sistema de arquivos raiz do Bottlerocket é imutável. Você não pode instalar pacotes no runtime. Cada pacote nos kits é compilado de forma cruzada especificamente para o Bottlerocket. Os RPMs upstream padrão não funcionam. Se você precisar de um software que ainda não esteja em um kit, considere os contêineres bootstrap
Liberar
Se você não precisar mais do host de compilação, encerre a instância do EC2 para evitar cobranças contínuas. As AMIs persistem de forma independente em sua conta; cancele o registro delas no console do EC2 ou na CLI se você não precisar mais delas.
Resumo
Este tópico mostrou como criar uma variante personalizada do Bottlerocket com outra ramificação do driver NVIDIA. O processo envolve copiar uma variante existente, alterar uma referência de pacote, registrar a nova variante no espaço de trabalho e nas especificações RPM e executar a compilação. A mesma abordagem se aplica a qualquer customização: trocar versões do kernel, adicionar pacotes ou criar variantes para novas versões do Kubernetes.