쿠버네티스에서 GPU를 잘 쓰기 위해선 NVIDIA GPU Operator를 많이 쓰죠. 그런데 이게 온라인 환경을 기본 전제로 움직이다 보니, 에어갭(air-gapped) 환경에선 설치가 꽤 까다롭습니다.
특히, GPU Operator가 노드에 올릴 커널 모듈이 필요한데, 이걸 빌드하려면 해당 노드에 커널 헤더랑 컴파일 툴들이 다 있어야 해요. 온라인이면 apt로 깔면 되지만, 오프라인이면 얘기가 달라지죠.
그래서 준비했습니다.
드라이버를 미리 빌드해서, 오프라인에서도 바로 쓸 수 있게 만든 이미지입니다.
(참고 저장소: pu4ro/nvidia-driver)
목표
- NVIDIA 드라이버를 미리 빌드해서 Docker 이미지에 포함
- 커널 모듈도 포함
- 의존 패키지들도 전부 담아서 apt 없이 설치 가능
- GPU Operator가 precompiled 드라이버를 인식할 수 있도록 정리
구조
총 3단계로 이미지가 만들어집니다.
1. repo-builder: 필요한 패키지를 모두 다운로드
2. driver-builder: 실제 드라이버 모듈을 빌드
3. final: 모듈과 패키지를 정리해 하나의 이미지로 구성
1단계: 필요한 패키지 오프라인으로 가져오기
FROM nvcr.io/nvidia/driver:535.183.06-ubuntu22.04 AS repo-builder
- NVIDIA의 base 이미지 사용
linux-headers,dkms,build-essential같은 커널 모듈 빌드에 필요한 패키지를 다운로드-only 옵션으로 받아둡니다./local-repo라는 디렉토리에.deb파일들을 모아두고, 로컬 APT 저장소를 만듭니다.
이렇게 하면 나중에 오프라인에서도 apt install이 되게 만들 수 있어요.
2단계: 드라이버 모듈 빌드
FROM nvcr.io/nvidia/driver:535.183.06-ubuntu22.04 AS driver-builder
- 여기선 실제로 NVIDIA의
.run파일을 받아서 드라이버 모듈을 빌드합니다. - 중요한 건
-dkms플래그 없이 직접 커널 모듈을 만드는 방식이라는 점. - 빌드한 결과는
/lib/modules,/usr/src/nvidia-...아래에 저장됩니다.
3단계: 최종 이미지 만들기
FROM nvcr.io/nvidia/driver:535.183.06-ubuntu22.04
앞 단계에서 만든 커널 모듈, 드라이버 소스, 설정 파일을 복사해 옵니다.
- 아까 만든
/local-repo도 복사해서, 시스템이 오직 이 repo만 보도록sources.list를 덮어씁니다. - 마지막으로
offline-init.sh라는 스크립트를 이미지에 포함시켜서, 컨테이너가 뜰 때 필요한 초기화 작업을 하도록 합니다.
ENTRYPOINT ["nvidia-driver","init"]
GPU Operator에서 쓰는 방법
GPU Operator의 driver 컴포넌트를 이 이미지로 바꿔주면 됩니다.
values.yaml 또는 ClusterPolicy에서 precompiled 드라이버를 참조하게 설정하면, 오프라인 환경에서도 모듈이 자동으로 올라가게 됩니다.
마무리
이 방식의 장점은:
- 오프라인 환경에서도 GPU Operator 작동 가능
- 커널 모듈 미리 준비해서 재빌드 필요 없음
- 운영 환경에서 DKMS나 빌드 도구 설치 안 해도 됨 (보안적으로도 좋죠)
CI 파이프라인에서 커널 버전별로 이미지를 미리 빌드해두면, 에어갭 환경에서도 GPU 노드를 문제없이 확장가능
참고
- GitHub: https://github.com/pu4ro/nvidia-driver
- 사용한 드라이버 버전:
535.183.06 - 커널 버전:
5.15.0-119-generic - OS: Ubuntu 22.04