이 페이지 개선에 도움 주기
이 사용자 가이드에 기여하려면 모든 페이지의 오른쪽 창에 있는 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 repository
빌드 시스템의 작동 방식
cargo make -e BUILDSYS_VARIANT=aws-k8s-1.36-nvidia를 실행하면 다음 세 가지 상황이 발생합니다.
-
종속성 가져오기 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 - kubelet, Containered, NVIDIA 디바이스 플러그인 및 컨테이너 도구 키트, 설정 플러그인 및 시스템 서비스 등 사용자 공간을 위해 사전 빌드된 RPM입니다.
Twoliter.toml은 버전을 고정하고Twoliter.lock은 해당 다이제스트를 잠급니다. 둘 중 하나를 변경하려면./tools/twoliter/twoliter update를 실행하여 다시 확인합니다.
-
-
변형을 빌드합니다. Twoliter는 SDK 컨테이너 내에서 Docker 빌드를 시작합니다. 변형의 settings-defaults 크레이트를 컴파일하고, 키트에서 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 파일은 복사본이 아닌 symlink입니다.
cp -R(macOS의cp -r이 아님)을 사용하여 해당 파일을 보존합니다. -
변형을 추가하려면 워크스페이스
Cargo.toml파일 2개,.spec파일 2개,README.md의 5개 위치에서 편집해야 합니다.
사전 조건
이 연습을 수행하려면 다음이 있어야 합니다.
-
EC2 인스턴스 시작 및 AMI 등록 권한이 있는 AWS 계정
-
최소 8개 코어, 16GiB 메모리 및 150GB 디스크가 있는 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, 64GiB 메모리). 150GB 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 packages directory
커널 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 변형은 RPM 종속성을 통해 필요한 모든 하위 패키지를 가져오는 -tesla를 참조합니다. 부팅 시 Bottlerocket은 인스턴스 유형에 따라 적절한 드라이버 종류를 자동으로 선택합니다.
6단계: 새 변형 생성
기존 변형을 복사합니다. cp -R을 사용하여 symlink를 보존합니다.
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 및 키트 이미지(총 약 2GB)를 가져옵니다. 이후 빌드는 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 또는 시작 템플릿에서 이 ID를 사용합니다.
빌드할 수 있는 기타 조합
이 연습에서는 NVIDIA 드라이버 브랜치를 교체하지만, 업스트림 키트에서 사용할 수 있는 모든 패키지에 동일한 접근 방식을 사용할 수 있습니다. 다음 예제에서는 키트를 포크하지 않고 어셈블할 수 있는 것을 보여줍니다.
| 원하는 사항 | 변형 Cargo.toml에서 변경할 사항 |
|---|---|
|
다른 NVIDIA 드라이버 브랜치 |
|
|
다른 커널 버전 |
|
|
NVIDIA를 완전히 제거 |
|
|
EFA 지원 추가 |
|
|
컨테이너 런타임 버전 전환 |
|
사용 가능한 패키지에 대한 자세한 내용은 GitHub 웹사이트의 kernel-kit
중요
Bottlerocket 루트 파일 시스템은 변경할 수 없습니다. 런타임에는 패키지를 설치할 수 없습니다. 키트의 모든 패키지는 Bottlerocket 전용으로 크로스 컴파일됩니다. 표준 업스트림 RPM은 작동하지 않습니다. 아직 키트에 없는 소프트웨어가 필요한 경우 런타임 대안으로 GitHub 웹사이트의 부트스트랩 컨테이너
정리
빌드 호스트가 더 이상 필요하지 않은 경우 지속적 요금이 부과되지 않도록 EC2 인스턴스를 종료합니다. AMI는 계정에서 독립적으로 유지되며 더 이상 필요하지 않은 경우 EC2 콘솔 또는 CLI에서 등록을 취소합니다.
요약
이 주제에서는 다른 NVIDIA 드라이버 브랜치를 사용하여 사용자 지정 Bottlerocket 변형을 생성하는 방법을 설명했습니다. 이 프로세스에는 기존 변형 복사, 패키지 참조 1개 변경, 워크스페이스 및 RPM 사양에 새 변형 등록, 빌드 실행이 포함됩니다. 커널 버전 교체, 패키지 추가, 새 Kubernetes 릴리스용 변형 생성 등 모든 사용자 지정에도 동일한 접근 방식이 적용됩니다.