오프라인 / 폐쇄망 설치 (Air-gap)
인터넷 접근이 차단된 사이트 (군시설 / 보안 등급 시설 / 일부 공장) 에 게이트웨이를 깔 때 사용하는 절차입니다.
표준 빠른 설치 는 product.kopens.io 도달이 필요한데, 폐쇄망에선 그게 안 되므로
외부에서 산출물 받아 와서 USB / NAS 로 옮긴 다음 깔아야 합니다.
컨테이너 모드 (2026.05+, 권장)
install 패키지 + 컨테이너 이미지 tar.zst 두 가지를 옮깁니다. install.sh 가 sibling
image/*.tar.zst 를 감지하면 docker load 로 자동 import (registry pull 우회).
준비 PC (인터넷 가능)
반출 번들은 손으로 만들지 말고 airgap-bundle.sh 로 굽습니다. 저장소 파일과 컨테이너 이미지를
한 덩어리로 묶어주므로 버전이 어긋날 일이 없습니다. GitLab 에서는 airgap:export 수동 잡을
돌린 뒤 artifacts 로 내려받아도 됩니다.
# 1) 저장소 받기
curl -fsSLO https://product.kopens.io/plantpulse-edge/plantpulse-edge-docker.tar.gz
mkdir -p plantpulse-edge-docker
tar xzf plantpulse-edge-docker.tar.gz -C plantpulse-edge-docker --strip-components=1
# 2) 반출 번들 굽기 — 저장소 + 이미지가 함께 들어간다
sudo bash plantpulse-edge-docker/bin/airgap-bundle.sh
# 3) USB / NAS 로 옮김 (파일명 예: plantpulse-edge-images-2026.07.tar.gz)
cp plantpulse-edge-images-*.tar.gz /media/usb/
폐쇄망 박스 (인터넷 없음)
sudo -i
mkdir -p /opt/kopens/plantpulse-edge-docker
tar xzf /media/usb/plantpulse-edge-images-*.tar.gz \
-C /opt/kopens/plantpulse-edge-docker --strip-components=1
cd /opt/kopens/plantpulse-edge-docker/repo/bin
# 필요하면 env.sh 에서 EDGE_ID / SITE_ID 를 박스별로 조정한 뒤 실행
sudo bash airgap-load.sh
# airgap-load.sh: 오프라인 Docker 설치 → 이미지 docker load → install.sh(SKIP_PULL=1)
설치 후 컨테이너 모드로 검증:
sudo bash /opt/kopens/install/bin/status.sh
sudo bash /opt/kopens/install/bin/health.sh
curl -ks https://127.0.0.1/api/v1/system/version | python3 -m json.tool
curl -ks https://127.0.0.1/api/v1/system/health | python3 -m json.tool
폐쇄망도 설치 완료 기준은 동일합니다. 운영 투입 전 프로덕션 인수 기준에 따라 백업 파일, acceptance log, image tag, 자격증명 전달 여부를 남깁니다.
(legacy) Native 모드 air-gap 절차
아래 절차는 2026.05 미만 native 박스 전용. 신규 배포는 위의 컨테이너 모드를 사용하세요.
1. 준비물
| 항목 | 비고 |
|---|---|
| 인터넷 연결된 준비 PC | 산출물 다운로드용 (사무실 PC 면 OK) |
| USB 디스크 (32GB+ 권장) | 산출물 + 의존 패키지 RPM 운반 |
| PlantPulse 산출물 | KOPENS_EDGE_V<버전>.tar.zstd (~1GB) |
install.sh 사본 | 폐쇄망에서도 동작하도록 일부 수정 필요 (URL → 로컬 경로) |
| OS RPM 패키지 | dnf 가 인터넷 안 가는 환경에서 설치할 수 있도록 미리 받음 |
2. 준비 PC 에서 (인터넷 가능)
2.1 산출물 + install.sh 다운로드
# USB 마운트 위치
USB=/mnt/usb
# 산출물 (가장 최신 버전 — 약 1GB)
curl --proto =https --tlsv1.2 --fail \
-o $USB/KOPENS_EDGE_V2026.tar.zstd \
https://product.kopens.io/plantpulse-edge/KOPENS_EDGE_V2026.tar.zstd
# install.sh 도 같이 (참고용 — 폐쇄망에선 수정 후 사용)
curl --proto =https --tlsv1.2 --fail \
-o $USB/install.sh \
https://product.kopens.io/plantpulse-edge/install.sh
# (옵션) sha256 검증 파일
curl --proto =https --tlsv1.2 --fail \
-o $USB/install.sh.sha256 \
https://product.kopens.io/plantpulse-edge/install.sh.sha256 || true
2.2 OS 의존성 RPM 다운로드 (Fedora 38 기준)
setup.sh 가 dnf 로 설치하는 패키지들을 미리 다운만 해서 USB 에 담음:
# 빈 디렉토리
mkdir -p $USB/rpms
cd $USB/rpms
# setup.sh 의 dnf install 라인의 패키지 목록
PKGS="tar htop fping pv firefox java-17-openjdk-devel jna jemalloc \
jemalloc-devel zstd curl-devel expat-devel uuid wget sysstat \
chrony tuned net-tools numactl nodejs npm python3 fail2ban \
gcc glibc-devel zlib-devel libstdc++-static NetworkManager-tui \
docker-ce docker-ce-cli containerd.io \
java-17-amazon-corretto-devel"
# 의존성 포함 다운로드 (--downloadonly + --resolve)
sudo dnf install --downloadonly --resolve --downloaddir=$USB/rpms $PKGS
2.3 install.sh 수정 (URL → 로컬 경로)
# install.sh 의 다운로드 부분을 USB 경로로
sed -i 's|https://download\.kopens\.[a-z]*\.com|file:///mnt/usb|g' $USB/install.sh
sed -i 's|https://download\.kopens\.[a-z]*\.io|file:///mnt/usb|g' $USB/install.sh
# (혹은 install.sh 내부의 `curl ... KOPENS_EDGE_*.tar.zstd` 라인을 직접 편집해 USB 경로 사용)
USB 안전하게 분리.
3. 폐쇄망 게이트웨이에서
3.1 USB 마운트 + RPM 일괄 설치
# USB 인식
sudo mount /dev/sdb1 /mnt/usb # 디바이스 명은 환경마다 다름
# RPM 일괄 설치 (의존성 자동 해결)
sudo rpm -Uvh --force --replacepkgs /mnt/usb/rpms/*.rpm
# (옵션) tar 보관소가 있으면 dnf 로도 가능:
# sudo dnf install --disablerepo=* --nogpgcheck /mnt/usb/rpms/*.rpm
3.2 산출물 압축 해제
sudo mkdir -p /opt
cd /opt
sudo tar -I 'zstd -d' -xvf /mnt/usb/KOPENS_EDGE_V2026.tar.zstd
# /opt/kopens 에 풀림
3.3 H/W 초기화 (선택) — tools/setup.sh 의 의존성 단계는 건너뛰고
dnf install 단계는 이미 RPM 으로 처리했으므로, 직접 setup.sh 일부 단계만 수동 실행:
sudo -i
cd /opt/kopens/tools
# 호스트명
hostnamectl set-hostname EDGE_<번호>
# env.sh 생성
cat > /opt/kopens/plantpulse-edge/conf/env.sh << EOF
export KOPENS_HOME=/opt/kopens
export PE_HOME=/opt/kopens/plantpulse-edge
export PE_DATA_DIR=/data1
export JAVA_HOME=/usr/lib/jvm/java-17-amazon-corretto
export CLEAN_ON_STARTUP=true
EOF
mkdir -p /data1
# 네트워크 (대화형)
./net/set-1.sh
./net/set-2.sh
systemctl restart NetworkManager.service
# 로케일 + 타임존
localectl set-locale LANG=ko_KR.utf8
timedatectl set-timezone Asia/Seoul
# tuned + 방화벽 + sysctl + chrony + ssl + vpn
systemctl enable --now tuned
tuned-adm profile throughput-performance
./firewall/open.sh
./file/run.sh
./ssl/gen.sh
# ./vpn/setup.sh # 폐쇄망에선 보통 미사용
# CPU governor + hugepages
for f in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do echo performance > $f; done
echo 9216 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
# systemd 서비스 등록
cp /opt/kopens/tools/service/plantpulse.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable plantpulse
3.4 시작
sudo systemctl start plantpulse
sleep 60 # 풀스택 부팅 대기
/opt/kopens/plantpulse-edge/bin/ps.sh
curl -s http://127.0.0.1/api/v1/system/health | jq
4. 업그레이드 (폐쇄망)
upgrade.sh 의 자동 다운로드는 인터넷이 필요해 사용 못 합니다. 수동 절차:
# 1. 준비 PC 에서 새 산출물 USB 로 옮김 (위 2.1 동일)
# 2. 폐쇄망 게이트웨이에서:
sudo /opt/kopens/plantpulse-edge/bin/backup.sh
sudo /opt/kopens/plantpulse-edge/bin/stop.sh
cd /opt
sudo mv kopens kopens.old.$(date +%Y%m%d-%H%M%S)
sudo tar -I 'zstd -d' -xvf /mnt/usb/KOPENS_EDGE_V<신버전>.tar.zstd
sudo /opt/kopens/plantpulse-edge/bin/start.sh
검증 후 kopens.old.* 디렉토리 보존 (혹은 디스크 부족 시 삭제).
5. 자주 빠지는 함정
| 증상 | 원인 / 해결 |
|---|---|
dnf install 이 인터넷 못 찾아 멈춤 | --disablerepo=* 옵션을 빼먹음. 위 3.1 의 옵션 그대로 |
tar: Error opening archive | USB 의 산출물이 파일 일부만 복사됨. 준비 PC 에서 sha256 비교 후 재복사 |
| systemctl status plantpulse → activating | bin/start.sh 의 단계 중 어디서 막힘. journalctl -u plantpulse -f 로 라이브 |
| 시각이 안 맞음 (1970년) | 폐쇄망에 NTP 미접근. 사내 NTP 서버 IP 를 /etc/chrony.conf 에 추가 |
| docker 가 안 깔림 | RPM 다운로드 시 docker-ce 누락. Fedora 의 docker repo 추가 후 재다운 |
| install.sh 가 download URL 호출 | sed 수정 누락 — install.sh 내 모든 URL 을 file:///mnt/usb/... 로 |
6. 더 알아보기
- 인터넷 가능 시 표준 절차: 빠른 설치
- legacy native 설치: (legacy) H/W 전체 설치
- 프로덕션 인수 기준: 프로덕션 인수 기준
- 백업으로부터 복구 (재해): 백업 / 복구
- 신버전 적용 (인터넷 가능): 업그레이드 (
upgrade.sh)