K8s Multi-Cluster 운영 전략

왜 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부터 시작하여 점진적으로 확장하는 것을 권장합니다.

위로 스크롤
WordPress Appliance - Powered by TurnKey Linux