서빙·인프라

폐쇄망 클라우드에 ML 서비스 배포하기: 컨테이너 반입 파이프라인 구축기

인터넷이 없는 발주기관의 쿠버네티스 기반 폐쇄망 클라우드에 3-티어 ML 서비스를 배포했습니다. 밖에서 완성해 통째로 들여보내고 안에서 자급하는 반입 파이프라인의 구조와, ML 서비스라서 더해지는 반입 목록을 정리합니다.

폐쇄망이라는 전제

한국 공공기관의 업무 환경은 망분리가 기본입니다. 인터넷이 차단되어 있고, 외부에서 만든 소프트웨어는 기관이 정한 매체와 절차로만 반입됩니다. 국가·공공기관에 도입되는 시스템은 유형에 따라 국가정보원의 보안적합성 검증 같은 사전 절차를 거치고, 정보시스템 구축에는 전자정부 표준프레임워크(eGovFrame)가 사실상 표준으로 요구됩니다.

운수종사자 사고 위험 예측 시스템을 위탁사업으로 수행하면서 이 전제를 처음부터 설계에 넣어야 했습니다. 배포 목적지는 발주기관이 운영하는 쿠버네티스 기반 폐쇄망 클라우드였고, 그 안에서는 pip installdocker pull도 Hugging Face 다운로드도 없습니다. 이 글은 그 환경에 ML 서비스를 들여보내면서 정리한 반입 파이프라인의 구조입니다.

배포 대상: 3-티어 ML 서비스

시스템은 세 덩어리입니다. React 관리 웹(대시보드·개인 진단·관리자 화면), 예측·재학습·SHAP 해석을 담당하는 FastAPI AI 엔진, 그리고 공공 요건에 맞춘 Spring Boot(eGovFrame) 백엔드입니다. 일반 웹 서비스와 같은 구성처럼 보이지만, ML이 끼면 반입 목록이 달라집니다. 코드만 들어가는 게 아니라 모델 산출물과 ML 의존성(수백 MB의 wheel)까지 전부 “다운로드 없이” 준비되어야 하기 때문입니다.

반입 파이프라인: 밖에서 완성, 통째로 반입, 안에서 자급

인터넷이 닿지 않는 클라우드에서는 배포의 중심 문제가 “무엇을 어떻게 반입할 것인가”로 바뀝니다. 폐쇄망에 쿠버네티스 플랫폼을 구축한 공개 사례들을 보면 공통 구조가 있습니다. 외부에서 이미지를 tar로 떠서 반입하고, 내부 사설 레지스트리에 적재한 뒤, 클러스터가 그 레지스트리만 바라보게 만드는 것입니다(공공 폐쇄망 K8s 플랫폼 구축기, 폐쇄망 배포 시스템 개발기). 이 과제의 배포도 같은 뼈대를 따랐습니다.

폐쇄망 클라우드 ML 배포 반입 파이프라인 — 외부망 빌드 존에서 서비스별 이미지를 만들어 tar로 고정하고, 보안 반입 절차를 거쳐 내부 사설 레지스트리에 적재한 뒤 쿠버네티스 클러스터에 배포하는 구조

단계별로 보면 이렇습니다.

1. 외부망에서 서비스별 이미지를 완성합니다. React는 정적 빌드 결과를 Nginx 이미지에 담고, AI 엔진은 ML 의존성 wheel을 빌드 시점에 전부 설치해 굽고, 백엔드는 jar와 JRE를 묶습니다. 핵심은 “런타임에 아무것도 내려받지 않는 이미지”입니다. 이미지 안에서 pip install이나 모델 다운로드가 일어나는 Dockerfile은 폐쇄망에서 그대로 죽습니다.

2. 베이스 이미지와 의존 차트까지 전수 목록화합니다. 폐쇄망 구축 사례들이 공통으로 지적하는 어려움이 이 지점입니다. 애플리케이션 이미지만 챙기면 되는 게 아니라, 베이스 이미지·사이드카·헬름 차트가 참조하는 CRD와 이미지까지 수십 개의 외부 파일을 사전에 전부 파악해 준비해야 합니다. 하나라도 빠지면 반입 절차를 처음부터 다시 밟게 되므로, “빠뜨리면 다시 못 가져온다”가 목록 작성의 기준이 됩니다.

3. docker save로 파일로 고정해 반입합니다. 이미지·매니페스트·운영 문서를 기관이 정한 매체와 심의 절차로 들여보냅니다. 태그는 반입 후 덮어쓸 수 없으므로, latest 같은 움직이는 태그 대신 버전 태그와 다이제스트로 식별을 고정하는 편이 안전합니다.

4. 내부 사설 레지스트리에 적재하고, 매니페스트의 이미지 경로를 재지정합니다. 클러스터의 모든 워크로드가 내부 레지스트리만 바라보게 만드는 것이 폐쇄망 쿠버네티스의 기본 형태입니다. 배포 이후의 갱신도 새 다운로드가 아니라 같은 반입 파이프라인의 반복입니다.

5. “떴다”와 “준비됐다”를 프로브로 구분합니다. 원격으로 들여다볼 수 없는 환경일수록 readiness/liveness 프로브를 성실하게 정의하는 것이 중요했습니다. ML 서비스는 프로세스 기동과 서비스 가능 상태의 간격이 특히 깁니다. 모델 로딩과 워밍업이 끝나기 전에 트래픽이 들어오면 초기 요청이 실패하는데, 이걸 구분해 주는 것이 readiness 프로브입니다.

발주기관 환경의 세부 구성은 기관의 자산이라 여기에 적지 않습니다. 위 도식도 특정 구성이 아니라 폐쇄망 반입 배포의 공통 구조로 일반화한 것입니다.

ML이라서 늘어나는 반입 목록

일반 웹 서비스와 달리 ML 서비스는 코드 밖 자산이 더 있습니다.

의존성 wheel. ML 파이썬 스택은 의존성이 무겁고 네이티브 바이너리가 많아, 소스가 아니라 플랫폼에 맞는 wheel로 준비해야 설치가 결정적입니다. 컨테이너로 배포하면 이 문제는 “이미지 빌드 시점에 전부 설치”로 흡수됩니다.

사전학습 모델과 임베딩 캐시. Hugging Face 계열은 미리 받아 캐시를 반입하고 런타임에 HF_HUB_OFFLINE=1을 걸어 허브 호출을 차단하는 것이 표준이지만, 라이브러리에 따라 오프라인 플래그를 걸어도 원격 연결을 시도해 타임아웃으로 기동이 늦어지는 사례가 보고됩니다(fastembed 사례). 캐시 경로를 명시적으로 고정하고, 네트워크를 끊은 상태에서 기동 스모크 테스트를 해 보는 것이 확실합니다.

학습 산출물의 자급 관리. 이 시스템은 부스팅 계열 모델이라 사전학습 모델 반입 문제는 없었지만, 대신 다른 결정을 했습니다. 학습 산출물(모델·캘리브레이터·설정)을 파일 트리가 아니라 DB에 버전 단위 BLOB으로 저장해, 모델 버전 목록·활성 전환·롤백을 관리자 화면에서 처리하게 한 것입니다. 외부 모델 레지스트리(MLflow·W&B류)를 쓸 수 없는 환경에서는 모델 버전 관리도 시스템 안에서 자급해야 합니다. 재학습이 중간에 죽어도 다음 기동 때 미완성 버전을 정리하고 복구하는 로직까지, 보통은 플랫폼이 해 주는 일을 애플리케이션이 스스로 담아야 했습니다.

취약점 스캔 준비. 반입 심의에서 취약점 스캔이 요구된다면 Trivy도 오프라인 모드(--skip-update, DB 사전 반입)로 준비해 둘 수 있습니다(공식 가이드).

검증: 오프라인을 코드로 증명하기

폐쇄망 배포에서 가장 값진 테스트는 화려한 통합 테스트가 아니라 네트워크를 끊고 처음부터 끝까지 돌려 보는 것이었습니다. 설치·기동·예측·재학습까지 외부 접근 없이 통짜로 성공해야 반입 후에도 성공합니다. 여기에 더해 “외부에 나가지 않는다”를 말이 아니라 코드로 증명하는 장치를 좋아하게 됐습니다. 예를 들어 파이썬 의존성 설치에 --no-index를 강제하면, 설치가 성공했다는 사실 자체가 오프라인 증명이 됩니다.

pip install --no-index --find-links "wheels" -r requirements.txt

배포물에 개발 흔적이 섞이는 사고도 폐쇄망에서는 회수가 어렵습니다. 그래서 빌드 마지막 단계에 잔여물 검사 게이트를 두고, __pycache__·*.db·.env·업로드 데이터 같은 것이 산출물에 하나라도 섞이면 빌드를 실패시켰습니다. 사람의 주의가 아니라 스크립트가 막게 하는 것입니다.

공개 저장소: 클라우드 없이 재현되는 설치형 트랙

이 시스템의 공개 저장소 driver-risk-prediction-platform은 실무 구현을 익명화해 재구성한 것인데, 배포 체계는 클라우드 의존 없이 단일 Windows PC에서 인터넷 없이 전 구간이 재현되는 오프라인 설치형(포터블 런타임 + wheel 동봉 zip, 약 400MB)으로 담았습니다. 쿠버네티스와 사설 레지스트리라는 전제 없이 누구든 배포 체계까지 돌려 볼 수 있게 하기 위한 선택이고, deploy/(build-package.sh, install.bat, nginx.conf)에 구현이 있습니다. 반입물 전수 목록화, 오프라인 설치 증명, 잔여물 게이트 같은 원칙은 두 트랙이 같습니다.

배운 것

  • 폐쇄망 배포의 본질은 목록 작성입니다. 이미지·베이스 이미지·wheel·모델·폰트까지, 다운로드가 필요한 모든 것을 빌드 시점에 확정하는 일이 기술의 대부분이었습니다. “빠뜨리면 다시 못 가져온다”는 전제가 목록의 완성도를 결정합니다.
  • 자급이 설계 기준이 됩니다. 모델 버전 관리·롤백·로그·복구까지, 밖의 서비스가 해 주던 일을 시스템 안에 넣어야 합니다. 갱신 전략도 부분 패치보다 상태 공간을 줄이는 쪽(통짜 교체 + 재학습)이 폐쇄망에서는 진단 가능성이 높았습니다.
  • 증명 가능한 오프라인이 심의도 운영도 쉽게 만듭니다. 네트워크 차단 스모크 테스트와 --no-index 같은 강제 장치는 “인터넷 안 씁니다”라는 설명을 코드 한 줄로 대체합니다.
폐쇄망쿠버네티스배포MLOps
관련 프로젝트
운수종사자 교통사고 위험 예측 모델·관리 웹 개발

행안부·NIA·한국교통안전공단(주관) 위탁사업. 검사 결과와 사고 이력을 학습한 앙상블 모델로 위험도를 예측하는 관리 웹을 개발하고, 발주기관의 쿠버네티스 기반 폐쇄망 클라우드 환경에 실제 배포까지 전 구간을 PL로 수행.

© 2026 Minsu Kang. All rights reserved.