최근 회사에서 진행 중인 공공기관 시스템 구축 프로젝트를 맡게 되었다.
공공기관 특성상 보안 정책이 매우 엄격해서, 클라우드 인프라를 활용할 수 없고 완전한 온프레미스(On-Premise) 환경 위에서 서비스를 운영해야 했다.
그런데 배포 절차를 살펴보다가 이런 부분이 눈에 띄었다.
“배포 중에는 서비스가 중단될 수 있습니다.
공지 후 재배포를 진행하세요.”
즉, 배포 과정에서 서비스 중단이 전제된 구조였다.
하지만 요즘 사용자는 1~2분의 중단에도 민감하게 반응한다.
그래서 “이 온프레미스 환경에서도 무중단 배포가 가능할까?”라는 궁금증이 생겼고,
그걸 직접 조사하고 정리해본 내용을 기술 블로그 형태로 남겨보려 한다.

무중단 배포란 무엇인가?
무중단 배포(Zero Downtime Deployment)는 말 그대로 서비스 중단 없이 새로운 버전을 배포하는 기법이다.
핵심 원리는 단순하다.
- 기존 버전이 요청을 처리하는 동안
- 새로운 버전을 배포하고
- 검증이 끝나면 트래픽을 새 버전으로 전환한다.
즉, 한쪽에서는 계속 서비스가 유지되고 다른 한쪽에서는 새로운 코드가 준비되는 구조다.
이걸 실현하려면 두 가지 전제가 필요하다.
- 로드 밸런서(또는 프록시) : 트래픽 전환을 담당
- 이중 서버 환경(Blue/Green 구조 등) : 구버전과 신버전이 동시에 존재
문제는 온프레미스 환경에서는 이런 구조를 기본적으로 제공하지 않는다는 점이었다.
그래서 실제 구축 가능한 여러 접근법을 찾아봤다.
온프레미스 환경에서 고려 가능한 무중단 배포 방식
조사해본 결과, 온프레미스 환경에서도 비교적 현실적으로 적용 가능한 방법은 아래 다섯 가지였다.
| 배포 방식 | 개념 | 장점 | 단점 |
| Blue-Green Deployment | 두 개의 동일한 환경(Blue=현재, Green=신규)을 두고, 배포 완료 후 트래픽 스위칭 | 완전한 롤백 가능 | 인프라 2배 필요 / DB 마이그레이션 시 복잡 |
| Rolling Deployment | 서버를 순차적으로 교체 | 인프라 절약 점진적 전환 |
구버전 혼재 가능 |
| Docker 기반 Blue-Green | 컨테이너 단위로 버전 교체 | 자동화 용이 롤백 간편 |
Docker 인프라 필요 |
| Canary Deployment | 일부 서버(혹은 요청)에만 새 버전 배포 후 점진 확대 | 문제 발생 시 영향 최소화 | 트래픽 분산 제어가 필요 / 자동화 어려움 |
| A/B Deployment | 특정 조건(유저, 지역, 세션 등)에 따라 다른 버전 제공 | 실험/테스트에 적합 | 인프라 관리 복잡 / 배포와는 다소 목적 다름 |
Blue-Green Deployment 방식
가장 먼저 검토한 것은 Blue-Green 방식이었다.
이 방식은
- 현재 운영 중인 시스템(Blue)과
- 새 버전이 올라갈 시스템(Green)을 동시에 운영하고 검증이 끝나면 트래픽을 Green 쪽으로 전환하는 구조다.
[사용자] → [Nginx Proxy] → [Blue Server / Green Server]
Nginx 같은 프록시 서버를 통해 두 서버 간 트래픽을 전환할 수 있다.
설정 파일의 upstream 블록을 바꾸고 reload 명령을 수행하면 실제로 서비스 중단 없이 트래픽 전환이 가능하다고 알려져 있다.
Blue-Green 방식의 가장 큰 장점은 완벽한 롤백이 가능하다는 점이다.
만약 새 버전에서 문제가 발생하면 단순히 Nginx 설정을 다시 Blue로 돌려놓기만 하면 된다.
다만, 두 개의 완전한 환경을 동시에 유지해야 하므로 인프라 리소스가 두 배로 필요하고
DB 스키마 변경이 포함된 배포에서는 버전 간 호환성 문제가 생길 수 있다.
Rolling Deployment 방식
그 다음은 Rolling 배포 방식이다.
서버가 2대 이상이라면 각 서버에 순차적으로 새 버전을 올리는 형태다.
예를 들어 서버가 A, B 두 대라면
A를 제외하고 B에 새 버전을 배포 → 검증 후 A에도 반영 → 트래픽 균등화
이런 순서로 진행된다.
이 경우 한쪽 서버는 항상 사용 가능한 상태로 남아 있으므로 서비스 전체가 동시에 멈추는 일은 없다.
이 방식은 로드 밸런서(Nginx, HAProxy 등) 를 통해 특정 서버를 일시적으로 제외시키는 식으로 구현할 수 있다.
Nginx의 upstream 블록에서 아래처럼 특정 서버를 임시로 빼는 식이다.
upstream backend {
server 192.168.0.10:8080;
# server 192.168.0.11:8080 down; # 배포 중인 서버
}
다만, 배포 타이밍이 서버별로 다를 경우
일시적으로 구버전과 신버전이 섞여 있는 상태가 발생할 수 있다는 점은 주의해야 한다.
Docker 기반 Blue-Green 구조
요즘 많은 곳에서 Docker를 사용하기 때문에 온프레미스에서도 Docker를 기반으로 한 Blue-Green 구조를 고려해볼 수 있다.
Docker를 이용하면 “컨테이너 단위로” Blue와 Green 환경을 운영할 수 있다.
예를 들어,
- 기존 컨테이너(app_blue)는 현재 서비스 중
- 새 버전(app_green)을 새로운 이미지로 띄운 뒤
- Nginx가 트래픽을 Green 컨테이너로 전환
이런 구조다.
특히 nginx -s reload를 이용하면 실제 요청이 끊기지 않은 상태에서 전환이 가능하다.
Docker 이미지 단위로 배포하기 때문에 이전 버전으로의 롤백도 매우 빠르다.
다만, 이는 Docker 인프라가 이미 구축되어 있는 환경이어야 적용이 가능하고 공공기관처럼 보안 제약이 많은 환경에서는 Docker 도입 자체가 어려운 경우가 대부분이다.
DB 마이그레이션 시 고려사항
조사를 하면서 가장 까다로워 보였던 부분이 바로 DB 변경이었다.
코드 배포는 Blue/Green 구조로 처리할 수 있지만 DB 스키마가 바뀌면 이야기가 달라진다.
무중단 배포를 위해서는 Forward & Backward Compatibility가 보장되어야 한다.
즉,
- 새 버전이 추가된 스키마에서도
- 기존 버전의 코드가 정상 동작해야 한다.
그래서 보통은 다음과 같은 순서를 권장한다.
- DB 스키마 먼저 확장 (새 컬럼 추가, nullable 유지)
- 새 버전 배포
- 데이터 이전(Migration)
- 구버전 제거
- 스키마 정리 (불필요 컬럼 삭제)
이 순서를 따르면 DB 변경이 포함된 배포에서도 비교적 안전하게 무중단 전환이 가능하다.
공공기관 온프레미스 환경에서의 현실적인 선택
공공기관 프로젝트의 경우 클라우드 서비스나 쿠버네티스(Kubernetes) 같은 고도화된 배포 환경을 도입하기 어렵다.
그래서 다음과 같은 기준으로 현실적인 접근이 필요하다고 느꼈다.
| 상황 | 추천 방식 | 비고 |
| 서버가 1대뿐 | Nginx + Docker Blue-Green (컨테이너 단위 전환) | 물리 서버 하나 내에서 컨테이너로 분리 |
| 서버가 2대 이상 | Nginx + Rolling 방식 | LB를 통한 점진적 배포 |
| Docker 인프라 구축 가능 | Blue-Green 구조 | 이미지 기반 롤백 지원 |
| 쿠버네티스 환경 존재 | RollingUpdate 전략 | 자동화 가능 (단, 대부분의 공공기관은 어려움) |
(1) Nginx + Blue-Green 구조
구성 예시:
- 서버 A (Blue): 현재 서비스 중
- 서버 B (Green): 새 버전 배포
- Nginx(또는 L4 LB)가 트래픽을 두 서버 중 하나로만 라우팅
절차:
- 서버 B에 새 버전 배포
- 헬스체크 (정상 작동 확인)
- Nginx 설정 스위치 (upstream 변경)
- Nginx reload (다운타임 없이 설정 갱신)
- 일정 기간 모니터링 후 서버 A 종료
(2) Tomcat + Rolling 방식 (무중단 Redeploy)
Spring Boot WAR 배포나 Tomcat을 사용하는 환경이라면, 로드밸런서와 여러 인스턴스를 통해 순차 배포가 가능해.
절차:
- 서버가 2대 이상일 경우
→ 하나씩 Tomcat 재기동 또는 새 버전 교체 - LB에서 해당 서버 트래픽 제외 → 배포 → 헬스체크 → LB 재등록
- 이를 반복
→ 스크립트나 Jenkins Pipeline으로 자동화하면 효율적
(3) Docker 기반 Rolling / Blue-Green
예시:
- Docker Compose 혹은 Kubernetes 없이도 docker run -d --name app_v2 식으로 새 컨테이너 띄우고 Nginx가 두 컨테이너 중 하나로 라우팅
- 완전히 검증 후 기존 컨테이너 종료
장점:
- 이미지 기반 배포로 일관성 확보
- rollback 용이 (이전 이미지로 교체)
(4) Kubernetes 사용 시
온프레미스에서도 K8s 클러스터를 구축할 수 있다면,
- RollingUpdate, BlueGreen, Canary 전부 자동 지원
- Deployment 리소스에서 전략(strategy) 지정만 하면 됨
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
정리
이번에 무중단 배포 구조를 조사하면서 느낀 점은 온프레미스 환경에서는 기술적인 어려움보다 조직적·정책적 제약이 더 크다는 것이다.
클라우드처럼 자동화된 기능이 없기 때문에 프록시 서버(Nginx), 간단한 스크립트, 혹은 Docker와 같은 도구를 조합해 직접 설계해야 한다.
다만, 그런 한계 속에서도 Blue-Green이나 Rolling 방식을 적절히 적용하면 공공기관 환경에서도 충분히 안정적인 무중단 배포 환경을 구축할 수 있다.
주어진 환경에서 가장 현실적인 선택을 하기 위한 조사
