에어갭 반입 (오프라인 설치·업그레이드 번들)
인터넷이 차단된 온프렘 사이트로 GenD 릴리스를 반입하는 표준 절차입니다 (v1.1.0+, ADR-0036 Phase 2).
개요
[공급자측: 인터넷 O] [고객측: 에어갭]
make_airgap_bundle.sh vX.Y.Z → 매체 반입 → load-airgap-images.sh <사이트 레지스트리>
(이미지 pull·save + 무결성) (검증 → load → 재태깅 → push)
- 업그레이드 번들(기본): 제품 이미지 4종 —
gend-api/gend-ui/gend-pipelines/gend-relay - 설치 번들(
--full): + 3rd-party 인프라 이미지 12종 (PostgreSQL, Trino, Kafka, OpenSearch 등 — 목록 단일 소스:infra/azure-deploy/scripts/third-party-images.txt) - ⚠ 커스텀 빌드 인프라 이미지(keycloak·hive-metastore·kafka-connect-iceberg)는
--full에 포함되지 않습니다 — 부트스트랩(01-push-images.sh)이 사이트에서 빌드·push 하는 대상입니다
1. 번들 생성 (공급자측)
전제: docker, 릴리스 레지스트리 pull 권한 (az acr login --name genosprodacr).
# 업그레이드 번들 (제품 4종)
scripts/make_airgap_bundle.sh v1.1.0 --output /tmp/bundles
# 신규 설치 번들 (제품 + 인프라 13종)
scripts/make_airgap_bundle.sh v1.1.0 --full --output /tmp/bundles
# 산출물: gend-airgap-v1.1.0[-full].tar.gz
번들 내용물:
| 경로 | 내용 |
|---|---|
images/*.tar + images/index.txt | 이미지 tar + 적재 매핑 (파일 ↔ 원본 ref ↔ 사이트 리포명) |
load-airgap-images.sh | 고객측 적재 스크립트 (레포 불필요, 단독 실행) |
manifests/alembic-upgrade-job.yaml | DB 마이그레이션 Job (업그레이드 절차에서 사용) |
sbom/*.cdx.json / sbom/*.spdx.json | 이미지 4종의 자재명세 — CycloneDX + SPDX 병행 |
sbom/*.identity.json | 이미지 아이덴티티(digest·소스 커밋·빌드 run) |
SHA256SUMS / bundle-manifest.json | 무결성 검증 / 번들 메타데이터 |
SBOM·이미지 아이덴티티 (반입 심사 대응)
금융·공공 반입 심사가 SBOM 제출을 요구하는 경우가 있어, 출하 번들에 봉인 시점의 SBOM 을 함께 넣는다. 두 형식(CycloneDX·SPDX)을 병행하는 것은 심사 기관마다 요구 형식이 다르기 때문이다.
- SBOM 은 번들 생성 시 재생성하지 않고 릴리스 자산에서 받아온다
(
gh release download <태그>). 다시 스캔해 만든 SBOM 은 "출하된 그 이미지의 자재명세" 가 아니라 "지금 이 시점의 재해석 결과" 라 증빙 가치가 약하다. 조달에 실패하면 번들 생성이 실패한다 — 조용히 SBOM 없는 번들을 만들지 않는다. (오프라인 조립 시에는--sbom-dir <디렉터리>로 직접 넘긴다) sbom/은SHA256SUMS검증 대상에 포함된다. 포함하지 않으면 고객이 "검증 통과" 를 보고 SBOM 까지 검증됐다고 믿게 되는데, 실제로는 아무것도 배제하지 못한다.
:::note SHA256SUMS 로 증명되는 것과 안 되는 것
SHA256SUMS 는 번들 파일의 무결성을 증명한다 — 매체 손상·전송 중 변조를 잡는다.
그러나 그것만으로 "고객사에 들어간 그 이미지" 를 특정하지는 못한다. 태그는 이동
가능하기 때문이다. 그래서 bundle-manifest.json 의 images[] 와
sbom/*.identity.json 에 digest 를 기록한다:
digest— 레지스트리 manifest digest (RepoDigests). 사후 역추적의 1차 근거.config_digest— 로컬 이미지 config digest (docker inspect .Id). 레지스트리에서 pull 하지 않고 조립한 경우의 폴백.
두 값은 다른 필드로 분리한다. 같은 필드에 섞으면 어느 쪽 증빙인지 알 수 없어진다.
이미지 서명(cosign)은 아직 도입하지 않았다 — 키 관리와 고객측 검증 도구 설치가 전제라 에어갭 반입 절차 자체가 바뀐다. 별도 검토 대상이다. :::
:::note UI 이미지와 사이트 도메인
gend-ui 릴리스 이미지는 gend.genon.ai 도메인이 빌드타임에 새겨져 있습니다.
도메인이 다른 사이트는 번들 생성 전에 사이트 도메인으로 재빌드한 이미지를
레지스트리에 올려 두거나(부트스트랩 01-push-images.sh, DOMAIN env),
--registry 로 해당 레지스트리를 지정해 번들을 만드세요.
:::
2. 반입·적재 (고객측)
전제: docker, 사이트 레지스트리 push 권한 (docker login).
tar xzf gend-airgap-v1.1.0.tar.gz && cd gend-airgap-v1.1.0
# 무결성 검증 + 적재 (검증 실패 시 즉시 중단)
./load-airgap-images.sh harbor.site.local/gend
# 출력 예: ✅ 4/4 이미지 적재 완료 → harbor.site.local/gend
- 무결성 검증만 따로 하려면:
sha256sum -c SHA256SUMS(macOS:shasum -a 256 -c) - 매체 반입 정책(백신 검사 등)은 사이트 보안 규정을 따르세요 — 번들은 단일 tar.gz 라 반입 심사 대상이 1개 파일입니다.
3. 업그레이드 연계
적재가 끝나면 업그레이드 절차의 표준 순서를 따릅니다:
# ① DB 마이그레이션 (번들 동봉 manifests/alembic-upgrade-job.yaml 사용 —
# image 를 <사이트 레지스트리>/gend-api:vX.Y.Z 로 치환)
# ② 이미지 교체
kubectl -n gend set image deploy/gend-api gend-api=harbor.site.local/gend/gend-api:v1.1.0
# ③ 검증
curl -fsS https://<도메인>/version # version/build_sha 확인 (-f: HTTP 오류를 실패로)
문제 해결
| 증상 | 원인·대처 |
|---|---|
SHA256SUMS: FAILED | 매체 손상 — 번들 재반입. --skip-verify 는 진단 용도로만 |
index.txt 가 비어 있다 | 번들 손상 — 재생성 |
push 시 denied | 사이트 레지스트리 docker login / 프로젝트 권한 확인 |
| 적재 후에도 파드가 구버전 | kubectl set image 미실행 — 업그레이드 절차 ② 참조 |