Air-Gapped GPU Driver Installation
The Verification Plan and the Rollback Path
한국어 원문으로 표시합니다.
한 줄 요약
폐쇄망 작업에서 롤백 경로가 없는 변경은 하지 않는다. 다시 나가서 뭔가를 받아 오는 것이 불가능하기 때문이다.
왜 이게 필요했나
연결망이라면 설치가 잘못돼도 다시 받으면 된다. 폐쇄망은 다르다. 무언가를 지웠는데 그것을 다시 받으려면 반입 심의를 또 거쳐야 한다. 되돌릴 수 없는 작업 하나가 며칠을 만든다.
그래서 폐쇄망 작업 절차의 절반은 "무엇을 바꿨는지 기록하고, 어떻게 되돌릴지 미리 정해 두는 것" 이다.
어떻게 동작하나
검증 계획
실제 GPU 가 있는 환경에서 설치 검증은 이 순서다.
# 1. 커널 층
lsmod | grep -c nvidia
ls /dev/nvidia*
# 2. 유저 공간 층
nvidia-smi
nvidia-smi --query-gpu=name,driver_version,memory.total --format=csv
# 3. 컨테이너 주입 층
nvidia-ctk cdi list
nvidia-container-cli info
# 4. 실제 컨테이너
podman run --rm --device nvidia.com/gpu=all <cuda 이미지> nvidia-smi
층을 순서대로 확인하는 것이 핵심이다. 4번만 해 보고 실패하면 어느 층이 문제인지 모른다. 1번부터 올라가면 실패 지점이 곧 원인이다.
패키지 무결성
설치 후에도 파일이 그대로인지 확인할 수 있다.
dpkg -V nvidia-driver-550 # 설치 시점의 해시와 비교
dpkg -V | head # 전체 검사
출력 형식은 ??5?????? 같은 문자열이다. 5 는 md5 불일치(내용이 바뀜), c 는 설정 파일 표시. 설정 파일이 바뀐 것은 정상이지만 바이너리가 바뀌었다면 조사해야 한다.
버전 고정
드라이버는 특히 고정이 중요하다. 커널이 올라가면 DKMS 재빌드가 필요하고, 폐쇄망에서 그건 또 한 번의 반입이다.
apt-mark hold nvidia-driver-550 nvidia-container-toolkit
apt-mark hold linux-image-generic linux-headers-generic
apt-mark showhold
커널까지 함께 고정하는 것이 GPU 노드의 관행이다.
롤백 경로
apt 는 트랜잭션 롤백을 직접 지원하지 않는다(dnf 의 history undo 같은 것이 없다). 그래서 수동으로 준비한다.
# 설치 전 상태 기록
dpkg -l > /var/log/labhub/before.txt
apt-mark showhold > /var/log/labhub/holds.txt
# 설치 로그 확인
cat /var/log/apt/history.log
grep -A3 'Start-Date' /var/log/apt/history.log | tail -20
# 롤백 (제거)
apt-get purge -y nvidia-container-toolkit
apt-get autoremove -y
/var/log/apt/history.log 에는 각 트랜잭션의 시작 시각, 명령줄, 설치/제거된 패키지가 기록된다. 이 파일이 사실상의 트랜잭션 로그다.
더 확실한 롤백은 시스템 스냅샷이다. LVM 스냅샷이나 VM 스냅샷을 설치 전에 떠 두면 어떤 실패에서도 되돌릴 수 있다. 폐쇄망 GPU 노드 작업 전에 이걸 하는 조직이 많다.
되돌리면 안 되는 것
커널이나 glibc 같은 기반 패키지의 다운그레이드는 위험하다. 의존성 그래프의 뿌리에 있어서, 되돌리는 순간 시스템 전체가 불안정해질 수 있다. 이런 것은 롤백 대상이 아니라 애초에 신중하게 올려야 하는 대상이다.
현장에서 만나는 모습
드라이버를 지웠더니 X 가 안 뜬다. nvidia-driver-* 를 purge 하면 디스플레이 드라이버도 함께 사라진다. 헤드리스 서버라면 상관없지만 콘솔이 필요한 워크스테이션이라면 nouveau 폴백을 확인해야 한다.
hold 를 걸어 두고 잊는다. 몇 달 뒤 보안 패치가 적용되지 않는 이유가 그 hold 였다. hold 목록을 정기적으로 검토하는 절차가 필요하고, 왜 걸었는지를 기록해 두어야 한다.
검증을 계층으로 나누기
"GPU 가 된다" 는 문장은 최소 네 층을 포함합니다. 아래에서 위로 하나씩 확인해야 어디가 깨졌는지 알 수 있습니다.
4. 프레임워크 torch.cuda.is_available() == True, 실제 연산이 맞는 값을 낸다
3. 컨테이너 파드 안에서 nvidia-smi 가 GPU 를 본다
2. 스케줄러 노드에 nvidia.com/gpu 자원이 광고되어 있다
1. 호스트 nvidia-smi 가 장치를 나열하고 모듈이 로드돼 있다
각 층의 확인 명령입니다.
# 1. 호스트
nvidia-smi && lsmod | grep nvidia
# 2. 스케줄러 — 자원이 0 이면 device plugin 이 안 도는 것
kubectl get nodes -o custom-columns=N:.metadata.name,GPU:.status.allocatable.'nvidia\.com/gpu'
# 3. 컨테이너
kubectl run gpu-check --rm -it --restart=Never \
--image=nvidia/cuda:12.4.0-base-ubuntu22.04 \
--limits=nvidia.com/gpu=1 -- nvidia-smi
# 4. 프레임워크 — 그리고 값이 맞는지까지
python -c "import torch; a=torch.randn(1000,1000,device='cuda'); print((a@a).sum().item())"
4번에서 값까지 확인하는 것 이 중요합니다. is_available() 이 True 인데 실제
연산이 NaN 을 내는 경우가 있습니다(드라이버와 CUDA 버전 불일치, ECC 오류).
롤백 경로를 미리 만들어 두기
폐쇄망에서는 "인터넷에서 다시 받는다" 가 불가능하므로, 되돌릴 것을 먼저 확보하고 시작합니다.
- 현재 드라이버 패키지를 보관 —
dpkg-repack이나 반입 매체의 옛 버전. - 현재 커널과 모듈을 고정 —
apt-mark hold. 새 커널이 들어와 모듈이 사라지는 것이 가장 흔한 사고입니다. - 작업 전 상태를 기록 —
nvidia-smi -q > before.txt,lsmod,dkms status. 되돌린 뒤 같은 상태인지 대조할 기준입니다.
# 되돌리기
apt-get install --allow-downgrades nvidia-driver-550=550.90.07-0ubuntu1
update-initramfs -u && reboot
update-initramfs 를 빠뜨리면 재부팅 뒤 옛 모듈이 그대로 로드되어 "되돌렸는데
그대로" 가 됩니다.
검증 결과를 남기는 형식
## GPU 설치 검증 2026-09-06 (node-gpu-03)
| 층 | 확인 | 결과 |
|---|---|---|
| 호스트 | nvidia-smi | 550.90.07, A100 ×2 인식 |
| 스케줄러 | allocatable | nvidia.com/gpu: 2 |
| 컨테이너 | 파드 안 nvidia-smi | 정상 |
| 프레임워크 | torch matmul | 값 일치, 3.2 TFLOPS |
- 되돌리기 검증: 550.54 로 다운그레이드 후 재부팅 → 정상, 다시 550.90.07 로 복귀
- 남은 위험: 커널 자동 업데이트 (apt-mark hold 로 고정함)
다음 실습에서 할 것
반입물의 무결성 매니페스트를 만들어 검증하고, 변조를 재현해 검증이 실패하는 것을 확인한다. 버전을 고정하고, 설치 트랜잭션 기록을 확인하고, 실제로 롤백을 수행한다.