한 줄 정의

애플리케이션 런타임은 애플리케이션의 실행·데이터·연결 요구사항을 배포 매니페스트로 선언하면 인프라 리소스를 동적으로 할당해 실행해 주는 계층입니다.

쉽게 말하면

출장을 가서 살 집을 직접 구하면 가구, 전기, 수도까지 전부 스스로 준비해야 합니다. 전통적인 배포가 이랬습니다. 서버를 먼저 마련하고 그 위에 앱을 설치하며, 방화벽이나 스토리지는 담당자에게 따로 부탁했습니다.

호텔은 다릅니다. “2인실, 조식 포함, 와이파이”라는 요구사항만 말하면 호텔이 알아서 방을 배정합니다. 몇 호실에 묵을지는 호텔(스케줄러)이 정하고, 프런트 안내(서비스 검색) 같은 공통 서비스도 호텔이 제공합니다.

배포 매니페스트가 바로 이 요구사항 명세서입니다. 앱은 “인스턴스 3~10개, 443 포트 헬스체크, 50GB 볼륨”만 선언하고, 어느 서버에서 어떻게 실행할지는 런타임 플랫폼이 결정합니다.

왜 중요한가?

전통적으로 앱 패키지는 서버 안쪽(포트, 인증서)까지만 책임지고, 서버 밖의 네트워킹·스토리지는 다른 사람이 별도로 구성해 주기를 의존해 왔습니다. 이 분업은 정적 환경에서는 통했지만, 인스턴스가 수시로 추가·제거·이동하는 동적 인프라에서는 사람이 따라갈 수 없습니다.

애플리케이션 중심(application-driven) 접근이 없으면 인프라를 먼저 만들고 앱을 끼워 맞추게 됩니다. 반대로 앱 포트폴리오의 런타임 요구사항을 먼저 분석하면, 팀이 특정 애플리케이션용 환경을 조합하는 데 쓸 재사용 가능한 스택과 컴포넌트를 설계할 수 있습니다.

핵심 내용

3계층 모델에서의 위치

애플리케이션 런타임은 애플리케이션과 인프라 플랫폼 사이의 계층으로, 인프라 관리 도구로 정의·생성하는 인프라 스택으로 구성됩니다.

런타임 계층의 구성 요소는 인프라 플랫폼의 리소스에 매핑됩니다.

런타임 계층 구성 요소기반 인프라 리소스
실행 환경컴퓨팅
데이터 관리스토리지
연결네트워킹

런타임 인프라를 설계하려면 먼저 애플리케이션을 이해해야 합니다. 어떤 언어·실행 스택인가, 서버·컨테이너·FaaS 중 무엇으로 패키징되는가, 단일 배포인가 클러스터 배포인가, 연결·데이터 요구사항은 무엇인가.

애플리케이션에서 배포 가능한 부분

릴리스에는 실행 파일 외에도 여러 요소가 포함될 수 있습니다.

요소내용
실행 파일릴리스의 핵심. 바이너리·스크립트와 사용하는 라이브러리
서버 구성프로세스용 사용자 계정, 폴더 구조, 시스템 구성 파일 변경
데이터 구조DB 스키마 생성·업데이트. 스키마 버전은 실행 파일 버전과 묶어 배포
참조 데이터신규 버전의 참조 데이터, 첫 설치를 돕는 예제 데이터
연결성네트워크 포트, 인증서·키
구성 파라미터구성 파일 복사 또는 레지스트리 푸시

애플리케이션과 인프라 사이의 선은 어디에나 그을 수 있습니다. 컨테이너 이미지는 OS 대부분을 앱 쪽으로 끌어오고, 변경 불가능한 서버·스택은 앱과 인프라를 단일 엔티티로 결합하며, 반대로 라이브러리·구성을 인프라 코드로 프로비저닝하면 앱 패키지에는 거의 남지 않습니다. 일반적으로 코드베이스의 구조는 이 배포 가능한 부분에 맞추는 것이 좋습니다.

타깃 런타임별 배포 패키지

타깃 런타임패키지 예
서버 운영 시스템Red Hat RPM, Debian .deb, Windows MSI
언어 런타임 엔진Ruby gem, Python pip 패키지, Java .jar·.war·.ear
컨테이너 런타임Docker 이미지
애플리케이션 클러스터Kubernetes Deployment, Helm 차트
FaaS 서버리스Lambda 배포 패키지

컨테이너 — 의존성을 앱 패키지로

컨테이너는 라이브러리·구성·사용자 계정 같은 의존성을 호스트 OS가 아니라 컨테이너 이미지에 번들로 담습니다. 패키지는 커지지만 얻는 것이 큽니다.

  • 앱과 의존성이 함께 움직이므로 서버마다 다를 수 있는 요소에 의존하지 않는 일관된 실행 환경 을 얻습니다
  • 실행되는 서버와 분리되어 실행 위치가 유연해집니다
  • 호스트 서버에는 컨테이너 실행 도구만 있으면 되므로 서버 요구사항이 단순·표준화됩니다
  • 환경 가변성이 줄어, 한 환경에서 테스트한 컨테이너가 다른 환경에서도 동일하게 동작한다고 합리적으로 확신할 수 있습니다 (QA 향상)

서버 클러스터 vs 애플리케이션 클러스터

flowchart TB
    deploy["배포 도구 (Capistrano, Fabric)<br/>서버별 반복 배포"] --> s1 & s2 & s3
    subgraph sc["서버 클러스터 — 모든 서버가 동일한 앱 집합"]
        direction LR
        s1["서버 1<br/>A, B"]
        s2["서버 2<br/>A, B"]
        s3["서버 3<br/>A, B"]
    end
    sched["스케줄러<br/>인스턴스 배치 결정"] --> h1 & h2 & h3
    subgraph ac["애플리케이션 클러스터 — 호스트마다 다른 인스턴스 그룹"]
        direction LR
        h1["호스트 1<br/>A, A, B"]
        h2["호스트 2<br/>B, C"]
        h3["호스트 3<br/>A, C"]
    end

서버 클러스터는 컨테이너 이전부터 쓰인 모델로, 각 서버가 동일한 애플리케이션 집합을 실행합니다. 여러 서버에 배포하므로 오케스트레이션을 결정해야 합니다. 한 번에 전부 배포할지, 그동안 서비스를 오프라인으로 전환할지, 한 대씩 업그레이드할지. blue-green·카나리 같은 점진적 배포 전략이 이 증분 배포를 활용합니다.

애플리케이션 클러스터에서는 스케줄러 가 알고리즘과 설정에 따라 어느 호스트에서 인스턴스를 추가·제거할지 결정합니다. Tomcat·WebSphere·WebLogic·JBoss 같은 Java 애플리케이션 서버에서, Google Borg에 영감을 받은 Mesos·DC/OS를 거쳐, 최근에는 컨테이너 오케스트레이션 시스템이 이 영역을 압도하고 있습니다.

배포 매니페스트 — 클러스터에 요구사항 선언

최신 런타임 플랫폼은 배포 가능한 조각을 전부 담은 아카이브 대신, 실제 아티팩트(컨테이너 이미지)를 참조 하는 배포 매니페스트를 사용합니다. Kubernetes용 Helm 차트, AWS ECS Services, Azure App Service Plans, CNAB(Cloud Native Application Bundle) 등이 이 부류입니다. 단일 배포 단위에 집중하는 매니페스트도 있고, 배포 가능한 서비스의 컬렉션과 공통 구성·통합 파라미터를 정의하는 매니페스트도 있습니다.

매니페스트는 런타임 환경이 알아야 하는 질문에 답합니다.

  • 최소/최대 몇 개의 인스턴스를 실행하는가
  • 인스턴스를 언제 추가·제거하는가
  • 인스턴스가 정상인지, 재시작해야 하는지 어떻게 아는가
  • 각 인스턴스에 어떤 스토리지를 프로비저닝하고 연결하는가
  • 네트워크 연결과 보안 요구사항은 무엇인가

ShopSpinner 웹 서버 배포 매니페스트의 슈도코드가 이 구조를 보여줍니다.

service:
  name: webservers
  organization: ShopSpinner
  version: 1.0.3
application:
  name: nginx
  container_image:
    repository: containers.shopspinner.xyz
    path: /images/nginx
    tag: 1.0.3
  instance:
    count_min: 3
    count_max: 10
    health_port: 443
    health_url: /alive
  connectivity:
    inbound:
      id: https_inbound
      port: 443
      allow_from: $PUBLIC_INTERNET
      ssl_cert: $SHOPSPINNER_PUBLIC_SSL_CERT
    outbound:
      port: 443
      allow_to: [ $APPSERVER_APPLICATIONS.https_inbound ]

컨테이너 이미지를 찾을 위치, 실행할 인스턴스 수, 헬스체크 방법, 인바운드·아웃바운드 네트워크 연결 규칙까지 하나의 명세로 선언합니다.

네트워크 연결도 매니페스트로

전통적으로 앱 패키지는 서버 안쪽(포트, 암호화 키)까지만 구성하고, 서버 밖 인프라(주소 지정, 라우팅, 네이밍, 방화벽 규칙)는 인프라 스택 프로젝트에서 별도로 정의해 왔습니다. 클라우드 네이티브 접근은 네트워크 요구사항을 매니페스트의 connectivity 블록으로 선언하고 런타임이 리소스를 동적으로 할당하게 합니다.

위 예제의 allow_to: [ $APPSERVER_APPLICATIONS.https_inbound ]처럼, 같은 클러스터에 자체 매니페스트로 배포되는 시스템의 다른 부분을 참조 해 연결을 정의하는 것이 핵심입니다.

FaaS 서버리스 배포

FaaS는 코드가 실행되는 서버·컨테이너의 세부를 숨기지만, 코드가 동작하려면 여전히 인프라가 필요할 수 있습니다. 인바운드·아웃바운드 네트워크 라우팅, 저장소, 메시지 큐 같은 것들입니다.

FaaS 프레임워크가 인프라 플랫폼과 통합해 필요한 인프라를 자동 프로비저닝하거나, Terraform·CloudFormation 같은 스택 도구에서 FaaS 코드 프로비저닝을 인프라 스택의 일부로 선언할 수 있습니다.

애플리케이션 데이터 — 사후 고려의 대가

데이터는 배포·실행에서 사후 고려사항이 되기 쉽지만, 데이터와 구조의 변경은 시간이 오래 걸리고 지루하며 위험합니다.

스키마 마이그레이션

데이터 구조 변경과 기존 데이터의 변환을 스키마 마이그레이션 이라고 합니다. name 필드를 first, middle, last로 분할하는 것이 전형적인 예입니다.

Flyway, DBDeploy, Liquibase, db-migrate 같은 도구로 증분 DB 변경을 코드로 정의하고, 버전 관리에 체크인해 릴리스의 일부로 패키징합니다. 이렇게 하면 DB 스키마가 인스턴스에 배포된 앱 버전과 동기화 상태를 유지합니다.

데이터 구조 업데이트는 인프라 플랫폼·런타임이 아니라 애플리케이션과 배포 프로세스의 영역 이어야 합니다. 이런 데이터베이스 진화 전략은 CI·CD·코드형 인프라를 포함한 애자일 접근 방식과 일치합니다.

클라우드 네이티브 스토리지

일부 플랫폼은 컴퓨팅·네트워킹뿐 아니라 스토리지도 동적으로 제공합니다. 매니페스트에 스토리지 요구사항을 선언하면, 시스템이 앱 인스턴스를 추가할 때 스토리지 장치를 자동으로 프로비저닝하고 연결합니다.

application:
  name: db_cluster
  compute_instance:
    memory: 2 GB
    container_image: db_cluster_node_application
  storage_volume:
    size: 50 GB
    volume_image: db_cluster_node_volume

동적으로 확장되는 데이터베이스 클러스터 노드의 정의입니다. 노드 인스턴스마다 플랫폼이 DB 소프트웨어 컨테이너를 만들고 초기화된 이미지로부터 복제 디스크 볼륨을 연결하며, 부팅된 인스턴스는 클러스터에 연결되어 데이터를 로컬 볼륨에 동기화합니다.

서비스 검색

동적 인프라에서는 서비스와 서버의 위치가 유동적이므로, 프런트엔드가 백엔드 서비스를 찾는 것 같은 일에 신속한 검색 메커니즘이 필요합니다. 런타임이 앱에 제공하는 공통 서비스의 대부분이 서비스 검색 유형입니다.

메커니즘방식특징
코드에 추가된 IP 주소서비스마다 고정 IP 할당 (예: 모니터링 서버는 항상 192.168.1.5)주소 변경·다중 인스턴스 실행에 앱 리빌드·재배포 필요
호스트 파일 엔트리서버 구성으로 각 서버의 /etc/hosts에 이름→IP 매핑 생성DNS보다 복잡. 팀에 DNS 변경 권한이 없을 때 쓰이는 우회책
DNS코드 또는 DDNS로 관리되는 DNS 엔트리로 이름→IP 매핑서비스 검색의 성숙한 솔루션
리소스 태그서비스·환경 정보를 태그로 달고 플랫폼 API로 검색앱 코드가 인프라 플랫폼에 결합되지 않도록 주의
구성 레지스트리인스턴스가 중앙 레지스트리에 연결 세부 정보를 유지주소 이상의 정보(작동 여부, 상태)가 필요할 때 유용
사이드카앱 인스턴스 옆의 별도 프로세스가 아웃바운드 프록시·인바운드 게이트웨이·조회를 담당보통 서비스 메시의 일부. 인증·암호화·로깅·모니터링까지 확장
API 게이트웨이경로·엔드포인트를 정의하는 중앙 집중식 HTTP 서비스사이드카와 비슷하지만 분산형이 아닌 중앙 집중식

인프라, 런타임, 애플리케이션을 엄격하게 구분 짓지 말자

이론적으로는 런타임을 완전한 서비스 집합으로 제공해 개발자가 기본 인프라의 세부에 영향을 덜 받게 하는 것이 유용합니다. 그러나 현실의 경계는 이 모델보다 훨씬 모호합니다. 각기 다른 사람과 팀이 서로 다른 제어·추상화 수준에서 리소스에 접근해야 하므로, 절대적인 경계를 가진 시스템 대신 각 사용자에게 다른 방식으로 구성되고 제공될 수 있는 시스템을 정의해야 합니다.

비교 / 트레이드오프

한쪽다른 쪽기준
의존성 위치호스트 OS 설치: 패키지가 작음컨테이너 번들: 크지만 일관성·이동성·QA 확보서버 간 가변성이 문제라면 번들
앱-인프라 경계단일 엔티티(변경 불가능한 서버·스택): 강한 결합, 단순한 배포 단위분리(인프라 코드가 라이브러리·구성 프로비저닝): 얇은 앱 패키지어느 쪽이든 코드베이스 구조를 배포 단위에 맞출 것
공통 서비스 배치사이드카: 인스턴스마다 분산API 게이트웨이: 중앙 집중게이트웨이에 비즈니스 로직이 몰리는 경향(overambitious API gateway)을 경계

내 생각

  • 예제 10-1은 사실상 Kubernetes Deployment + Service + NetworkPolicy의 추상형입니다. count_min/max는 HPA, health_url은 liveness probe, connectivity는 NetworkPolicy에 대응합니다. 매니페스트 개념이 낯설면 이 매핑으로 읽으면 됩니다.
  • 스키마 마이그레이션을 릴리스에 묶는 원칙은 백엔드에서 이미 표준입니다. Spring Boot에 Flyway를 붙여 배포와 함께 마이그레이션을 실행하는 구성이 그 구현입니다. 핵심은 “스키마 버전 = 앱 버전” 동기화입니다.
  • 서비스 검색 표는 성숙도 사다리로 읽힙니다. 하드코딩 IP → hosts 파일 → DNS → 레지스트리·사이드카 순이고, 조직의 자동화·거버넌스 수준이 어느 단까지 올라갈 수 있는지를 결정합니다. hosts 파일 우회는 기술 선택이 아니라 조직 문제(DNS 권한 부재)의 증상입니다.
  • CAUTION의 “경계를 엄격히 긋지 말자”가 플랫폼 팀의 실전 함정입니다. 추상화로 완전히 감춘 런타임은 디버깅·튜닝이 필요한 순간 벽이 됩니다. 팀마다 다른 추상화 수준으로 내려갈 수 있는 통로를 남겨야 합니다.

관련 개념