왜 Multi-Cluster인가?
단일 Kubernetes 클러스터는 규모가 커질수록 장애 반경(blast radius), 리전 종속성, 업그레이드 리스크라는 한계에 부딪힙니다. Multi-Cluster 아키텍처는 클러스터를 분리하여 이 문제들을 근본적으로 해결합니다.
Multi-Cluster가 필요한 대표적인 시나리오:
- 고가용성: 리전/AZ 장애 시 다른 클러스터로 트래픽 전환
- 규제 준수: 데이터 주권법에 따라 리전별 클러스터 분리
- 환경 격리: dev/staging/prod를 물리적으로 분리
- 성능: 사용자와 가까운 리전에서 서비스 제공
Multi-Cluster 토폴로지
| 토폴로지 | 구조 | 적합한 상황 |
|---|---|---|
| Active-Passive | 주 클러스터 + 대기 클러스터 | DR(재해복구) 목적, 단순한 구조 |
| Active-Active | 모든 클러스터가 트래픽 처리 | 글로벌 서비스, 지역별 라우팅 |
| Hub-Spoke | 중앙 관리 클러스터 + 워크로드 클러스터 | 엣지, IoT, 매장별 클러스터 |
| Flat Mesh | 클러스터 간 서비스 메시로 직접 통신 | MSA 간 크로스 클러스터 호출 |
kubectl 멀티 컨텍스트 관리
가장 기본적인 Multi-Cluster 운영은 kubeconfig 컨텍스트 전환입니다.
# 컨텍스트 목록 확인
kubectl config get-contexts
# 컨텍스트 전환
kubectl config use-context prod-ap-northeast-2
kubectl config use-context staging-us-west-2
# 컨텍스트 지정하여 명령 실행
kubectl --context=prod-ap-northeast-2 get pods -n api
kubectl --context=staging-us-west-2 get pods -n api
# kubectx로 빠른 전환 (추천)
kubectx prod-ap-northeast-2
kubens api
ArgoCD Multi-Cluster GitOps
ArgoCD는 단일 인스턴스에서 여러 클러스터에 애플리케이션을 배포할 수 있어 Multi-Cluster GitOps의 표준입니다. K8s FluxCD GitOps 자동 배포의 FluxCD도 비슷한 기능을 제공하지만, ArgoCD의 UI와 Application Sets가 Multi-Cluster에 더 적합합니다.
# 클러스터 등록
argocd cluster add prod-ap-northeast-2
argocd cluster add prod-us-west-2
argocd cluster add staging-ap-northeast-2
ApplicationSet으로 다중 클러스터 배포
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: api-server
namespace: argocd
spec:
generators:
- clusters:
selector:
matchLabels:
env: production
values:
replicas: "3"
- clusters:
selector:
matchLabels:
env: staging
values:
replicas: "1"
template:
metadata:
name: 'api-server-{{name}}'
spec:
project: default
source:
repoURL: https://github.com/company/k8s-manifests.git
targetRevision: main
path: apps/api-server
helm:
parameters:
- name: replicas
value: '{{values.replicas}}'
- name: cluster
value: '{{name}}'
destination:
server: '{{server}}'
namespace: api
syncPolicy:
automated:
prune: true
selfHeal: true
clusters 제너레이터가 ArgoCD에 등록된 클러스터를 순회하며, 라벨 기반으로 환경별 설정을 다르게 적용합니다.
글로벌 로드밸런싱: 트래픽 라우팅
Multi-Cluster에서 사용자 트래픽을 적절한 클러스터로 보내는 방법입니다.
DNS 기반 라우팅
# AWS Route 53 가중치 기반 라우팅
resource "aws_route53_record" "api_ap" {
zone_id = aws_route53_zone.main.zone_id
name = "api.example.com"
type = "A"
set_identifier = "ap-northeast-2"
weighted_routing_policy {
weight = 70
}
alias {
name = module.eks_ap.lb_dns_name
zone_id = module.eks_ap.lb_zone_id
evaluate_target_health = true
}
}
resource "aws_route53_record" "api_us" {
zone_id = aws_route53_zone.main.zone_id
name = "api.example.com"
type = "A"
set_identifier = "us-west-2"
weighted_routing_policy {
weight = 30
}
alias {
name = module.eks_us.lb_dns_name
zone_id = module.eks_us.lb_zone_id
evaluate_target_health = true
}
}
| 방식 | 도구 | 특징 |
|---|---|---|
| DNS 가중치 | Route53, Cloud DNS | 간단, TTL 기반 전환 지연 |
| 지리 기반 DNS | Route53 Geolocation | 사용자 위치 기반 자동 라우팅 |
| 글로벌 LB | GCP GCLB, AWS Global Accelerator | Anycast IP, 빠른 장애 전환 |
| 서비스 메시 | Istio Multi-Cluster | L7 라우팅, mTLS 자동화 |
크로스 클러스터 서비스 디스커버리
클러스터 간 서비스 호출이 필요하면 Istio Multi-Cluster 또는 Submariner를 사용합니다.
# Istio Multi-Cluster: 원격 클러스터 시크릿 등록
istioctl create-remote-secret
--context=prod-us-west-2
--name=us-west-2 |
kubectl apply -f - --context=prod-ap-northeast-2
# 이후 ap-northeast-2 클러스터에서 us-west-2의 서비스 직접 호출 가능
# payment.payment-ns.svc.cluster.local → 자동으로 원격 클러스터 라우팅
상태 동기화: DB와 시크릿
Multi-Cluster에서 가장 어려운 부분은 상태(state) 동기화입니다.
# External Secrets Operator로 시크릿 동기화
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: api-secrets
namespace: api
spec:
refreshInterval: 1h
secretStoreRef:
name: aws-secrets-manager
kind: ClusterSecretStore
target:
name: api-secrets
data:
- secretKey: db-password
remoteRef:
key: prod/api/db-password
K8s External Secrets 운영에서 다룬 것처럼, AWS Secrets Manager나 Vault를 단일 소스로 사용하면 모든 클러스터에서 동일한 시크릿을 자동 동기화할 수 있습니다.
장애 전환(Failover) 전략
# 헬스체크 실패 시 DNS 자동 전환 (Route53 Health Check)
resource "aws_route53_health_check" "api_ap" {
fqdn = "api-ap.internal.example.com"
port = 443
type = "HTTPS"
resource_path = "/health"
failure_threshold = 3
request_interval = 10
tags = {
Name = "api-ap-northeast-2-health"
}
}
# Failover 레코드
resource "aws_route53_record" "api_failover_primary" {
zone_id = aws_route53_zone.main.zone_id
name = "api.example.com"
type = "A"
set_identifier = "primary"
failover_routing_policy {
type = "PRIMARY"
}
health_check_id = aws_route53_health_check.api_ap.id
alias {
name = module.eks_ap.lb_dns_name
zone_id = module.eks_ap.lb_zone_id
}
}
정리
K8s Multi-Cluster는 고가용성과 글로벌 서비스를 위한 필수 아키텍처입니다. ArgoCD ApplicationSet으로 배포를 통합하고, DNS 기반 또는 글로벌 LB로 트래픽을 분배하며, External Secrets로 상태를 동기화하는 것이 실전 패턴입니다. 복잡도가 높으므로 먼저 Active-Passive부터 시작하여 점진적으로 확장하는 것을 권장합니다.