본문으로 건너뛰기

폐쇄망 설치

개요​

인터넷이 닿지 않는 망에는 번들 하나로 설치합니다. 절차는 세 단계입니다.

  1. 인터넷이 되는 장비에서 번들을 만든다(또는 KOPENS 가 발행한 번들을 내려받는다).
  2. 허용된 매체로 폐쇄망 서버에 옮긴다.
  3. 폐쇄망 서버에서 로드하고 설치한다.

번들은 도커 엔진 설치 패키지까지 안고 있습니다. 대상 서버에 도커가 없어도 됩니다.

번들에 들어 있는 것​

산출물은 plantpulse-platform-images-<버전>.tar.gz 한 파일입니다.

경로내용
images/이미지마다 docker save 한 tar 하나씩
docker-rpms/RHEL · Rocky 용 도커 엔진 rpm
docker-debs/Ubuntu 용 도커 엔진 deb (OS_TARGET 으로 선택)
repo/설치·운영 스크립트와 compose/ 전체 (bin/env.sh 포함)
NOTICE내장 서드파티 구성 요소와 각 라이선스 위치
EULA.txtPlantPulse 자체의 사용 조건

NOTICE 와 EULA.txt 는 이미지 안에도 있지만 번들 최상단에 꺼내 둡니다. 무엇이 들어 있는지 보려고 10GB 짜리 tar 를 docker load 할 수는 없기 때문입니다.

1단계 — 번들 만들기​

권장 경로는 KOPENS 가 발행한 번들을 받는 것입니다.

https://product.kopens.io/plantpulse-platform/plantpulse-platform-images-<버전>.tar.gz

직접 만들어야 하면 인터넷이 되는 장비에서 다음을 실행합니다.

cd /opt/kopens/plantpulse-platform-docker/bin
./airgap-bundle.sh
환경 변수기본값뜻
INCLUDE_DATALAKE1데이터레이크 이미지를 함께 담는다
OS_TARGETrhelrhel · ubuntu · both — 어느 OS 패키지를 담을지
VERSION그 달(yyyy.mm)번들 파일명에 박히는 버전
OUT_TGZ저장소 아래산출물 경로를 직접 지정
AIRGAP_KEEP3최신 N 개만 남기고 오래된 번들을 지운다
INCLUDE_DATALAKE=0 으로 만들지 마라

클러스터의 마스터와 워커 다섯 대가 모두 plantpulse-datalake 이미지로 뜹니다(2026-08-31 부터 compose/docker-compose.worker.yml 이 이 이미지로 바뀌었습니다). 이 값을 0 으로 두고 구운 번들은 마스터도 워커도 세우지 못합니다. 기본값이 1 인 이유가 이것입니다.

이미지 목록은 손으로 적지 않는다

airgap-bundle.sh 는 담을 이미지를 docker compose config --images 로 뽑습니다. 예전에는 목록을 스크립트 안에 적어 두었는데, 2026-09-01 실측에서 스택이 실제로 요구하는 이미지는 아홉 개였고 그 안에 plantpulse-platform 은 없었습니다 — compose/docker-compose.yml 의 어떤 서비스도 그것을 띄우지 않습니다. 즉 그때의 번들은 «쓰지 않는 이미지 한 개» 를 담고 «필요한 여덟 개» 를 빠뜨린 물건이었고, 폐쇄망 설치가 될 수 없었습니다. 목록을 두 벌 두지 마십시오.

번들을 굽는 장비에서는 플랫폼 자격증명이 먼저 잡혀 있어야 합니다. compose 파일이 그 값들을 :? 로 선언하고 있어, 없으면 이미지가 하나도 안 잡히고 스크립트가 빈 번들 대신 오류로 끝납니다.

2단계 — 폐쇄망 서버로 옮기기​

USB · 내부 파일 서버 · scp 등 허용된 매체로 .tar.gz 를 대상 서버에 전달합니다.

3단계 — 로드와 설치​

sudo -i
mkdir -p /opt/kopens/plantpulse-platform-docker
tar -xzf plantpulse-platform-images-*.tar.gz -C /opt/kopens/plantpulse-platform-docker

# 자격증명 사이드카는 폐쇄망 서버에도 있어야 한다
vi /etc/kopens/plantpulse-platform.env

cd /opt/kopens/plantpulse-platform-docker/repo/bin
./airgap-load.sh

airgap-load.sh 가 순서대로 처리합니다.

  1. 번들 검증 — 곁파일 셋으로 서명과 체크섬을 확인합니다(아래).
  2. 도커 엔진 오프라인 설치 — rpm -ivh 또는 dpkg -i. 이미 깔려 있으면 건너뜁니다.
  3. 이미지 로드 — images/ 안의 tar 를 전부 docker load 합니다.
  4. 덮개 검사 — 로드된 이미지를 compose config --images 와 맞춰 봅니다.
  5. install.sh 호출 — SKIP_LOGIN=1. 이미지가 이미 로컬에 있으니 레지스트리 로그인을 하지 않습니다.

0단계 — 번들 검증 (2026-09-18 부터 곁파일 셋)​

번들 옆에 파일 셋이 함께 옵니다.

파일무엇
<번들>.tar.gz.sha256sha256sum -c 입력
<번들>.tar.gz.sha256.sig그 체크섬 파일에 대한 cosign 서명
<번들>.tar.gz.pub검증 키 사본

airgap-load.sh 가 두 단계를 순서대로 돌립니다 — 서명을 먼저 확인하고, 그 다음 체크섬을 씁니다. 인증하지 않은 체크섬은 증거가 아니기 때문입니다.

# 1) 이 체크섬이 «우리» 것인가
cosign verify-blob --key <번들>.tar.gz.pub \
--signature <번들>.tar.gz.sha256.sig <번들>.tar.gz.sha256

# 2) 번들의 바이트가 그 체크섬과 맞는가
sha256sum -c <번들>.tar.gz.sha256
서명 대상이 «번들» 이 아니라 «체크섬 파일» 입니다

번들이 8 GB 를 넘는데 cosign sign-blob 은 대상을 통째로 메모리에 올립니다. 그래서 서명은 체크섬 곁파일에 걸고, 번들 자체는 그 체크섬으로 확인합니다. 옛 <번들>.tar.gz.sig 는 더 이상 만들어지지 않습니다 — 그 이름을 찾는 절차서가 있으면 고치십시오.

곁파일이 없으면 «검증 없이» 진행됩니다

airgap-load.sh 는 곁파일이 없을 때 그 사실을 찍고 설치를 계속합니다. 옛 이름(.tar.gz.sig)만 들고 온 번들은 검증을 건너뛴 채로 설치됩니다. 화면에 찍히는 0단계 줄을 반드시 읽으십시오.

그리고 이 검증은 전송 중 손상과 일부만 바꿔치기한 경우를 잡습니다. 번들을 통째로 바꿀 수 있는 상대라면 곁파일도 함께 바꿀 수 있습니다 — 그래서 보안 검토가 필요한 현장에서는 키를 번들이 아닌 경로로 따로 받아 검증하십시오.

3번이 이 스크립트의 값어치입니다. 빠진 이미지가 있으면 설치를 시작하기 전에 그 이름을 찍고 멈춥니다. 이것이 없으면 설치가 한참 진행되다가 레지스트리 풀 타임아웃으로 죽는데, 폐쇄망에서 레지스트리는 애초에 닿지 않는 곳입니다.

images/ 가 비었거나 tar 하나라도 로드에 실패하면 그 자리에서 멈춥니다 — 구멍 난 채로 설치를 시작하지 않습니다.

설치 뒤의 부팅 검증(./up.sh, ./stack-verify-boot.sh)과 운영 점검(./ops-check.sh)은 Docker 설치와 같습니다.

폐쇄망 업데이트​

새 판으로 번들을 다시 구워 같은 절차로 옮긴 뒤, 새 번들을 풀고 그 안의 bin/airgap-load.sh 를 다시 실행합니다. 설치된 스택이 있으면 업그레이드로 판단해 먼저 백업하고([2.9] An installed stack was found … this is an UPGRADE), 이미지를 load 한 뒤 설치기를 돌립니다. 실패하면 이전 판으로 자동으로 되돌립니다 — 지원 범위와 백업 · 되돌리기는 업그레이드에 있습니다.

  • 되돌리기에는 이전 판의 이미지가 서버에 남아 있어야 합니다. 지웠다면 이전 번들을 다시 docker load 합니다
  • ./update.sh 로 컨테이너만 재생성하는 것은 업그레이드가 아닙니다 — 운영 스크립트 · compose 가 옛 판 그대로 남습니다

자주 빠지는 함정​

증상원인조치
번들이 만들어지다 «이미지를 하나도 못 찾았다» 로 끝난다굽는 장비에 플랫폼 자격증명이 없다사이드카를 먼저 잡고 다시 실행
워커가 뜨지 않는다INCLUDE_DATALAKE=0 으로 구운 번들기본값(1)으로 다시 굽는다
설치 도중 레지스트리 풀 타임아웃번들에 없는 이미지를 스택이 요구airgap-load.sh 가 찍은 «없는 이미지» 목록대로 다시 굽는다
대상 서버가 Ubuntu 인데 도커가 안 깔린다rpm 만 담긴 번들OS_TARGET=ubuntu 또는 both 로 다시 굽는다

더 알아보기​