티스토리 뷰

반응형

쿠버네티스 실습: 글로벌 트래픽 분산과 리전 간 자동 전환 (Geo Failover with External-DNS & Global Load Balancer)

이전 글에서는 멀티클러스터 GitOps + Velero 기반 DR(재해복구) 구조를 구축했습니다.
이제는 그 위에 “사용자 트래픽을 전 세계 리전으로 자동 분산하고 장애 시 즉시 전환되는 시스템”을 실습합니다.
즉, 이번 글은 **실시간 리전 간 장애 복구(Geo Failover)**의 완성 단계입니다.


1) 목표 구조

아래와 같은 구조를 구축합니다.

사용자 요청
   │
   ▼
[ Global DNS / LoadBalancer (e.g. Cloudflare, Route53) ]
   ├── region-a.example.com → Cluster A (Active)
   └── region-b.example.com → Cluster B (Standby)
         ↑
         └── Health Check 실패 시 자동 전환

이 시스템의 핵심은:

  • External-DNS로 각 리전의 Ingress 주소를 DNS에 자동 반영
  • Cloud Provider의 Global Load Balancer로 헬스체크 기반 트래픽 분산
  • Prometheus + Alertmanager로 장애 감지 후 Route 자동 전환

2) 사전 준비

2-1. 멀티클러스터 환경

이전 단계에서 만든 두 클러스터를 활용:

cluster-a → 서울 리전 (active)
cluster-b → 도쿄 리전 (standby)

2-2. 도메인 준비

Cloudflare, AWS Route53, GCP DNS 중 하나에서
예: fuelstation.app 도메인을 관리 중이라 가정.


3) External-DNS 설치

3-1. External-DNS 개념

쿠버네티스 Ingress나 Service의 IP가 변경될 때마다
자동으로 DNS 레코드를 업데이트해주는 컨트롤러입니다.
즉, LoadBalancer → DNS → 실시간 연결 유지를 자동으로 수행합니다.


3-2. 설치 (AWS Route53 예시)

helm repo add external-dns https://kubernetes-sigs.github.io/external-dns/
helm repo update

helm install external-dns external-dns/external-dns \
  --namespace kube-system \
  --set provider=aws \
  --set policy=sync \
  --set registry=txt \
  --set txtOwnerId=fuelstation-cluster-a \
  --set domainFilters={fuelstation.app} \
  --set aws.zoneType=public \
  --set logLevel=debug

Cluster B도 동일하게 설치하되 txtOwnerId만 다르게 지정 (fuelstation-cluster-b).


4) Ingress 설정

반응형

각 클러스터의 Ingress는 고유한 도메인을 사용합니다.

Cluster A:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: fuelstation-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    external-dns.alpha.kubernetes.io/hostname: region-a.fuelstation.app
spec:
  rules:
  - host: region-a.fuelstation.app
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: frontend
            port:
              number: 80

Cluster B도 동일하게 작성하되 hostname만 변경:

region-b.fuelstation.app

적용:

kubectl apply -f ingress.yaml

5) 글로벌 DNS / 트래픽 라우팅 설정

5-1. Route53 (Weighted Routing 예시)

AWS 콘솔에서 다음과 같이 레코드를 설정합니다.

Name Type Value Routing Policy Weight

fuelstation.app A region-a LB IP Weighted 100
fuelstation.app A region-b LB IP Weighted 0

Prometheus가 Region A 장애를 감지하면 Route53 API를 통해 Weight를 자동 조정합니다.


6) 자동 장애 감지 + Route 전환

6-1. Prometheus Rule

- alert: RegionA_Unavailable
  expr: up{cluster="region-a"} == 0
  for: 2m
  labels:
    severity: critical
  annotations:
    summary: "Region A Unreachable"
    description: "Cluster A가 응답하지 않음. 트래픽을 Region B로 전환합니다."

6-2. Alertmanager → Lambda Webhook (AWS 예시)

Alertmanager가 호출하는 Lambda 함수가 Route53 Weight 변경 API를 실행합니다.

import boto3

def lambda_handler(event, context):
    route53 = boto3.client('route53')
    route53.change_resource_record_sets(
        HostedZoneId='Z1234567890',
        ChangeBatch={
            'Changes': [{
                'Action': 'UPSERT',
                'ResourceRecordSet': {
                    'Name': 'fuelstation.app',
                    'Type': 'A',
                    'SetIdentifier': 'region-b',
                    'Weight': 100,
                    'ResourceRecords': [{'Value': 'IP_REGION_B'}],
                    'TTL': 60
                }
            }]
        }
    )

→ 즉, Region A 장애 시 자동으로 Region B가 활성화됩니다.


7) Grafana에서 글로벌 상태 시각화

Grafana에서 다음 패널을 구성:

  • region_a_up vs region_b_up
  • active_traffic_weight
  • restore_events_total

→ 리전별 상태, 트래픽 전환 이력, 복구 여부를 한눈에 확인.


8) DR 전환 시나리오 테스트

1️⃣ Region A 정상 동작

curl https://fuelstation.app
# "Response from region-a"

2️⃣ Region A 중단 (Ingress 삭제)

kubectl delete ingress fuelstation-ingress --context cluster-a

3️⃣ 2분 내

  • Prometheus 경보 발생
  • Alertmanager → Lambda 호출
  • Route53 레코드 Weight 전환
  • 트래픽 Region B로 자동 이동
curl https://fuelstation.app
# "Response from region-b"

9) 고급 구성 — Active/Active 트래픽 분산

  • Weighted 대신 Latency 기반 Routing 사용
  • 각 지역 사용자에게 가장 가까운 리전으로 라우팅
  • Prometheus + Grafana로 전 리전 트래픽 비율 모니터링
aws route53 change-resource-record-sets --cli-input-json file://latency-policy.json

→ 전 세계에서 자동으로 최적 리전 선택 가능.


10) 정리

  • External-DNS: 클러스터 Ingress → DNS 자동 반영
  • Prometheus + Alertmanager + Lambda(Route53): 장애 감지 및 자동 트래픽 전환
  • Active/Standby or Active/Active 구조로 글로벌 고가용성 확보
  • DR + Geo Failover까지 완성하면 “끊김 없는 서비스 인프라” 완성

다음 글에서는 이 모든 인프라를 Terraform + ArgoCD + Helm으로
코드 한 줄로 자동 구축하는 Infrastructure as Code (IaC) 파이프라인을 실습합니다.


 

쿠버네티스,GeoFailover,ExternalDNS,Route53,멀티클러스터,ArgoCD,DevOps,고가용성,글로벌배포,K8s실습

 

✅ 참고할 최신 기술 사항

  • External‑DNS: 쿠버네티스 리소스(Ingress/Service 등)를 외부 DNS 레코드로 자동 동기화하는 오픈소스 툴입니다. (GitHub)
  • Amazon Route 53 라우팅 정책: 멀티리전 가용성 확보를 위해 Weighted, Failover, Geolocation, Latency 기반 Routing 등의 정책이 제공됩니다. (AWS Documentation)

⚠️ 보완/강화 제안

아래 항목들을 검토해서 글에 반영하시면 독자에게 더 도움될 거예요.

  1. DNS Routing 정책 정확히 설명하기
    • Route 53의 Failover, Weighted, Geolocation, Latency 기반 정책 등 각각의 사용 케이스를 간단히 요약하면 좋습니다. 예컨대 “Active-Standby 전환에는 Failover 정책”, “지역별 분산에는 Geolocation” 식으로요. (AWS Documentation)
    • 글에서 “Weighted routing” 예시를 들었는데, 실제 장애 전환에는 Failover routing이 더 맞는 경우가 많다는 설명을 추가하면 좋습니다. (Medium)
  2. External-DNS 설치/운영 시 유의사항 추가하기
    • 외부 DNS 레코드를 자동 생성/삭제하므로 잘못 설정 시 도메인 누락이나 트래픽 손실이 발생할 수 있다는 주의사항. (Medium)
    • 각 리전 클러스터에 설치 시 --txt-owner-id 또는 domainFilters 같은 설정을 다르게 해야 충돌 없이 동작한다는 팁을 넣으면 좋습니다. (Kubernetes Sigs)
  3. 글로벌 로드밸런서와 헬스체크 연계 설명 강화
    • 단순 DNS 레코드 분산뿐 아니라, 헬스체크(예: Cloud provider의 ALB/NLB 헬스체크) → 장애 감지 → DNS 전환 방식까지 흐름을 구체화하면 좋습니다.
    • 특히 “Cluster A 응답 없음 → Prometheus Alert → Route53 API 호출” 흐름을 더 명확히 보여주면 좋습니다.
  4. 리전 간 데이터/스토리지 동기화 고려사항 추가하기
    • 사용자 트래픽 리전 전환만 고려했지만, 데이터 동기화(예: DB Replication, 스토리지 복제)도 중요합니다. 글에서는 Velero 백업 복제까지 이어졌지만, 트래픽 전환 시 데이터 지연이나 일관성 문제가 생길 수 있다는 경고도 삽입하면 좋습니다.
  5. 용어 및 흐름 정리하기
    • “Active/Active” vs “Active/Standby” 구조 등 용어를 정리해주면 읽는 사람이 혼동 덜합니다.
    • “셀프 힐링 인프라”, “글로벌 고가용성” 등 문구는 좋지만, 구체적 예시로 보완하면 좋습니다.

 

※ 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/04   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30
글 보관함
반응형