Zonal 클러스터 운영 전략: 트래픽 전환, 업그레이드 롤백, 데이터 AZ 친화
지원 버전: Amazon EKS 1.33+, AWS Load Balancer Controller 2.9+, Kafka 2.4+ (KIP-392), Valkey GLIDE 1.x 마지막 업데이트: 2026년 7월 15일
< 이전: Tekton Pipelines | 목차 >
고객 문의에서 가장 많이 나오는 주제는 "운영"입니다. 그중에서도 반복되는 조합이 있습니다: zone 단위로 클러스터를 쪼개 장애를 격리하고, 로드밸런서 타겟 그룹의 weight로 트래픽을 옮기고, 문제가 생기면 클러스터를 새로 만들지 않고 in-place로 되돌리는 것. 이 문서는 이 조합을 하나의 운영 전략으로 정리하고, 여기에 흔히 빠지는 조각인 DB/캐시/메시징의 read 경로를 zone에 고정하는 방법까지 더합니다.
각 영역의 구체적인 절차는 이미 이 레포의 다른 문서에 있습니다. 이 문서는 그 조각들이 "왜 함께 쓰이는지"와 "지금까지 없던 데이터 계층 부분"을 채웁니다.
목차
- 왜 zonal 운영인가
- 트래픽 계층: Target Group + TargetGroupBinding + Weight 전환
- 업그레이드: In-Place + 네이티브 롤백이 기본이 된 이유
- 데이터 계층: Read 경로를 Zone에 고정하기
- 권장 조합 요약
왜 zonal 운영인가
멀티 AZ 단일 클러스터와 AZ마다 클러스터를 두는 zonal(싱글존) 구성은 트레이드오프가 다릅니다.
| 관점 | 멀티 AZ 단일 클러스터 | Zonal(싱글존) 클러스터 |
|---|---|---|
| 장애 격리 | AZ 장애가 클러스터 일부에 영향 | AZ 장애가 해당 zonal 클러스터에만 영향, 나머지는 무관 |
| Cross-AZ 비용 | 파드 간 통신이 AZ 경계를 넘나듦 ($0.01/GB) | 같은 AZ 내 통신이라 인터-AZ 전송비 발생 안 함 |
| 업그레이드 | 롤링 업데이트, 클러스터 전체가 한 번에 버전 이동 | zone 단위로 순차 업그레이드, 나머지 zone은 이전 버전 유지 |
| 운영 복잡도 | 클러스터 1개 관리 | 클러스터 N개 + 트래픽 라우팅 계층 동기화 필요 |
AWS도 이 패턴을 Cell-Based Architecture for Amazon EKS 공식 가이드로 제공합니다. 여기서 zonal 클러스터 하나가 "cell"이고, 여러 cell을 리전 단위로 묶은 것이 "supercell"입니다. 셀 앞단의 라우팅 계층(Route 53 가중치 라우팅 + Application Recovery Controller)이 장애 조치를 담당하고, 각 cell 내부에는 ALB가 트래픽을 분배합니다. 핵심은 "cell 경계를 넘는 트래픽이 없으므로 인터-AZ 데이터 전송비가 발생하지 않는다"는 점입니다.
이 레포에서 zonal/블루-그린 아키텍처 자체는 이미 ops/02-infrastructure-advanced.md에서, 성숙도 모델 관점의 Multi-AZ/Cell-Based Architecture는 eks/10-eks-resiliency.md에서 다룹니다. 이 문서는 그 위에 트래픽 전환·업그레이드·데이터 read를 "하나의 운영 루프"로 엮습니다.
트래픽 계층: Target Group + TargetGroupBinding + Weight 전환

zonal 클러스터 여러 개를 운영할 때 트래픽을 옮기는 표준 패턴은 다음과 같습니다.
- NLB/ALB와 Target Group을 클러스터 밖에서 Terraform 등 IaC로 생성합니다 (클러스터가 사라져도 로드밸런서는 유지됨).
- 각 zonal 클러스터의 Service를
TargetGroupBindingCRD로 해당 Target Group에 바인딩합니다. - 클러스터 간 트래픽 이동은 클러스터 내부 리소스를 건드리지 않고, 로드밸런서의 Target Group weight만 조정합니다.
apiVersion: elbv2.k8s.aws/v1beta1
kind: TargetGroupBinding
metadata:
name: zone-a-tgb
namespace: production
spec:
targetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-2:ACCOUNT:targetgroup/zone-a-tg/xxxxxxxxxxxx
serviceRef:
name: app-service
port: 80
targetType: ip# ALB 리스너 규칙의 forward action에서 Target Group 간 weight 조정
aws elbv2 modify-listener \
--listener-arn "$LISTENER_ARN" \
--default-actions '[{
"Type": "forward",
"ForwardConfig": {
"TargetGroups": [
{"TargetGroupArn": "'"$ZONE_A_TG_ARN"'", "Weight": 20},
{"TargetGroupArn": "'"$ZONE_C_TG_ARN"'", "Weight": 80}
]
}
}]'TargetGroupBinding의 기본/고급/멀티포트 설정은 networking/03-aws-lb-controller.md에, NLB 가중치 타겟 그룹과 Route 53 가중치 라우팅의 전체 Terraform 구성은 ops/02-infrastructure-advanced.md에 있습니다.
계획된 전환 vs 장애 시 전환: weight 조정은 업그레이드·배포처럼 계획된 전환에 씁니다. AZ 장애처럼 예기치 않은 상황은 ARC(Application Recovery Controller) Zonal Shift가 자동 감지·전환을 담당합니다 — 두 메커니즘은 경쟁하지 않고 계획적/반응적으로 역할이 나뉩니다.
업그레이드: In-Place + 네이티브 롤백이 기본이 된 이유
2026년 7월 Amazon EKS가 Kubernetes 버전 네이티브 롤백을 GA했습니다. 업그레이드 후 문제가 발견되면 7일 이내, 한 번에 마이너 버전 1개를 되돌릴 수 있고, 롤백 전 API 호환성·kubelet 스큐·add-on 버전을 점검하는 Rollback Readiness Insights가 자동으로 사전 체크를 수행합니다. Auto Mode 클러스터는 컨트롤 플레인뿐 아니라 데이터 플레인(워커 노드)까지 롤백 대상에 포함됩니다 — 단, 셀프 매니지드 노드 그룹으로 zonal 클러스터를 in-place 업그레이드한 경우(3절)에는 이 자동 데이터 플레인 롤백이 적용되지 않고 컨트롤 플레인만 되돌아가므로, 노드/AMI/애드온 변경은 따로 되돌려야 합니다. 두 경우 모두 추가 비용은 없습니다.
이 기능이 나오기 전에는 "새 버전이 잘못되면 어떻게 되돌리나"라는 질문에 클러스터를 통째로 새로 만들어 검증하는 블루/그린 플릿이 유일한 답이었습니다. 이제는 이미 zonal(싱글존) 구성으로 운영 중인 팀이라면, zone별 클러스터를 하나씩 in-place로 업그레이드하고 문제 시 네이티브 롤백을 안전망으로 쓰는 더 가벼운 방식을 쓸 수 있습니다.
| 방식 | 언제 유리한가 |
|---|---|
| 블루/그린 클러스터 플릿 상시 유지 | 전환 전에 완전히 분리된 클러스터에서 실제 프로덕션 트래픽으로 신규 버전을 검증해야 하는 경우. 노드/AMI/애드온까지 통째로 되돌려야 하는 경우 (네이티브 롤백은 컨트롤 플레인만 되돌림) |
| Zonal In-Place + 네이티브 롤백 | 원래 가용성 목적으로 zonal 클러스터를 운영 중이고, 클러스터 플릿 두 벌을 상시 운영하는 비용을 피하고 싶으며, 즉각적인 클러스터 단위 failback보다 ~7일 롤백 유효기간을 감내할 수 있는 경우 |
| Route 53 가중치 DNS 전환 | 클러스터가 아예 다른 리전/계정에 있거나, NLB 계층 자체를 교체해야 하는 경우 |
실행 절차(NLB weight 이동 → in-place 업그레이드 → 검증 → weight 복원, 그리고 롤백 조건을 충족하지 못하는 경우들)는 이미 ops/11-upgrade-operations.md의 "대안: 네이티브 롤백을 활용한 Zonal In-Place 업그레이드" 섹션에 정리되어 있으므로 여기서는 반복하지 않습니다. 롤백이 가능한 정확한 조건(대상 버전으로 새로 생성된 클러스터는 롤백 불가, 이미 재업그레이드된 경우 등)은 eks/08-eks-upgrades.md의 롤백 절차를 참고하세요.
데이터 계층: Read 경로를 Zone에 고정하기
트래픽 전환과 업그레이드까지는 zonal 아키텍처를 갖춘 팀이라면 대체로 준비되어 있습니다. 반면 DB/캐시/메시징의 read 경로는 놓치기 쉽습니다 — 애플리케이션 파드는 자기가 속한 AZ 안에 있어도, DB reader나 캐시 replica, Kafka broker는 라운드로빈으로 다른 AZ에 배정되어 조용히 인터-AZ 비용과 지연을 만듭니다.
공통 원리는 하나입니다: write는 leader/primary로 가야 하니 어차피 cross-AZ가 발생할 수 있지만, read는 같은 AZ의 replica로만 보내면 됩니다. 트래픽의 대부분이 read인 워크로드(캐시, 조회성 쿼리, 컨슈머)에서는 이것만으로도 인터-AZ 비용의 상당 부분이 사라집니다.

이걸 하려면 먼저 파드가 "나는 어느 AZ에 있는가"를 알아야 합니다. Kubernetes Downward API는 Pod에 노드의 zone 라벨(topology.kubernetes.io/zone)을 직접 주입해주지 않으므로, 다음 중 하나가 필요합니다.
- EC2 IMDS 조회: 파드/사이드카가
http://169.254.169.254/latest/meta-data/placement/availability-zone을 직접 호출 - Admission 시점 라벨 주입: Kyverno 같은 mutating policy로, 노드의
topology.k8s.aws/zone-id라벨을 파드 annotation으로 복사 — AWS가 MSK-on-EKS rack awareness 가이드에서 권장하는 패턴이며, 이 레포의security/01-kyverno-policy-management.md에서 Kyverno 정책 작성법을 다룹니다 - 오퍼레이터 내장 지원: Strimzi처럼 rack-awareness를 1급 기능으로 제공하는 오퍼레이터를 쓰면 별도 구현 없이 init-container가 자동으로 처리
Kafka: KIP-392 Follower Fetching
KIP-392(Kafka 2.4+)는 컨슈머가 파티션 리더가 아니라 같은 rack(AZ)에 있는 팔로워 replica에서 직접 fetch하도록 허용합니다.
브로커:
replica.selector.class=org.apache.kafka.common.replica.RackAwareReplicaSelector설정, 모든 브로커에broker.rack(AZ ID) 지정컨슈머:
client.rack컨슈머 속성에 자기 AZ ID를 설정 — 앞서 설명한 zone 인지 방법으로 얻은 값을 주입Strimzi 사용 시: 오퍼레이터가 이를 내장 지원합니다.
yamlapiVersion: kafka.strimzi.io/v1beta2 kind: Kafka spec: kafka: rack: topologyKey: topology.kubernetes.io/zone config: replica.selector.class: org.apache.kafka.common.replica.RackAwareReplicaSelectorrack.topologyKey를 지정하면 Strimzi가 broker.rack 설정과 client rack을 파드에 주입하는 init-container를 자동으로 구성합니다.참고: KIP-881은 여기서 한 단계 더 나가, 컨슈머 그룹의 파티션 할당 자체를 rack 인지형으로 만듭니다.
Kafka on EKS 배포 전반은 data-on-eks/kafka/ 문서를 참고하세요.
Redis/Valkey (ElastiCache): AZ Affinity Read 전략
Valkey GLIDE 클라이언트는 ReadFrom 설정으로 4가지 read 전략을 지원합니다.
| 전략 | 동작 |
|---|---|
PRIMARY | 항상 primary에서 읽음 (기본값, AZ 무관) |
PREFER_REPLICA | replica 사이 라운드로빈, 실패 시 폴백 |
AZ_AFFINITY | 같은 AZ의 replica를 우선, 없으면 폴백 |
AZ_AFFINITY_REPLICAS_AND_PRIMARY | 같은 AZ의 replica 우선 → 같은 AZ의 primary → 최후에 다른 AZ |
Read 비율이 압도적으로 높은 워크로드(>99% read)에는 AZ_AFFINITY_REPLICAS_AND_PRIMARY가 비용 절감과 가용성의 균형점으로 권장됩니다.
from glide import GlideClient, GlideClientConfiguration, ReadFrom
config = GlideClientConfiguration(
addresses=[...],
read_from=ReadFrom.AZ_AFFINITY_REPLICAS_AND_PRIMARY,
client_az="ap-northeast-2a", # 파드가 속한 AZ — 앞서 설명한 방법으로 획득
)
client = await GlideClient.create(config)실사례로 HotelTrader는 Valkey GLIDE의 AZ affinity 라우팅 도입 후 인터-AZ 데이터 전송비를 95% 절감하고 평균 지연을 49% 개선했습니다 (AZ 인지 없이는 캐시 요청이 AZ와 무관하게 무작위 분산되어 불필요한 전송비가 발생하고 있었습니다). 자세한 내용은 AWS 데이터베이스 블로그를 참고하세요.
Aurora/RDS: Reader Endpoint의 한계와 우회
Aurora의 기본 reader endpoint는 AZ를 고려하지 않는 라운드로빈 DNS입니다 — 같은 AZ에 replica가 있어도 우선권이 없습니다. 이건 기능 누락이 아니라 현재 시점의 실제 제약이며, AZ affinity 자체를 요청하는 aws-advanced-jdbc-wrapper#1139 이슈가 아직 열려 있습니다.
우회 방법은 두 가지입니다.
AZ별 커스텀 엔드포인트: 특정 AZ의 replica 인스턴스 서브셋만 묶어 커스텀 엔드포인트를 만들고, 해당 AZ의 애플리케이션이 그 엔드포인트로 접속하도록 설정합니다.
bashaws rds create-db-cluster-endpoint \ --db-cluster-identifier my-aurora-cluster \ --db-cluster-endpoint-identifier reader-az-a \ --endpoint-type READER \ --static-members db-instance-az-a-1 db-instance-az-a-2AWS Advanced JDBC Wrapper: read/write splitting과
fastestResponse리더 선택 전략을 제공해, 완전한 AZ affinity는 아니지만 응답이 빠른(대체로 같은 AZ인) 리더를 선호하게 만듭니다.
완전한 AZ affinity가 필요하다면, 위 이슈가 해결되기 전까지는 ①번(커스텀 엔드포인트)이 유일하게 확실한 방법입니다.
Kubernetes 서비스 계층 보완
애플리케이션 계층에서 Service 트래픽 자체를 AZ에 고정하려면 Topology Aware Routing GA를, 서비스 메시를 쓴다면 Istio Zone-Aware Routing을 참고하세요. 이 문서의 데이터 계층 전략과 함께 쓰면 애플리케이션→캐시/DB/메시징까지 전체 read 경로가 AZ 안에 머뭅니다.
권장 조합 요약
| 계층 | 2026년 기준 권장 | 대안/폴백 |
|---|---|---|
| 아키텍처 | Zonal(싱글존) 클러스터 + Cell-Based Architecture | 멀티 AZ 단일 클러스터 (운영 인력이 적을 때) |
| 트래픽 전환 | Target Group + TargetGroupBinding + weight 조정 | Route 53 가중치 DNS (리전/계정이 다를 때) |
| 장애 대응 | ARC Zonal Shift (자동) | 수동 weight 조정 |
| 업그레이드 | Zonal In-Place + EKS 네이티브 롤백 (7일) | 블루/그린 클러스터 플릿 (완전한 사전 검증 필요 시) |
| Kafka read | KIP-392 (client.rack + RackAwareReplicaSelector), Strimzi는 rack.topologyKey | 리전 전역 폴백 허용 (팔로워 부재 시 자동) |
| 캐시 read | Valkey GLIDE AZ_AFFINITY_REPLICAS_AND_PRIMARY | PREFER_REPLICA (AZ 인지 불필요한 경우) |
| DB read | Aurora AZ별 커스텀 엔드포인트 | AWS Advanced JDBC Wrapper fastestResponse |
도입 순서는 트래픽 전환 계층 → 업그레이드/롤백 → 데이터 read 계층 순을 권장합니다. 앞 단계가 없으면 뒤 단계의 효과(특히 비용 절감)를 측정하기 어렵기 때문입니다.
< 이전: Tekton Pipelines | 목차 >