들어가며: QA 테스트 환경, 왜 문제였나?
국내 IT 서비스 기업에서 QA 테스트 환경을 운영해본 경험이 있으신가요? 저도 몇 년 전까지만 해도 매번 새로운 기능을 검증할 때마다 '환경 좀 열어주세요'라는 요청을 플랫폼 팀에 넣고, 30~45분을 기다리는 게 일상이었습니다. 특히 여러 조합의 애플리케이션을 동시에 테스트해야 하는 상황에서는 각각의 전용 Amazon EKS 클러스터를 따로 띄워야 했고, ALB(Application Load Balancer), Route 53 레코드, 모니터링 에이전트까지 매번 중복으로 생성되면서 인프라 비용과 운영 부담이 눈덩이처럼 불어났습니다.
Deloitte도 정확히 같은 고민을 하고 있었습니다. 그들이 선택한 해결책은 Amazon EKS + vCluster 조합이었고, 그 결과는 놀라웠습니다.
- 환경 프로비저닝 시간: 45분 → 5분 미만 (89% 감소)
- 연간 회수 시간: 약 500시간
- vCPU 절감: 피크 사용 시 50개 이상
- 메모리 절감: 200GB 이상
- 비용 최적화: Spot Instance 활용 시 최대 70% 절감
이 글에서는 Deloitte가 실제 사용한 아키텍처와 핵심 설정 코드를 바탕으로, 어떻게 이런 성과를 냈는지 단계별로 살펴보겠습니다. (참고: Deloitte의 원문 글에서 더 자세한 배경을 확인할 수 있습니다.)

핵심 아키텍처: 하나의 EKS 클러스터로 여러 개의 가상 클러스터 운영하기
Deloitte의 솔루션은 크게 세 가지 레이어로 구성됩니다.
- 호스트 클러스터 (Host Cluster) : Amazon EKS Auto Mode가 활성화된 기본 클러스터. 모든 컴퓨팅과 네트워킹 리소스를 제공합니다.
- 가상 클러스터 (vCluster) : 호스트 위에서 동작하는 경량 Kubernetes 클러스터. 각각 완전히 격리된 테스트 환경 역할을 합니다.
- 공유 컨트롤러 (Shared Controllers) : Load Balancer Controller, Storage Controller 등이 호스트에 한 번만 배포되어 모든 가상 클러스터에서 공유됩니다.
vCluster 배포하기 (Helm 차트)
실제로 vCluster를 배포하는 명령어는 다음과 같습니다. 아래 값들은 각자 환경에 맞게 수정해야 합니다.
export DOMAIN_NAME=<your-domain.com>
export ZONE_ID=<your-route53-zone-id>
export CERTIFICATE_ARN=$(aws acm request-certificate \
--domain-name $DOMAIN_NAME \
--validation-method DNS \
--output text)
# 인증서 검증 레코드 생성
CERT_NAME=$(aws acm describe-certificate \
--certificate-arn $CERTIFICATE_ARN \
--query 'Certificate.DomainValidationOptions[0].ResourceRecord.Name' \
--output text)
CERT_VALUE=$(aws acm describe-certificate \
--certificate-arn $CERTIFICATE_ARN \
--query 'Certificate.DomainValidationOptions[0].ResourceRecord.Value' \
--output text)
aws route53 change-resource-record-sets \
--hosted-zone-id $ZONE_ID \
--change-batch '{
"Changes": [{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "'"$CERT_NAME"'",
"Type": "CNAME",
"TTL": 300,
"ResourceRecords": [{"Value": "'"$CERT_VALUE"'"}]
}
}]
}'
vCluster Helm 차트 설치
helm repo add loft https://charts.loft.sh
helm repo update
helm upgrade --install vcluster-pro loft/vcluster \
--namespace vcluster-platform \
--create-namespace \
--set admin.create=true \
--set admin.username=admin \
--set admin.password=<your-password> \
--set ingress.enabled=true \
--set ingress.name=loft-ingress \
--set ingress.annotations."alb\.ingress\.kubernetes\.io/subnets"="<subnet-1>,<subnet-2>" \
--set ingress.annotations."alb\.ingress\.kubernetes\.io/certificate-arn"=$CERTIFICATE_ARN \
--set ingress.annotations."alb\.ingress\.kubernetes\.io/scheme"=internet-facing \
--set ingress.annotations."alb\.ingress\.kubernetes\.io/load-balancer-name"=vcluster-alb \
--set ingress.host=$DOMAIN_NAME \
--set ingress.path="/*" \
--set ingress.ingressClass=alb \
--set ingress.tls.enabled=false
주의:
admin.password는 반드시 강력한 비밀번호로 변경하세요. 기본값 그대로 사용하면 보안에 취약합니다.
![]()
가상 클러스터 생성 및 애플리케이션 배포
vCluster 플랫폼이 배포되면, 웹 UI에 접속해서 가상 클러스터를 생성할 수 있습니다. 각 가상 클러스터는 완전한 Kubernetes API를 제공하므로, 일반적인 kubectl 명령어로 제어할 수 있습니다.
가상 클러스터 YAML 설정
# vcluster.yaml
sync:
fromHost:
ingressClasses:
enabled: true
storageClasses:
enabled: true
toHost:
ingresses:
enabled: true
controlPlane:
coredns:
enabled: true
embedded: true
이 설정이 중요한 이유는 다음과 같습니다.
fromHost.ingressClasses.enabled: 호스트의 IngressClass를 가상 클러스터에서 사용할 수 있게 해줍니다.fromHost.storageClasses.enabled: 호스트의 StorageClass를 가상 클러스터에서 사용할 수 있게 해줍니다.toHost.ingresses.enabled: 가상 클러스터에 생성된 Ingress 리소스를 호스트로 동기화하여, 하나의 ALB로 여러 가상 클러스터의 트래픽을 받을 수 있게 합니다.
가상 클러스터에 애플리케이션 배포
# app-deployment.yaml
apiVersion: v1
kind: Namespace
metadata:
name: echoserver
---
apiVersion: v1
kind: Service
metadata:
name: echoserver
namespace: echoserver
spec:
ports:
- port: 80
targetPort: 8080
selector:
app: echoserver
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: echoserver
namespace: echoserver
spec:
replicas: 1
selector:
matchLabels:
app: echoserver
template:
metadata:
labels:
app: echoserver
spec:
containers:
- image: hashicorp/http-echo:latest
name: echoserver
args:
- "-text=Hello from App1"
ports:
- containerPort: 8080
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: echoserver
namespace: echoserver
annotations:
alb.ingress.kubernetes.io/certificate-arn: <your-cert-arn>
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/group.order: "-999"
spec:
ingressClassName: alb
rules:
- host: <your-domain.com>
http:
paths:
- path: /app1
pathType: ImplementationSpecific
backend:
service:
name: echoserver
port:
number: 80
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ebs-claim
namespace: echoserver
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: auto-ebs-sc
팁:
alb.ingress.kubernetes.io/group.order를 조정하면 여러 가상 클러스터의 Ingress 규칙이 ALB에 추가될 때 우선순위를 제어할 수 있습니다. 기본값은0이며, 음수 값은 더 높은 우선순위를 가집니다.
두 번째 가상 클러스터에도 동일한 방식으로 배포하되, path: /app2와 args의 텍스트를 변경하면 됩니다.

국내 환경에서의 적용 맥락과 주의사항
국내 SI/스타트업 환경에서의 장점
- 개발 환경 격리: 여러 프로젝트를 동시에 진행하는 SI 환경에서 각 프로젝트별로 완전히 격리된 테스트 환경을 제공할 수 있습니다.
- 비용 절감: 하나의 EKS 클러스터로 여러 환경을 운영하므로, AWS 비용을 크게 줄일 수 있습니다. 특히 국내 중소기업에게는 매력적인 옵션입니다.
- 셀프 서비스: 플랫폼 팀의 개입 없이 QA 팀이 직접 환경을 생성할 수 있어, 업무 효율이 극대화됩니다.
주의사항 및 한계
- vCluster의 오버헤드: vCluster는 완전한 격리를 제공하지만, 호스트 클러스터의 리소스를 공유하기 때문에 호스트에 장애가 발생하면 모든 가상 클러스터에 영향이 갑니다. 따라서 호스트 클러스터의 안정성이 매우 중요합니다.
- 네트워크 격리 수준: vCluster는 네트워크 레벨의 완전한 격리를 보장하지 않습니다. 보안이 중요한 환경에서는 추가적인 네트워크 정책(NetworkPolicy)을 적용해야 합니다.
- Auto Mode 비용: Amazon EKS Auto Mode는 편리하지만, 노드 그룹을 직접 관리하는 것보다 비용이 더 나올 수 있습니다. 사용 패턴에 따라 검토가 필요합니다.
- 라이선스: vCluster Community Edition은 무료이지만, vCluster Platform(프로 버전)은 13일 트라이얼 이후 유료입니다. 장기적으로 사용하려면 라이선스 비용을 고려해야 합니다.
다음 단계 학습 방향
- EKS Auto Mode 공식 문서를 통해 세부 설정을 익혀보세요.
- vCluster 공식 문서에서 다양한 동기화 옵션을 확인해보세요.
- 실제 프로젝트에 적용하기 전에, 간단한 PoC(Proof of Concept)를 통해 자신의 환경에서의 성능과 안정성을 테스트해보는 것을 추천합니다.