클라우드 컴퓨팅과 마이크로서비스 아키텍처(MSA)가 지배하는 현대 프로덕션 환경에서 인프라스트럭처의 본질은 '관리 대상'에서 '소모품'으로 진화했습니다.
과거에는 서버에 이름을 붙여주고 정성스럽게 관리하는 "Pets" 모델이 주류였으나, 현재 하이퍼스케일 환경에서는 장애가 발생하거나 업데이트가 필요할 때 미련 없이 서버를 교체해 버리는 "Cattle" 모델이 표준이 되었습니다. 이러한 패러다임 전환의 중심에 불변 인프라(Immutable Infrastructure) 가 있습니다.
이 글에서는 Immutable Infrastructure가 시스템 안정성과 보안의 핵심 원칙으로 자리 잡은 이유와 그 아키텍처적 장점, 그리고 구현 시 피할 수 없는 비즈니스 및 운영 관점의 트레이드오프를 심층 분석합니다.
기존의 가변 인프라(Mutable Infrastructure)는 하나의 서버가 프로비저닝된 이후, 수개월에서 길게는 수년 동안 운영체제 위에서 수많은 설정 변경과 애플리케이션 패치가 누적되는 구조입니다.
운영자가 SSH로 서버에 접속하여 패키지를 업그레이드하고 설정 파일을 수정하는 행위는 직관적이고 빠르지만, 규모가 커지면 치명적인 문제를 야기합니다.
수십 대의 웹 서버가 있다고 가정해 봅시다. 긴급 장애 처리(Hotfix)를 위해 운영자가 일부 서버의 설정만 수동으로 변경하고 문서화를 누락한다면, 클러스터 내 서버들의 상태는 시간이 지남에 따라 조금씩 달라집니다. 이 현상을 Configuration Drift라고 부릅니다.
예를 들어, 처음에는 웹 서버 10대가 모두 동일한 설정(Java 21, timeout=30, 동일한 Nginx 설정)으로 운영되고 있었다고 가정해 보겠습니다.
어느 날 Server7에서만 장애가 발생하여 운영자가 SSH로 접속한 뒤 timeout=30을 timeout=60으로 변경해 문제를 해결했습니다. 하지만 이 변경 사항을 Git이나 IaC(Terraform, Ansible)에는 반영하지 않았고 문서도 작성하지 않았습니다.
며칠 뒤에는 Server3에서 또 다른 문제가 발생하여 Java 버전을 21에서 22로 변경했고, 이후에는 Server5의 Nginx 설정까지 수정했습니다.
결국 서버들의 상태는 다음과 같이 달라집니다.
| 서버 | 상태 |
|---|---|
| Server1 | 기본 설정 |
| Server2 | 기본 설정 |
| Server3 | Java 22 |
| Server4 | 기본 설정 |
| Server5 | Nginx 설정 변경 |
| Server6 | 기본 설정 |
| Server7 | timeout=60 |
| Server8 | 기본 설정 |
| Server9 | 기본 설정 |
| Server10 | 기본 설정 |
겉으로 보기에는 모두 같은 웹 서버처럼 보이지만, 실제로는 서버마다 조금씩 다른 설정을 가지게 됩니다. 이러한 상태가 바로 Configuration Drift입니다.
이러한 개별 서버들은 세상에 단 하나밖에 없는 고유한 설정을 가진 이른바 "Snowflake Server"가 됩니다.
테스트 환경에서는 완벽하게 동작하던 코드가 특정 프로덕션 서버에서만 에러를 뿜어내는 원인 불명의 장애(Heisenbug)를 유발합니다. 예를 들어 테스트 서버와 대부분의 운영 서버에서는 정상 동작하지만, timeout=60으로 변경된 Server7에서만 예외가 발생하는 상황이 대표적인 사례입니다.
특정 서버가 다운되었을 때 해당 서버를 처음부터 다시 구축하여 동일한 상태로 복원하는 것이 사실상 불가능해집니다. 운영자가 SSH로 직접 수정한 설정이 Git이나 문서에 남아 있지 않기 때문에, 새로운 서버를 만들어도 이전 Server7과 완전히 동일한 환경을 재현할 수 없기 때문입니다.
이러한 불확실성을 제거하기 위해 "서버를 패치하지 말고 교체하라(Trash Your Servers and Burn Your Code)"는 철학이 등장했습니다.
Immutable Infrastructure의 핵심 원칙은 "한 번 배포된 서버의 상태나 설정은 런타임에서 절대 수정(Update)되지 않는다" 는 것입니다.
v1.1 패치가 필요하다면, 기존에 돌아가던 v1.0 서버에 접속해 패치를 설치하는 것이 아닙니다.v1.1 "Golden Image" 를 빌드한 뒤, 새로운 인스턴스로 교체하고 이전 서버를 폐기합니다.이미지(Docker Image 또는 AWS AMI) 단위로 배포되므로, 개발자의 로컬 환경, Staging, Production 환경이 바이트 단위까지 정확히 동일합니다. "내 PC에서는 되는데..."라는 고질적인 변명을 근원적으로 차단하며, 환경 간 불일치로 인한 장애를 0에 수렴하게 만듭니다.
가변 인프라에서 실패한 패치를 되돌리려면 의존성 충돌이나 깨진 패키지로 인해 시스템이 망가질 위험이 매우 큽니다.
반면 불변 인프라에서는 애플리케이션 계층의 롤백이 이미지 단위로 예측 가능해집니다.
단, 롤백 자체가 항상 100% 멱등성(Idempotent)을 보장하는 것은 아닙니다.
DB 마이그레이션이 수행되었거나, 외부 API 상태가 변경된 경우 완전한 롤백은 어려울 수 있습니다.
핵심은 "애플리케이션 계층의 롤백은 이미지 교체로 즉각 수행되며, 인프라 프로비저닝 과정은 코드를 통해 멱등성을 갖도록 설계할 수 있다" 는 점입니다.
불변 인프라에서는 프로덕션 서버에 대한 원격 접속을 차단하고 컨테이너 루트 파일 시스템을 읽기 전용(Read-only Root FS) 으로 마운트하여 공격 표면(Attack Surface)을 극적으로 줄입니다.
이러한 런타임 불변성은 악의적인 코드 주입 방어를 넘어 비즈니스적 이점을 제공합니다.
인프라가 코드로 관리되고 런타임 변경이 원천 차단되므로, ISMS-P(정보보호 관리체계) 인증이나 클라우드 규정 준수를 증명하기 위한 기업의 보안 감시가 고도로 자동화되고 수월해집니다.
Immutable Infrastructure를 구축하는 표준적인 파이프라인은 크게 코딩, 베이킹(Baking), 배포로 나뉩니다.
IaC (Infrastructure as Code): 서버의 OS 베이스 이미지부터 애플리케이션 설치, 설정 파일 주입까지 모든 과정을 코드(Terraform, Ansible)로 선언합니다.
Image Baking (HashiCorp Packer / Docker): HashiCorp Packer를 이용해 클라우드 환경용 독립 실행형 이미지(예: AWS AMI, GCP Custom Image)를 구워내거나 Docker Image Build를 수행합니다.
Immutable Provisioning (Terraform / Kubernetes): 구워진 이미지를 바탕으로 새 인스턴스 클러스터를 프로비저닝합니다.
불변 인프라의 배포 무중단성을 보장하는 가장 강력한 패턴이 Blue/Green 배포입니다.
기존 버전(Blue)이 서비스 중일 때, 새 버전의 완전히 독립적인 인프라 클러스터(Green)를 구성합니다.
Green 환경에서 모든 E2E 테스트를 완료하면 로드 밸런서(LB)의 트래픽 라우팅만 Green으로 스위칭합니다. 장애가 발생하면 즉시 트래픽을 기존 Blue로 돌려(Rollback) 피해를 최소화할 수 있습니다.
불변 인프라 도입은 다음과 같은 비즈니스 및 운영 관점의 트레이드오프를 수반합니다.
불변 인프라는 장기적인 운영 리스크를 감소시키는 대신, 단기적인 구축 및 파이프라인 유지보수 비용(OPEX)을 크게 증가시킵니다.
서버를 "Cattle"처럼 다루다 보면, 오토 스케일링으로 인해 수십, 수백 개의 인스턴스가 수시로 생성되고 사라집니다. 이때 철저한 네이밍 컨벤션과 태깅(Tagging) 정책이 강제되지 않으면 문제가 발생합니다.
서버가 언제든 Terminate 될 수 있다는 것은 로컬 파일시스템에 영구 데이터를 저장해서는 안 됨을 의미합니다.
유저 세션은 Redis 등 인메모리 캐시로, 업로드 파일은 S3와 같은 외부 스토리지로 완전히 분리(Stateless)해야 합니다.
트러블슈팅 방식 역시 직접 접속을 배제하고, 모든 로그와 메트릭을 외부 시스템(Datadog, Prometheus, ELK)으로 스트리밍하는 중앙 집중형 옵저버빌리티(Observability) 구축이 조건이 됩니다.
Immutable Infrastructure는 단순히 서버를 교체하는 배포 기법이 아닙니다.
운영 환경의 상태를 예측 가능하게 만들고, 시스템의 일관성과 재현성을 보장하기 위한 아키텍처 원칙입니다.
Configuration Drift를 제거하고, Snowflake Server의 생성을 원천적으로 방지하며, 장애 복구와 롤백을 예측 가능한 프로세스로 만드는 것이 바로 Immutable Infrastructure의 가장 큰 가치입니다.
물론 모든 시스템이 반드시 Immutable Infrastructure를 적용해야 하는 것은 아닙니다.
이미지 빌드 시간, 배포 파이프라인 구축 비용, 운영 복잡성 등은 분명한 트레이드오프이며, 작은 규모의 서비스나 빠른 MVP 검증 단계에서는 Mutable Infrastructure가 더 합리적인 선택일 수도 있습니다.
결국 중요한 것은 "Immutable인가, Mutable인가"가 아니라 비즈니스 요구사항과 서비스의 복구 목표(RPO/RTO), 운영 규모를 고려하여 가장 적절한 운영 모델을 선택하는 것입니다.
좋은 아키텍처는 특정 기술을 맹목적으로 도입하는 것이 아니라,
일관성(Consistency), 재현성(Reproducibility), 운영 효율성(Operational Excellence), 그리고 비즈니스 비용 사이에서 최적의 균형점을 찾는 과정이라는 점을 기억해야 합니다.