K8s Topology Aware Routing

K8s Topology Aware Routing이란?

멀티존 클러스터에서 Service 트래픽은 기본적으로 모든 존의 Pod에 균등 분배됩니다. Zone A의 클라이언트가 Zone C의 Pod에 요청하면 불필요한 크로스존 네트워크 비용과 지연이 발생합니다. Topology Aware Routing(구 Topology Aware Hints)은 트래픽을 같은 존의 Pod으로 우선 라우팅하여 비용과 레이턴시를 동시에 줄이는 K8s 네이티브 기능입니다.

1. 크로스존 트래픽 비용 문제

클라우드 같은 존 트래픽 크로스존 트래픽 크로스리전
AWS 무료 $0.01/GB (양방향) $0.02/GB
GCP 무료 $0.01/GB $0.02~0.08/GB
Azure 무료 $0.01/GB $0.02~0.05/GB

마이크로서비스가 10개이고 서비스 간 평균 트래픽이 월 1TB라면, 크로스존 라우팅으로 인한 추가 비용은 월 $100~200에 달할 수 있습니다. Topology Aware Routing은 이를 대부분 제거합니다.

2. 활성화 방법

Service에 어노테이션 하나만 추가하면 됩니다.

apiVersion: v1
kind: Service
metadata:
  name: api-server
  annotations:
    # K8s 1.27+ 권장 방식
    service.kubernetes.io/topology-mode: Auto
    
    # K8s 1.23~1.26 (구 방식, 여전히 동작)
    # service.kubernetes.io/topology-aware-hints: Auto
spec:
  selector:
    app: api-server
  ports:
  - port: 80
    targetPort: 8080

Auto로 설정하면 kube-proxy가 EndpointSlice의 hints 필드를 참조하여 같은 존의 엔드포인트로 트래픽을 라우팅합니다.

3. 내부 동작 원리

EndpointSlice Controller가 각 엔드포인트에 hints.forZones를 할당하는 과정입니다.

# EndpointSlice에 hints가 추가된 모습
apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
  name: api-server-abc12
  labels:
    kubernetes.io/service-name: api-server
endpoints:
- addresses: ["10.1.1.10"]
  zone: "us-east-1a"
  conditions:
    ready: true
  hints:
    forZones:
    - name: "us-east-1a"    # 이 엔드포인트는 Zone A 트래픽 담당

- addresses: ["10.1.2.20"]
  zone: "us-east-1b"
  conditions:
    ready: true
  hints:
    forZones:
    - name: "us-east-1b"    # Zone B 트래픽 담당

- addresses: ["10.1.3.30"]
  zone: "us-east-1c"
  conditions:
    ready: true
  hints:
    forZones:
    - name: "us-east-1c"    # Zone C 트래픽 담당

kube-proxy는 iptables/IPVS 규칙 생성 시 자신의 노드가 속한 존과 일치하는 hints를 가진 엔드포인트만 규칙에 포함합니다.

단계 담당 컴포넌트 동작
1. 노드 토폴로지 감지 kubelet topology.kubernetes.io/zone 레이블 설정
2. 힌트 계산 EndpointSlice Controller 존별 CPU 비율 기반 엔드포인트 할당
3. 라우팅 규칙 생성 kube-proxy 같은 존 hints의 엔드포인트만 규칙에 포함
4. 트래픽 전달 iptables/IPVS 로컬 존 엔드포인트로 전달

4. 자동 비활성화 조건

EndpointSlice Controller는 안전하지 않은 상황에서 자동으로 hints를 제거합니다.

# hints가 제거되는 조건들:

# 1. 존 간 엔드포인트 불균형이 심한 경우
#    - 한 존에 Pod 10개, 다른 존에 1개 → hints 제거
#    - 기준: 존별 할당량 차이가 엔드포인트 수 대비 과도할 때

# 2. 엔드포인트 수가 너무 적은 경우 (존 수보다 적으면)
#    - 3존 클러스터에 Pod 2개 → 1개 존에 엔드포인트 없음 → 비활성화

# 3. 특정 존에 노드가 없는 경우

# 4. kube-proxy가 topology aware routing을 지원하지 않는 경우
# hints 적용 여부 확인
kubectl get endpointslice -l kubernetes.io/service-name=api-server -o yaml 
  | grep -A 2 hints

# 비활성화 이벤트 확인
kubectl describe svc api-server
# Events:
#   TopologyAwareHintsDisabled: zone "us-east-1c" has no allocatable endpoints

5. Pod 배치 전략: TopologySpreadConstraints

Topology Aware Routing이 효과적으로 동작하려면 Pod이 존별로 균등 배치되어야 합니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-server
spec:
  replicas: 6  # 3존 × 2개씩
  template:
    spec:
      topologySpreadConstraints:
      - maxSkew: 1                    # 존 간 최대 1개 차이
        topologyKey: topology.kubernetes.io/zone
        whenUnsatisfiable: DoNotSchedule
        labelSelector:
          matchLabels:
            app: api-server
      
      # 존 내에서도 노드 분산 (선택)
      - maxSkew: 1
        topologyKey: kubernetes.io/hostname
        whenUnsatisfiable: ScheduleAnyway
        labelSelector:
          matchLabels:
            app: api-server
      
      containers:
      - name: api
        image: api-server:latest
        resources:
          requests:
            cpu: 250m
            memory: 256Mi
replicas 3존 배치 TAR 동작
3 1-1-1 ✅ 각 존 1개씩 라우팅
6 2-2-2 ✅ 이상적
2 1-1-0 ❌ hints 제거 (1개 존 비어있음)
4 2-1-1 ⚠️ 불균형하지만 동작 가능

6. Istio/Cilium과의 통합

# Istio: DestinationRule로 locality 기반 라우팅
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
  name: api-server
spec:
  host: api-server.default.svc.cluster.local
  trafficPolicy:
    connectionPool:
      tcp:
        maxConnections: 100
    outlierDetection:
      consecutive5xxErrors: 5
      interval: 30s
      baseEjectionTime: 30s
    # Istio locality load balancing
    loadBalancer:
      localityLbSetting:
        enabled: true
        # 같은 존 실패 시 인접 존으로 폴백
        failover:
        - from: us-east-1a
          to: us-east-1b
        - from: us-east-1b
          to: us-east-1a
        - from: us-east-1c
          to: us-east-1a
      # 분배 비율 세밀 제어
      distribute:
      - from: us-east-1a/*
        to:
          "us-east-1a/*": 80
          "us-east-1b/*": 10
          "us-east-1c/*": 10
# Cilium: 네이티브 topology aware routing 지원
# cilium-config ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: cilium-config
  namespace: kube-system
data:
  enable-service-topology: "true"
  # Cilium은 eBPF로 kube-proxy 없이 직접 라우팅
  # EndpointSlice hints를 eBPF 맵에 반영

7. 모니터링: 크로스존 트래픽 측정

# kube-proxy 메트릭으로 hints 적용 확인
kubectl port-forward -n kube-system ds/kube-proxy 10249:10249

# topology aware hints가 적용된 엔드포인트 수
curl localhost:10249/metrics | grep endpoint_slice

# Prometheus 쿼리: 크로스존 트래픽 비율
# (Istio 사용 시)
sum(rate(istio_tcp_sent_bytes_total{
  source_workload_namespace="default",
  source_zone!="destination_zone"
}[5m])) /
sum(rate(istio_tcp_sent_bytes_total{
  source_workload_namespace="default"
}[5m]))

# 결과: 0.05 = 5%만 크로스존 (TAR 적용 전 ~66%)
# AlertRule: TAR 비활성화 감지
groups:
- name: topology-routing
  rules:
  - alert: TopologyAwareRoutingDisabled
    expr: |
      kube_service_annotations{
        annotation_service_kubernetes_io_topology_mode="Auto"
      } unless on(service, namespace)
      kube_endpoint_slice_hints_zone_count > 0
    for: 10m
    labels:
      severity: warning
    annotations:
      summary: "{{ $labels.service }}의 Topology Aware Routing이 비활성화됨"

8. 트러블슈팅 체크리스트

증상 원인 해결
hints가 생성되지 않음 노드에 zone 레이블 없음 kubectl get nodes --show-labels | grep zone
hints가 있다가 사라짐 Pod 불균형 (스케일 다운 후) TopologySpreadConstraints + replicas ≥ 존 수
특정 존에서 타임아웃 해당 존 Pod 모두 비정상 readinessProbe 점검, PDB 설정
존 간 부하 불균형 존별 클라이언트 수 차이 HPA minReplicas를 존별 트래픽 비례 설정
externalTrafficPolicy: Local과 충돌 두 메커니즘 동시 적용 하나만 선택 (TAR이 더 유연)

마무리

Topology Aware Routing은 어노테이션 한 줄로 크로스존 트래픽을 대폭 줄이는 강력한 최적화입니다. 핵심은 Pod의 존별 균등 배치(topologySpreadConstraints)가 전제되어야 한다는 점입니다. replicas가 존 수보다 적으면 자동 비활성화되므로, K8s HPA 오토스케일링의 minReplicas를 존 수 이상으로 설정하고, Prometheus 모니터링으로 크로스존 트래픽 비율을 지속 추적하는 것을 권장합니다.

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