한 줄 정의

Kubernetes 같은 애플리케이션 클러스터와 FaaS 런타임을 코드로 정의한 인프라 스택으로 구축하고, 스택 분리·파이프라인·클러스터 공유 전략으로 안전하게 변경하는 방법입니다.

쉽게 말하면

애플리케이션 클러스터는 공유 오피스입니다. 입주사(애플리케이션)는 자기 자리가 몇 층 어느 책상인지 신경 쓰지 않고, 운영사(스케줄러)가 빈자리를 찾아 배정하고 문제가 생기면 자리를 옮겨 줍니다.

이 장은 입주사가 아니라 공유 오피스를 차리는 쪽 의 이야기입니다. 건물(인프라 리소스)을 빌려 좌석과 회의실을 구축하는 일도 코드로 해야 하고, 지점을 하나 크게 낼지 여러 개로 나눌지(공유 전략), 보안 요구가 엄격한 회원사에게 전용 층을 줄지(거버넌스 클러스터)도 결정해야 합니다.

왜 중요한가?

애플리케이션 클러스터는 애플리케이션을 오케스트레이션하는 문제와 서버를 프로비저닝·구성하는 문제를 분리해 주는 계층입니다. 그런데 그 계층 자체가 또 하나의 인프라이고, 클러스터에 문제가 생기면 그 위의 모든 애플리케이션이 함께 영향을 받습니다.

그래서 클러스터야말로 코드로 정의하고 파이프라인으로 변경을 검증해야 합니다. 수동으로 관리하면 시스템 전체에서 가장 큰 단일 장애점을 가장 검증 안 된 방식으로 바꾸는 셈이 됩니다.

핵심 내용

두 가지 클러스터 솔루션

접근특징
서비스형(관리형) 클러스터EKS, AKS, GKE (Kubernetes 기반), ECS (CSP 전용)플랫폼이 관리 계층을 대신 운영 — 클러스터를 정의하는 스택 코드만 있으면 됨
패키징된 클러스터 배포kops·Kubeadm·kubespray 설치, OpenShift·Rancher RKE 같은 배포판직접 프로비저닝한 인프라에 클러스터 관리 소프트웨어까지 설치·운영

어느 쪽이든 클러스터를 구축하는 일은 결국 클러스터와 지원 요소를 포함하는 스택을 생성하는 문제 로 환원됩니다.

관리형 Kubernetes 클러스터는 클라우드 추상화 계층이 아니다

관리형 Kubernetes를 쓰면 어느 클라우드에서나 투명하게 애플리케이션을 실행할 수 있을 것 같지만, 클러스터는 전체 애플리케이션 호스팅 플랫폼의 작은 부분일 뿐입니다. 스토리지·네트워킹 같은 클러스터 밖 리소스, 모니터링·ID 관리·비밀 관리 같은 서비스는 클라우드마다 다르게 제공되므로, 각 클라우드의 서비스를 따로 쓰거나 추상화 계층을 직접 구축해야 합니다. 핵심 Kubernetes조차 버전·구현·도구가 클라우드마다 다릅니다.

클러스터를 구성하는 부품

부품역할
스케줄러각 애플리케이션의 인스턴스 수와 실행 위치 결정
모니터링인스턴스 문제를 감지해 재시작하거나 이동
구성 레지스트리클러스터 관리와 애플리케이션 구성에 필요한 정보 저장
서비스 검색애플리케이션·서비스가 인스턴스의 현재 위치를 찾도록 지원
관리 API와 UI도구와 사용자의 클러스터 상호작용 창구

여기에 스케줄러가 애플리케이션 인스턴스를 실제로 실행하는 서버 풀인 애플리케이션 호스팅 노드 가 더해집니다. 호스트 노드는 보통 서버 클러스터로 구성하고, 관리 서비스는 호스팅용 서버와 분리된 전용 서버에서 — 가용성을 위해 그 자체도 클러스터로 — 실행합니다.

스택 토폴로지 — 모놀리식에서 멀티 스택으로

가장 간단한 설계는 클러스터의 모든 부분을 단일 스택으로 정의하는 것입니다. 규모가 커지면 안티패턴이 되지만 작고 단순한 클러스터의 시작점으로는 유용합니다.

address_block:
  name: cluster_network
  address_range: 10.1.0.0/16
  vlans:
    - vlan_a: { address_range: 10.1.0.0/8 }
    - vlan_b: { address_range: 10.1.1.0/8 }
    - vlan_c: { address_range: 10.1.2.0/8 }
 
application_cluster:
  name: product_application_cluster
  address_block: $address_block.cluster_network
 
server_cluster:
  name: "cluster_nodes"
  min_size: 1
  max_size: 3
  vlans: $address_block.cluster_network.vlans
  each_server_node:
    source_image: cluster_node_image
    memory: 8GB

서비스형 클러스터라면 이것으로 충분합니다 — 관리 서비스는 플랫폼이 처리하므로 관리 서버를 프로비저닝할 필요가 없습니다. 패키징된 솔루션이라면 여기에 클러스터 관리 서버(예: cluster_manager 역할을 적용한 가상 머신)를 추가하고, 설치 프로그램 실행은 별도 단계로 취급 합니다. 그래야 인프라 스택을 애플리케이션 클러스터와 분리해 테스트할 수 있습니다.

파이프라인 설계

전체 그림은 세 갈래 파이프라인입니다. 호스트 노드 서버 이미지 파이프라인, 클러스터 스택 파이프라인, 그리고 클러스터에 배포되는 각 애플리케이션의 파이프라인입니다. 애플리케이션 파이프라인은 클러스터 파이프라인과 매우 느슨하게 연결되며, 클러스터 업데이트 후 애플리케이션 테스트를 트리거해 클러스터 변경이 일으킨 문제를 잡을 수 있습니다.

클러스터 스택 파이프라인은 구문 검사와 모의(mock) 적용을 하는 오프라인 단계로 시작해 빠르게 코딩 레벨 문제를 잡고, 온라인 단계에서 실제 스택 인스턴스를 생성해 검증합니다. 온라인 단계의 테스트 대상은 관리 서비스가 올바르게 생성·접근되는지, 관리 엔드포인트가 외부에 열려 있지 않은지(Kubernetes는 인증 없는 관리 API 노출 사고의 역사가 있습니다), 그리고 샘플 애플리케이션 배포입니다. 실제 애플리케이션 대신 의존성이 최소인 샘플을 쓰면, 테스트 실패의 원인이 애플리케이션 배포의 복잡성이 아니라 클러스터 프로비저닝 문제임을 분명히 할 수 있습니다.

문제는 모놀리식 스택의 온라인 단계가 무겁다 는 점입니다. 클러스터 구성, 호스트 노드 서버 클러스터, 클러스터 컨텍스트의 서버 이미지까지 한 단계에서 테스트하므로 실패 요인이 많아 진단이 복잡하고, 테스트보다 프로비저닝에 훨씬 긴 시간이 듭니다. 이 두 문제가 클러스터를 멀티 스택으로 나누는 주요 원인입니다.

멀티 스택 분리

호스트 노드 서버 풀을 별도 스택으로 꺼내면 애플리케이션 클러스터 없이도 이 스택만 프로비저닝해 서버 부팅·네트워킹 경로를 테스트하고, 의도적으로 장애를 일으켜 플랫폼이 서버를 자동 교체하는지 확인할 수 있습니다. 분리하면서 호스트 노드에 별도 VLAN을 부여해 클러스터 관리와 네트워크 세그먼트를 나누는 것이 좋습니다.

flowchart LR
    image["호스트 노드 이미지<br/>파이프라인"] --> host["호스트 노드 클러스터 스택<br/>온라인 테스트"]
    mgmt["클러스터 관리 스택<br/>온라인 테스트"] --> integ["스택 통합<br/>테스트 단계"]
    host --> integ
    integ --> delivery["환경별 딜리버리"]

단계 수는 늘지만 각 단계는 단일 파이프라인보다 가볍고 빠릅니다. 클러스터 관리 스택의 온라인 단계는 서버 노드 없이 관리 인프라만 프로비저닝하므로 빠르게 관리 계층의 구성·보호를 검증하고, 마지막 스택 통합 단계는 두 스택의 조합에서만 발생하는 문제 에 집중합니다. 이전 단계의 테스트를 복제하지 않고, 샘플 애플리케이션 배포와 장애 트리거·인스턴스 증설로 안정성과 확장성을 검증합니다.

클러스터 공유 전략

얼마나 많은 클러스터를, 어떤 크기로 실행할 것인가의 문제입니다. 이론적으로는 하나의 클러스터 안에서 환경과 애플리케이션 경계를 다 표현할 수 있지만, 단일 클러스터는 다음 이유로 실용적이지 않습니다.

관점단일 클러스터의 문제
변경 관리업데이트·업그레이드를 서비스 중단 없이 테스트할 곳이 없고, 위험한 변경의 시간대를 모든 팀·리전에 맞추기 어려움
분리많은 클러스터 구현이 애플리케이션·데이터·구성을 충분히 분리하지 못함
구성 가능성팀·애플리케이션마다 다른 구성 요구가 한 클러스터에서 충돌
성능과 확장성넓은 지리적 범위는 지연 시간 때문에 단일 클러스터가 비현실적이고, 여러 앱이 함께 확장되면 리소스 경합 발생
가용성단일 클러스터는 단일 장애점

이 요구사항들에 맞춰 고를 수 있는 전략은 다음과 같습니다.

  • 하나의 큰 클러스터: 관리는 가장 쉽지만, 최소한 변경을 테스트할 별도 클러스터 인스턴스와 파이프라인은 반드시 필요합니다
  • 딜리버리 단계별 클러스터: 환경마다 클러스터를 하나씩 두면 환경 간 불일치는 막지만 유지 비용이 크고, 테스트 환경을 동적으로 만드는 경우 클러스터 생성 시간이 병목이 됩니다. 변형으로 개발 클러스터 / 스테이징 클러스터 / (고객 데이터를 다루는) 스테이징·프로덕션 환경을 함께 호스팅하는 프로덕션 클러스터처럼 거버넌스 수준이 같은 단계끼리 클러스터를 공유할 수 있습니다
  • 거버넌스 클러스터: PCI 적용 신용카드 처리, GDPR 적용 개인 데이터 처리처럼 규제 대상 서비스를 전용 클러스터로 분리하면 그 클러스터의 감사·통제는 강화하고 나머지 클러스터의 거버넌스는 간소화할 수 있습니다
  • 팀 클러스터: 대고객 서비스 팀과 내부 서비스 팀처럼 거버넌스·가용성 요구가 다른 팀별로 클러스터를 할당해 각자 최적화합니다

공유 클러스터에서의 환경 분리

클러스터링 솔루션이 제공하는 분리 메커니즘 다수는 강력하지 않습니다. 인스턴스에 환경 태그를 붙이는 것은 순전히 규칙일 뿐이므로, 여러 환경을 공유 클러스터에 호스팅한다면 애플리케이션과 운영 서비스가 다른 환경의 인스턴스를 보거나 상호작용할 수 없게 하는 더 강력한 분리 방법을 찾아야 합니다.

서비스 메시

서비스 메시는 분산 시스템의 부분 간 연결을 동적으로 관리하는 분산 서비스 네트워크로, 네트워크 기능을 인프라 계층에서 애플리케이션 런타임 계층으로 옮깁니다. 일반적인 구현에서 각 애플리케이션 인스턴스는 다른 인스턴스와의 통신을 사이드카 프로세스 에 위임합니다. 예로 HashiCorp Consul, Envoy, Istio, Linkerd가 있습니다.

제공 서비스내용
라우팅가장 적절한 인스턴스로 트래픽 전달 — blue-green·카나리 같은 고급 배포 시나리오 가능
가용성회로 차단기(circuit breaker) 같은 요청 수 제한 규칙 시행
보안인증서를 포함한 암호화 처리
인증서비스 간 연결 허용 규칙 적용, P2P 인증용 인증서 관리
관찰 가능성분산 시스템을 관통하는 요청을 추적할 수 있도록 연결·이벤트 기록

애플리케이션 클러스터가 하위 레벨 리소스에서 분리된 컴퓨팅을 동적으로 제공한다면, 서비스 메시는 하위 레벨 네트워킹에서 분리된 애플리케이션 통신을 동적으로 관리합니다. 공통 문제를 애플리케이션 코드에서 사이드카로 옮겨 개발을 단순화하고, 사이드카 업데이트만으로 시스템 전체를 개선할 수 있으며, 앱 인스턴스를 배포하는 동일한 오케스트레이션이 사이드카도 함께 배포합니다. 주로 컨테이너 시스템과 쓰이지만 사이드카를 가상 머신에 배포하는 식으로 비컨테이너 시스템에도 구현할 수 있습니다.

복잡성은 사라지지 않고 이동한다

서비스 메시는 개별 애플리케이션 개발을 단순화하지만 그 복잡성은 인프라로 이동했을 뿐입니다. 가파른 학습 곡선을 감당할 준비가 필요하고, 인프라 수준 네트워킹과 메시 네트워킹 간 경계를 명확히 유지하지 않으면 문제가 중복되고 섞여 시스템 이해와 트러블슈팅이 더 어려워집니다.

FaaS 서버리스용 인프라

FaaS는 이벤트나 일정에 따라 요청을 받으면 코드를 실행하는 모델로, HTTP 요청 처리나 메시지 큐 이벤트 응답처럼 잘 정의된 단기 작업에 맞습니다. 수요가 크게 변동하고 필요 없을 때는 전혀 실행되지 않는 워크로드에 효율적입니다.

‘서버리스’는 정확한 용어가 아닙니다. 코드는 서버에서 실행되며 서버가 개발자에게 보이지 않을 뿐인데, 그것은 컨테이너도 마찬가지입니다. 진짜 차이는 추상화 레벨이 아니라 장기 실행 프로세스가 아닌 단기 프로세스 라는 점이고, 그래서 FaaS라는 용어가 선호됩니다. 외부에서 제공되는 서버리스 서비스인 BaaS(backend as a service)와도 구분됩니다.

FaaS 런타임은 애플리케이션 클러스터와 동일한 구도를 따릅니다. 서비스형(AWS Lambda, Azure Functions, Google Cloud Functions)이 있고, 직접 인프라를 프로비저닝해야 하는 패키지 솔루션(Fission, Kubeless, OpenFaaS, Apache OpenWhisk)이 있습니다. 패키지 솔루션은 작동 방식을 깊이 이해해야 하는데, 예를 들어 다른 FaaS 코드가 접근 가능한 위치에 임시 파일이 남아 데이터 분리·규정 준수 문제가 될 수 있고, 이에 따라 런타임을 몇 개의 인스턴스로 나눠 실행할지 결정해야 합니다.

벤더 FaaS는 호스트 서버의 크기·특성을 지정할 필요가 없어 관리할 인프라 범위가 크게 줄어듭니다. 그러나 대부분의 FaaS 코드는 다른 서비스와 상호작용하므로 트리거하는 인바운드 요청과 코드가 만드는 아웃바운드 요청의 네트워킹, 데이터를 읽고 쓰는 스토리지·데이터베이스·메시지 큐를 여전히 인프라 코드로 정의·테스트해야 하고, FaaS 코드 자체도 다른 코드처럼 파이프라인으로 딜리버리해야 합니다.

비교 / 트레이드오프

모놀리식 클러스터 스택멀티 스택
구조네트워킹·클러스터 정의·서버 풀이 한 프로젝트호스트 노드 풀·클러스터 관리 등을 별도 스택으로 분리
온라인 테스트한 단계에서 모든 것을 프로비저닝·검증 — 느리고 무거움스택별로 빠르게 검증 후 통합 단계에서 조합 문제만 테스트
실패 진단실패 요인이 많아 원인 찾기 복잡실패한 스택 단계가 원인 범위를 좁혀 줌
적합한 시점작고 단순한 클러스터의 시작점규모가 커져 변경 안정성·속도가 중요해질 때

내 생각

  • “관리형 Kubernetes는 추상화 계층이 아니다”는 멀티클라우드 환상에 대한 정확한 경고입니다. EKS 위에서도 IAM 연동, 스토리지 클래스, 로드밸런서 컨트롤러, 모니터링은 전부 AWS 고유물이라, 클러스터만 옮긴다고 워크로드가 이식되지 않습니다.
  • 멀티 스택 분리는 Terraform 스테이트를 나누는 이유와 같은 구조입니다. 한 스테이트가 커지면 plan/apply가 느려지고 실패 반경이 커지는 것처럼, 클러스터 스택도 프로비저닝 시간과 실패 요인이 분리의 트리거가 됩니다.
  • 네임스페이스 분리는 환경 태그와 같은 급의 “규칙일 뿐”인 경우가 많습니다. 규제 워크로드에서 네임스페이스 멀티테넌시로 감사를 통과하기 어려운 이유가 이것이고, 결국 거버넌스 클러스터처럼 물리적 분리가 답이 되곤 합니다.
  • FaaS의 실제 작업량은 함수 밖에 있습니다. Lambda 함수 코드보다 트리거·VPC·큐·DB 연결 같은 주변 리소스 정의가 본체라는 지적은, “서버리스라 인프라 작업이 없다”는 오해를 정확히 교정합니다.

관련 개념