2025-05-05 9:00 AM
Kubernetes 클러스터, 특히 AWS EKS와 같은 클라우드 환경에서는 여러 가용 영역(Availability Zone, AZ)에 걸쳐 워크로드가 배포됩니다. 서로 다른 AZ 간 통신은 추가적인 네트워크 비용과 지연 시간을 발생시키는데, 이를 최소화하기 위해 Kubernetes에서는 토폴로지 인식 트래픽 라우팅 기능을 제공합니다.
이 문서에서는 Kubernetes의 토폴로지 인식 라우팅 기능의 발전 과정과 최신 방식인 trafficDistribution: PreferClose
옵션을 EKS 환경에서 테스트한 결과를 공유합니다.
Kubernetes에서 토폴로지 인식 라우팅 기능은 다음과 같이 발전해왔습니다:
v1.21 (알파): "Topology Aware Hints"라는 이름으로 처음 도입
TopologyAwareHints
기능 게이트 필요service.kubernetes.io/topology-aware-hints
어노테이션 사용v1.23 (베타): 베타 단계로 승격
v1.24: 기능 게이트가 기본적으로 활성화
v1.27: 이름 및 어노테이션 변경
service.kubernetes.io/topology-mode
로 변경v1.28: EndpointSlice의 hints 필드만 GA 목표
v1.33 (예정):
service.kubernetes.io/topology-mode
어노테이션이 deprecated 예정spec.trafficDistribution
필드가 GA로 승격 예정trafficDistribution: PreferClose
는 Kubernetes Service 리소스의 필드로, 같은 AZ 내에서 우선적으로 트래픽을 분산시키는 기능을 제공합니다. 이를 통해 AZ 간 네트워크 통신을 최소화하여 지연 시간과 데이터 전송 비용을 줄일 수 있습니다.
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
trafficDistribution: PreferClose # v1.33에서 GA 예정
v1.33 이전 버전에서는 아래와 같이 어노테이션을 사용 (Kubernetes v1.27 이상):
apiVersion: v1
kind: Service
metadata:
name: my-service
annotations:
service.kubernetes.io/topology-mode: Auto
spec:
selector:
app: my-app
ports:
- port: 80
테스트는 ap-northeast-2 리전의 EKS 클러스터에서 수행되었으며, 노드는 A존과 C존에 분산 배치되었습니다.
# 네임스페이스
apiVersion: v1
kind: Namespace
metadata:
name: topo-test
---
# 애플리케이션: test-app (5 replicas, 기본 스케줄링)
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-app
namespace: topo-test
spec:
replicas: 5
selector:
matchLabels:
app: test-app
template:
metadata:
labels:
app: test-app
spec:
containers:
- name: http-echo
image: hashicorp/http-echo:0.2.3
args:
- "-text=$(POD_NAME)"
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
ports:
- containerPort: 5678
---
# Service: ClusterIP + PreferClose
apiVersion: v1
kind: Service
metadata:
name: test-app-svc
namespace: topo-test
spec:
type: ClusterIP
selector:
app: test-app
ports:
- port: 80
targetPort: 5678
trafficDistribution: PreferClose
---
# A존 클라이언트
apiVersion: apps/v1
kind: Deployment
metadata:
name: client-a
namespace: topo-test
spec:
replicas: 1
selector:
matchLabels:
app: client-a
template:
metadata:
labels:
app: client-a
spec:
nodeSelector:
topology.kubernetes.io/zone: ap-northeast-2a
containers:
- name: curl
image: nicolaka/netshoot:latest
command: ["sleep","3600"]
---
# C존 클라이언트
apiVersion: apps/v1
kind: Deployment
metadata:
name: client-c
namespace: topo-test
spec:
replicas: 1
selector:
matchLabels:
app: client-c
template:
metadata:
labels:
app: client-c
spec:
nodeSelector:
topology.kubernetes.io/zone: ap-northeast-2c
containers:
- name: curl
image: nicolaka/netshoot:latest
command: ["sleep","3600"]
EndpointSlice에는 각 Pod의 AZ 정보가 힌트로 저장되어 있습니다.
kubectl -n topo-test get endpointslices \
-l kubernetes.io/service-name=test-app-svc \
-o jsonpath='{.items[*].endpoints[*].hints.forZones}'
결과:
[{"name":"ap-northeast-2c"}] [{"name":"ap-northeast-2a"}] [{"name":"ap-northeast-2a"}] [{"name":"ap-northeast-2a"}] [{"name":"ap-northeast-2c"}]
11 test-app-6477bdcb89-btrhg
13 test-app-6477bdcb89-d7jv8
6 test-app-6477bdcb89-m5ds6
분석: A존 클라이언트의 모든 요청이 A존에 위치한 3개의 Pod으로만 분산되었습니다.
19 test-app-6477bdcb89-79xq5
11 test-app-6477bdcb89-rclxt
분석: C존 클라이언트의 모든 요청이 C존에 위치한 2개의 Pod으로만 분산되었습니다.
A존의 Pod를 모두 제거하고 C존에만 Pod이 있는 상황에서 테스트했습니다.
9 test-app-54fb4d54c6-9vvtj
12 test-app-54fb4d54c6-hl2r4
9 test-app-54fb4d54c6-wv2qw
분석: A존에 Pod이 없으므로, 클러스터 전체(실제로는 C존)의 Pod로 트래픽이 분산되었습니다.
A존과 C존에 다시 Pod을 분산 배치한 후 테스트했습니다.
12 test-app-6477bdcb89-k6p49
18 test-app-6477bdcb89-pmfm2
분석: A존 클라이언트의 요청이 다시 A존 Pod에게만 분산되었습니다.
Kubernetes에서는 AZ 간 통신을 최적화하기 위한 두 가지 주요 접근 방식이 있습니다:
apiVersion: v1
kind: Service
metadata:
name: my-service
annotations:
service.kubernetes.io/topology-mode: Auto # v1.27부터 사용, v1.33에서 Deprecated 예정
spec:
selector:
app: my-app
ports:
- port: 80
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- port: 80
trafficDistribution: PreferClose # v1.33에서 GA 예정
분산 알고리즘:
적용 우선순위:
service.kubernetes.io/topology-mode
어노테이션이 Auto로 설정된 경우, trafficDistribution
필드보다 우선 적용됩니다.버전 상태:
service.kubernetes.io/topology-mode
: v1.27부터 도입되었으며, v1.33에서 deprecated 예정trafficDistribution
: v1.33에서 GA(정식 버전)로 승격 예정Kubernetes 버전 기준:
trafficDistribution: PreferClose
사용 권장 (GA 버전)trafficDistribution: PreferClose
권장service.kubernetes.io/topology-aware-hints: Auto
사용기능적 요구사항 기준:
trafficDistribution: PreferClose
권장topology-mode: Auto
고려 (v1.33 이전 버전에서)마이그레이션 계획:
trafficDistribution: PreferClose
로 마이그레이션할 계획 수립 필요Pod 분포 관리:
PreferClose
를 사용할 경우, 애플리케이션 Pod이 AZ 간에 적절하게 분산되도록 관리해야 합니다.가용성과 복원력:
모니터링:
단계적 적용:
EKS 환경에서 토폴로지 인식 라우팅 기능, 특히 trafficDistribution: PreferClose
옵션을 사용하면 다음과 같은 이점을 얻을 수 있습니다:
테스트 결과, trafficDistribution: PreferClose
옵션은 의도한 대로 정확하게 작동하며, 로컬 AZ 내에서 트래픽을 효과적으로 유지하는 것을 확인했습니다. 이는 특히 마이크로서비스 아키텍처에서 서비스 간 호출이 많은 경우 상당한 비용 절감과 성능 향상을 가져올 수 있습니다.
쿠버네티스 v1.33에서는 trafficDistribution: PreferClose
가 GA로 승격될 예정이므로, 장기적인 관점에서 새로운
서비스에는 이 방식을 적용하는 것이 권장됩니다. 기존에 topology-mode: Auto
어노테이션을 사용 중인 서비스는 향후 v1.33 이후에 점진적으로 마이그레이션을 계획하는 것이 좋습니다.