🚀 요약
SUMMARY
고객 운영계에 고정된 특정 커널(
el8_8계열)에 NVIDIA 드라이버를 맞춰야 했는데, 기본 저장소에는 그 커널의kernel-devel/kernel-headers가 없어 dkms가 모듈을 빌드하지 못했다. Rocky Linux vault 저장소를 dnf에 추가해 아카이브된 정확한 커널 버전을 지정 설치하고, nvidia rpm은 인터넷이 되는 호스트에서 의존성까지 받아 패키징해 폐쇄망으로 반입했다. 커널-드라이버 버전 정합성을 맞춘 뒤에야 dkms 빌드가 통과했다.
⚙️ 환경
- 고객 운영계: RHEL 8.8 계열, 커널
4.18.0-477.15.1.el8_8로 고정 (버전은 대표값으로 표기) - GPU 서버, NVIDIA open kernel module(dkms) 방식 설치
- 완전 폐쇄망: 외부 저장소·인터넷 직접 접근 불가
💬 이슈
고객 운영계 GPU 서버에 드라이버를 올려야 했다. 문제는 이 서버의 커널이 특정 버전에 고정돼 있다는 점이었다. 운영계는 검증된 커널에서만 돌리는 게 원칙이라 마음대로 최신으로 올릴 수 없다. 커널은 그대로 두고, 그 커널에 맞는 드라이버를 얹어야 하는 상황이었다.
NVIDIA 드라이버를 open kernel module(dkms) 방식으로 깔면, dkms가 현재 실행 중인 커널의 소스로 커널 모듈을 그 자리에서 빌드한다. 그래서 빌드에는 실행 커널과 정확히 같은 버전의 kernel-devel, kernel-headers가 필요하다. 여기서 버전이 한 끗이라도 어긋나면 모듈이 커널에 안 맞아 nvidia-smi가 장치를 못 찾는다.
그런데 폐쇄망에 물려 있는(정확히는 사내 미러를 바라보는) 이 서버에서 kernel-devel을 설치하려 하면, 실행 커널이 아니라 저장소에 올라온 최신 커널(el8_10 계열, 4.18.0-553.x)용 패키지가 잡혔다.
# 실행 커널은 el8_8인데, 기본 저장소가 내주는 kernel-devel은 el8_10 최신이다.
uname -r
# 4.18.0-477.15.1.el8_8.x86_64
sudo dnf install kernel-devel
# → kernel-devel-4.18.0-553.8.1.el8_10 ← 실행 커널과 버전이 다르다이유는 단순하다. RHEL/Rocky의 기본 저장소는 해당 마이너 버전의 최신 포인트 릴리스만 서비스한다. 이전 포인트 릴리스 패키지는 시간이 지나면 vault(아카이브)로 밀려나 기본 저장소에서 사라진다. 운영계 커널은 이미 몇 단계 뒤의 릴리스라, 그에 맞는 kernel-devel/kernel-headers가 기본 저장소엔 남아 있지 않았다. 결국 “실행 커널에 맞는 개발 패키지를 어디서 구하느냐”가 전부였다.
🧗 해결
1. Rocky vault 저장소에서 정확한 커널 패키지 확보
사라진 옛 패키지는 vault 저장소에 그대로 있다. Rocky Linux는 dl.rockylinux.org/vault 경로에 마이너 버전별 아카이브를 공개해두는데, 여기엔 8.8 시점의 BaseOS/AppStream 패키지가 통째로 보존돼 있다. 운영계가 RHEL이어도 Rocky는 바이너리 호환이라, el8_8 패키지를 그대로 가져다 쓸 수 있다.
인터넷이 되는 별도 호스트(운영계와 같은 8.8로 맞춘 스테이징)에 vault 저장소를 dnf에 추가했다.
# Rocky 8.8 vault를 dnf 저장소로 추가한다. 8.8 시점 패키지가 아카이브돼 있다.
sudo dnf config-manager --add-repo=https://dl.rockylinux.org/vault/rocky/8.8/BaseOS/x86_64/os/여러 저장소를 한 번에 잡으려고 .repo 파일을 직접 써 넣는 편이 깔끔했다. $releasever는 vault 경로와 어긋날 수 있어 버전(8.8)을 URL에 박아버렸다.
# /etc/yum.repos.d/rocky-vault.repo
[rocky-vault-baseos]
name=Rocky Linux 8.8 - BaseOS - Vault
baseurl=https://dl.rockylinux.org/vault/rocky/8.8/BaseOS/x86_64/os/
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-rockyofficial
[rocky-vault-appstream]
name=Rocky Linux 8.8 - AppStream - Vault
baseurl=https://dl.rockylinux.org/vault/rocky/8.8/AppStream/x86_64/os/
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-rockyofficial
[rocky-vault-powertools]
name=Rocky Linux 8.8 - PowerTools - Vault
baseurl=https://dl.rockylinux.org/vault/rocky/8.8/PowerTools/x86_64/os/
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-rockyofficial
[rocky-vault-extras]
name=Rocky Linux 8.8 - Extras - Vault
baseurl=https://dl.rockylinux.org/vault/rocky/8.8/extras/x86_64/os/
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-rockyofficial메타데이터를 새로 만들고, --showduplicates로 정말 그 버전이 vault에 있는지부터 확인했다.
sudo dnf clean all
sudo dnf makecache
# vault를 붙였으니 옛 커널 릴리스가 후보로 뜬다.
sudo dnf list --showduplicates kernel목록에서 드라이버를 얹을 el8_8 버전을 확인한 뒤, 버전을 콕 집어 설치했다. 커널과 함께 kernel-devel, kernel-headers도 같은 버전으로 맞춘다. 여기가 이 작업의 핵심이다. dkms가 참조할 커널 소스를 커널과 완전히 동일한 버전으로 깔아두는 것.
# 최신으로 올리지 않고, vault가 보존한 el8_8 버전을 명시해 설치한다(대표값 4.18.0-477.15.1.el8_8).
sudo dnf install \
kernel-4.18.0-477.15.1.el8_8 \
kernel-devel-4.18.0-477.15.1.el8_8 \
kernel-headers-4.18.0-477.15.1.el8_8NOTE
dkms가 참조하는 건 실행 커널의 소스라, 커널과 그
kernel-devel/kernel-headers가 모두 같은 버전에 맞물려 있어야 한다. 최신으로 올려버리면 다시 devel이 없는 상황이 되니, vault가 아직 내주는 el8_8 버전에 맞추는 게 핵심이다.
2. nvidia rpm은 호스트에서 받아 패키징
폐쇄망 서버는 vault든 NVIDIA CUDA 저장소든 직접 못 나간다. 그래서 저장소를 서버에 붙이는 대신, 인터넷이 되는 호스트에서 필요한 rpm을 의존성까지 통째로 받아 묶은 뒤 반입했다.
연결된 호스트에 NVIDIA CUDA 저장소를 추가하고, 설치가 아니라 다운로드만 시켰다. --resolve로 의존성까지 같이 받는 게 폐쇄망 반입의 관건이다. 하나라도 빠지면 격리된 서버에서 설치가 멈춘다.
# 연결된 호스트에 CUDA 저장소 추가
sudo dnf config-manager --add-repo=https://developer.download.nvidia.com/compute/cuda/repos/rhel8/x86_64/cuda-rhel8.repo
# 설치하지 않고, 의존성까지 한 폴더에 내려받는다.
sudo dnf install --downloadonly --downloaddir=./nvidia-rpms --resolve \
nvidia-driver:open-dkms
# 반입용으로 묶는다.
tar czf nvidia-rpms.tar.gz ./nvidia-rpms이 묶음과 앞서 받은 커널 패키지를 폐쇄망 서버로 옮긴 뒤, 로컬 파일만으로 설치했다. 저장소를 안 타고 내려받은 rpm 디렉토리에서 바로 설치하면 된다.
# 반입한 rpm 디렉토리에서 로컬 설치. dkms가 el8_8 커널 소스로 모듈을 빌드한다.
sudo dnf install ./nvidia-rpms/*.rpm✅ 확인
먼저 실행 커널과 설치된 kernel-devel 버전이 같은지 봤다. 이게 어긋나 있으면 나머지는 볼 필요도 없다.
uname -r
# 4.18.0-477.15.1.el8_8.x86_64
rpm -q kernel-devel
# kernel-devel-4.18.0-477.15.1.el8_8.x86_64 ← 실행 커널과 일치그다음 dkms가 모듈을 실제로 빌드해 붙였는지 확인한다. 상태가 installed로 실행 커널에 걸려 있으면 정상이다.
# 실행 커널(kernel: 4.18.0-477.15.1.el8_8)에 nvidia 모듈이 installed로 붙어야 한다.
dkms status마지막으로 nvidia-smi가 GPU를 정상적으로 잡으면 끝이다. 커널-드라이버 버전이 맞지 않던 동안엔 여기서 계속 장치를 못 잡았다.
nvidia-smi버전 정합성만 맞추면 나머지는 평범하게 굴러갔다. 폐쇄망이라 저장소를 못 붙이는 게 처음엔 막막했는데, 결국 실행 커널에 맞는 패키지를 어디서 구해 어떻게 반입하느냐의 문제였다.