LabHub
배우기 러닝패스 코스

Air-Gapped GPU Driver Installation

Why Air-Gapped Installation Is Hard

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

한 줄 요약

폐쇄망 설치가 어려운 진짜 이유는 의존성을 계산하는 쪽과 설치하는 쪽이 분리되어 있기 때문이다. 계산에 필요한 정보가 양쪽에 나뉘어 있다.

Concept map: 의존성을 계산하는 쪽과 설치하는 쪽이 분리되어 있기 때문 · 반입 심의는 하루에 한 번뿐이다. · 저장소 메타데이터 전체 · 설치 대상 시스템의 현재 상태

왜 이게 필요했나

요청은 항상 이렇게 온다. "드라이버 파일 하나만 받아다 주세요."

받아서 넣으면 이런 에러가 난다.

The following packages have unmet dependencies:
 nvidia-driver-550 : Depends: nvidia-kernel-dkms-550 but it is not installable

다시 나가서 그걸 받아 오면 또 다른 게 없다고 한다. USB 를 서너 번 왕복하면 반나절이 지나 있고, 반입 심의는 하루에 한 번뿐이다.

어떻게 동작하나

계산과 설치의 분리

의존성 해결기(depsolver)의 입력은 두 가지다.

  1. 저장소 메타데이터 전체 — 어떤 패키지가 무엇을 제공하고 무엇을 요구하는가
  2. 설치 대상 시스템의 현재 상태 — 이미 무엇이 깔려 있는가

폐쇄망 안쪽에는 1번이 없고, 바깥쪽에는 2번이 없다. 이 분리가 문제의 본질이다.

해법은 두 갈래다.

작게 시작하면 첫 번째로 가지만, 대부분의 조직은 결국 두 번째로 간다. 반입이 반복되면 첫 번째 방식의 관리 비용이 급격히 커지기 때문이다.

조용히 빠지는 것들

1번 방식에서 가장 위험한 것은 에러 없이 조용히 빠지는 패키지다.

첫째, 이미 설치된 것이 결과에서 사라진다. 의존성 계산은 "계산하는 시스템의 현재 상태"를 전제로 한다. 연결망 장비에 이미 깔려 있는 라이브러리는 "필요 없음" 으로 처리되어 목록에서 빠지고, 그 사실은 폐쇄망 안쪽에서야 드러난다.

둘째, 버전이 다르면 결과가 달라진다. 연결망 장비가 24.04 이고 설치 대상이 22.04 라면 해결 결과가 다를 수 있다.

셋째, 아키텍처를 빼먹는다. noarch/all 패키지를 arch 지정에서 누락하면 파이썬 모듈이나 설정 패키지가 통째로 빠진다.

넷째, 약한 의존(Recommends)의 처리. 계산할 때는 제외했는데 설치할 때는 기본 포함이라 요구받는 경우가 있다. 반대도 있다.

그래서 정석은 빈 루트를 기준으로 계산하는 것이다. apt 쪽에서는 --print-uris 로 받을 목록을 먼저 뽑아 검토하고, --download-only 로 받은 뒤 그 묶음이 자기 안에서 닫히는지(closure) 확인한다.

무결성 — 두 개의 다른 질문

매체를 통과한 파일에 대해 물어야 할 질문은 두 개다.

질문 답하는 것 도구
전송 중 손상됐나 체크섬 sha256sum -c
이게 정말 그쪽에서 온 게 맞나 서명 GPG 검증, dpkg-sig, rpm --checksig

같은 매체에만 담긴 체크섬은 매체가 통째로 바뀌면 함께 바뀐다. 그러니 체크섬만으로는 출처를 보증할 수 없다. 실질적인 보증은 서명에서 나온다.

그리고 매니페스트에 없는데 매체에 들어 있는 파일도 검사해야 한다. 누락은 설치 실패로 금방 드러나지만, 추가된 파일은 아무도 모르게 지나간다. 반입 심의의 관점에서는 이쪽이 더 큰 문제다.

반입 기록

번들에는 파일뿐 아니라 기록이 함께 들어가야 한다.

항목
번들 ID gpu-airgap-2026-08-20 서버와 번들을 연결하는 키
스냅샷 날짜 2026-08-20 어느 시점 콘텐츠인지
대상 버전 ubuntu 24.04 / driver 550.90.07 재현의 전제
생성 명령 apt-get install --download-only ... 재현의 핵심
매체 해시 아카이브 전체의 SHA-256 매체 단위 무결성
반입 일시·담당자 감사 요구

6개월 뒤 "이 서버는 어느 시점 콘텐츠로 설치됐지?" 라는 질문에 답할 수 있어야 한다.

반입 전에 목록을 만드는 법

폐쇄망 반입에서 가장 흔한 실패는 무결성이 아니라 빠뜨림이다. 한 번 들어가면 다시 나오기 어려우므로, 목록을 만드는 방법 자체가 절차의 핵심이 된다.

의존성을 사람이 세지 않는다. 패키지 관리자에게 "이걸 설치하려면 무엇이 필요한가" 를 물어 그 답을 그대로 담는다.

# 데비안 계열: 의존성까지 통째로 내려받는다
apt-get install --download-only --reinstall -o Dir::Cache::archives=./pkgs <패키지>
# RHEL 계열
dnf download --resolve --alldeps --destdir ./pkgs <패키지>
# 파이썬: 해시까지 고정해서
pip download -r requirements.txt -d ./wheels --require-hashes

컨테이너 이미지는 다이제스트로 담는다. 태그로 담으면 밖에서 받은 것과 안에서 쓰는 것이 다를 수 있다.

skopeo copy --all docker://registry/app@sha256:... dir:./images/app

--all 이 없으면 지금 이 컴퓨터의 아키텍처만 담긴다. 반입 대상이 다른 아키텍처면 안에서 "manifest unknown" 을 만난다.

GPU 쪽은 버전 짝이 특히 엄격하다. 드라이버, 컨테이너 툴킷, CUDA, 프레임워크의 조합이 맞아야 한다. 하나만 어긋나도 "GPU 를 못 찾는다" 로 나타나고, 폐쇄망 안에서는 다른 버전을 받아 볼 수 없다. 밖에서 같은 조합을 한 번 세워 보고 그 목록을 그대로 반입한다.

설치 순서를 함께 담는다. 오프라인 저장소를 만들고, 그 저장소를 가리키게 설정하고, 순서대로 설치하는 스크립트를 같이 넣는다. 안에서 손으로 순서를 찾는 것은 시간도 걸리고 재현도 안 된다.

되돌릴 방법도 함께 넣는다. 드라이버를 올렸다가 문제가 생기면 이전 버전으로 돌아가야 하는데, 그 이전 버전 패키지가 안에 없으면 되돌릴 수 없다. 지금 설치된 버전의 패키지도 함께 반입한다.

현장에서 만나는 모습

epoch 의 함정. 데비안/RPM 모두 버전 앞에 epoch 를 둘 수 있다(1:550.90.07-0ubuntu1). 파일 이름에는 epoch 가 들어가지 않는다. 그런데 버전 비교에서는 epoch 가 가장 우선한다. 파일 이름만 보고 "이게 더 최신" 이라고 판단하면 틀릴 수 있다. 매니페스트에 완전한 버전 문자열을 적어야 하는 이유다.

다음 확인에서 볼 것

이어지는 퀴즈에서는 의존성 계산의 두 입력, 체크섬과 서명의 역할, 매니페스트의 양방향 검증을 먼저 구분한다. 그 판단 기준을 확인한 뒤 다음 모듈부터 패키지 묶음의 의존성 그래프와 설치 순서를 실제로 산출한다.