RHEL 계열 관리 · 에어갭 설치 · 이론
매체에 담을 여섯 가지
한 줄 요약
반입 매체에는 rpm 만 담으면 안 된다. rpm, repodata, GPG 키, 매니페스트, 체크섬, 설치 절차서 여섯 가지가 다 있어야 한다. 실제로 가장 자주 빠지는 것이 GPG 키와 매니페스트다.
왜 이게 필요했나
연결망에서 성공한 다운로드 명령은 설치 대상의 버전·아키텍처·기설치 상태가 다르면
폐쇄망에서 같은 결과를 보장하지 않는다. 누락된 의존성은 재반입을 만들고, 출처를
검증할 키나 승인 목록이 없으면 파일이 있어도 설치 허가를 증명할 수 없다. 그래서
번들은 패키지 모음이 아니라 재현 조건과 검증 근거까지 포함한 배포 단위여야 한다.
어떻게 동작하나
밖에서 받기
두 갈래가 있다.
해결된 결과를 옮기기
dnf download --resolve --alldeps --destdir=/srv/bundle/rpms httpd mod_ssl--resolve— "지정한 패키지의 의존성을 해결하고 시스템에 없는 의존성을 내려받는다"--alldeps— "--resolve와 함께 쓰면 이미 설치된 것도 건너뛰지 않고 전부 받는다"
--resolve 만 쓰면 이 장비에 없는 것만 받는다. 폐쇄망 번들을 만드는 목적이라면 이건 거의 항상 틀린 결과다.
그런데 --alldeps 만으로도 부족하다. 의존성 해결 자체는 여전히 이 시스템의 상태를 전제로 이루어지기 때문이다. 연결망 장비가 9.4 이고 대상이 9.2 라면 결과가 달라질 수 있다. 정석은 빈 루트를 쓰는 것이다.
mkdir -p /var/tmp/airgap-rootdnf download --installroot=/var/tmp/airgap-root --releasever=9.4 \ --setopt=reposdir=/etc/yum.repos.d --resolve --alldeps \ --destdir=/srv/bundle/rpms httpd mod_ssl--releasever 를 반드시 함께 지정해야 한다. 문서의 경고: "installroot 를 만들 때 --releasever 를 쓰지 않으면 $releasever 값이 installroot 안의 rpmdb 에서 오는데, 생성 시점에는 비어 있어 트랜잭션이 실패한다."
저장소를 통째로 옮기기
dnf reposync --repoid=rhel-9-for-x86_64-baseos-rpms \ --download-path=/srv/sync --download-metadata --gpgcheck \ --newest-only --arch=x86_64 --arch=noarch --remote-time주요 옵션: --download-metadata(메타데이터 함께), --gpgcheck(서명 실패 패키지 삭제, 하나라도 삭제되면 종료 코드 1), --newest-only(저장소별 최신만), --delete(원격에 없는 것 삭제), --norepopath(경로에 repo 이름을 붙이지 않음).
함정: --newest-only 와 --download-metadata 를 함께 쓰면 최신 패키지만 받지만 메타데이터에는 이전 패키지 정보가 남는다. 안쪽에서 특정 옛 버전을 요청하면 메타데이터에는 있는데 파일이 없는 상태가 된다.
매니페스트
매니페스트에 담아야 할 다섯 요소: 완전한 NEVRA(Name, Epoch, Version, Release, Architecture), 패키지별 SHA-256, 스냅샷 날짜, 사용한 releasever, 출처 저장소 ID.
rpm -qp --queryformat '%{NAME}\t%|EPOCH?{%{EPOCH}}:{0}|\t%{VERSION}\t%{RELEASE}\t%{ARCH}' "$f"sha256sum "$f" | cut -d' ' -f1epoch 삼항 표기가 핵심이다. mod_ssl 같은 패키지는 epoch 가 1인데 파일 이름 어디에도 그 숫자가 없다.
안쪽에서 검증
rpmkeys --import /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-releaserpmkeys --listrpmkeys --checksig /srv/bundle/rpms/*.rpm | grep -v 'digests signatures OK'마지막 줄이 아무것도 출력하지 않으면 전부 정상이다. 그리고 매니페스트에 없는데 매체에 있는 파일도 확인한다.
comm -13 <(cut -f7 MANIFEST.tsv | sort) <(cd rpms && ls -1 *.rpm | sort)누락은 설치 실패로 금방 드러나지만, 추가된 파일은 아무도 모르게 지나간다. 반입 심의 관점에서는 이쪽이 더 큰 문제다.
안쪽에 세우기
createrepo_c /srv/repo/labhubcat > /etc/yum.repos.d/airgap.repo <<'EOF'[airgap-baseos]name=RHEL 9 BaseOS (airgap local, snapshot 2026-08-20)baseurl=file:///srv/repo/labhubenabled=1gpgcheck=1gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-releasemetadata_expire=-1EOFdnf --disablerepo='*' --enablerepo=airgap-baseos install -y httpd현장에서 만나는 모습
아키텍처를 빼먹는다. x86_64 노트북에서 받아 ARM 서버로 반입하면 에러 없이 잘못된 것이 들어간다. --arch 에 noarch 를 함께 지정하지 않으면 파이썬 모듈이나 설정 패키지가 통째로 빠진다.
다음 실습에서 할 것
반입 번들을 만들고, 매니페스트로 검증하고, 아카이브로 묶었다 풀고, 저장소를 세워 그것만으로 설치한다.