IT/Kubernets

Service의 PreferSameNode 트래픽 분산, 이거 모르는 분 꽤 많더라

gfrog 2026. 7. 14. 00:13

크로스존 트래픽 비용 청구서를 보고 눈을 의심한 적이 있다. AZ 세 개에 노드가 흩어져 있는 EKS 클러스터에서, 결제 API가 유저 서비스를 호출하는데 세 번에 한 번은 다른 AZ로 넘어간다. NAT는 아니지만 AZ 간 트래픽은 GB당 $0.01. 요청 하나로는 티끌인데 P99 QPS로 곱해보면 월 결제서에 꽤 나온다.

Kubernetes 1.34에서 Service의 spec.trafficDistributionPreferSameNode가 GA로 붙었다. 원래 있던 PreferClose(구 PreferSameZone)에 이어서 나온건데, 같은 노드에 엔드포인트가 있으면 무조건 거기로 보낸다. 없을 때만 외부로 나간다. 아주 간단한데 효과가 크다.

어떻게 쓰나

apiVersion: v1
kind: Service
metadata:
  name: user-svc
spec:
  trafficDistribution: PreferSameNode
  selector:
    app: user
  ports:
  - port: 8080

끝이다. 필드 한 줄. PreferClose도 그렇지만 이건 힌트일 뿐이라 라우팅이 완벽하게 100% 로컬로만 가진 않는다. 로컬 파드가 없으면 어쩔 수 없이 다른 노드로 나간다. 근데 이게 오히려 좋다. 강제 로컬이면 파드 하나 죽으면 트래픽이 뚝 끊길 텐데, 힌트라서 자연스럽게 페일오버된다.

쓸 때 조심할 것

우리 팀에서 며칠 붙여보고 정리한 것들.

첫째, DaemonSet 스타일 사이드카에 특히 잘 맞는다. OpenTelemetry Collector나 Fluent Bit처럼 노드마다 한 개씩 뜨는 서비스면, 같은 노드의 파드가 항상 로컬 콜렉터로 붙어서 네트워크 홉이 사라진다. Otel Collector agent 모드 쓰는 팀은 이거 켜면 P50 latency가 눈에 띄게 떨어진다.

둘째, 워크로드 분산이 극단적으로 치우칠 수 있다. 노드 A에 파드가 3개, 노드 B에 1개면, A에서 오는 요청은 A의 파드가 다 받는다. 트래픽이 특정 노드에 몰리면 그 파드들만 CPU가 튄다. HPA는 잘 붙지만, PDB랑 topologySpreadConstraints를 같이 안 걸어두면 스케일 아웃 시에도 배치가 편향된다.

셋째, kube-proxy 버전 체크. 1.34 클러스터라도 kube-proxy가 예전 iptables 모드면 라우팅 힌트를 완전히 못 살린다. nftables 모드나 Cilium kube-proxy replacement 쓰면 훨씬 잘 붙는다. 우리는 nftables로 넘어가면서 겸사겸사 켰다.

결과

붙이기 전 대비 크로스존 트래픽이 대략 40% 정도 줄었다. AZ 밸런싱이 어떻게 되어있냐에 따라 편차가 크니까 이 숫자는 참고만 하자. 그리고 뭐 이 정도 트래픽 비용이 큰 팀이 얼마나 있겠냐만, 관측성 사이드카 홉을 줄이는 부수효과가 더 크더라.

혹시 이미 PreferClose로 zone-aware 라우팅만 쓰고 있다면, 노드 단위까지 좁혀보는 것도 시험해볼 만하다. 물론 배치 편향은 monitoring 잘 걸어놓고.

참고