IT/AWS

EKS CoreDNS, 노드 늘리기 전에 이거 먼저 보자

gfrog 2026. 5. 26. 12:43
반응형

클러스터 트래픽이 늘 때 우리 팀이 가장 먼저 듣는 얘기는 보통 이거다. "노드 부족한 거 아니에요?" 근데 막상 들여다보면 노드는 멀쩡한데 DNS 쪽에서 병목이 생긴 경우가 절반쯤 된다. 특히 EKS에서 default 설정 그대로 굴리고 있으면 CoreDNS는 2개 파드로 묶여서 같은 AZ에 떨어져 있는 일도 흔하다.

이 글은 EKS CoreDNS를 운영하면서 트래픽이 늘기 시작했을 때 가장 먼저 점검해야 하는 3가지를 정리한 가이드다. 정말로 노드를 더 붙이기 전에, DNS 레이어부터 들여다보자는 얘기.

1. CoreDNS 파드 분산 — topologySpreadConstraints

이게 의외로 묻혀 있는 변화인데, EKS의 CoreDNS add-on이 v1.9.3-eksbuild.11 그리고 v1.10.1-eksbuild.7 부터 topologySpreadConstraints를 기본으로 박아준다. 이전에는 안 들어가 있어서 노드 2~3개짜리 작은 클러스터에서는 CoreDNS 2개가 같은 AZ에 떨어지는 게 비일비재했다.

기본값은 대충 이렇게 들어간다.

topologySpreadConstraints:
  - maxSkew: 1
    topologyKey: topology.kubernetes.io/zone
    whenUnsatisfiable: ScheduleAnyway
    labelSelector:
      matchLabels:
        k8s-app: kube-dns

whenUnsatisfiable: ScheduleAnyway 라서 강제는 아니다. 노드가 한쪽 AZ에만 있으면 그냥 거기 떨어진다. 그래도 분산 가능한 상황이면 알아서 분산해 주는 게 어디인가.

근데 자기 클러스터의 add-on 버전이 저 버전 미만이면 이 기본값을 못 받는다. 확인은 한 줄.

aws eks describe-addon \
  --cluster-name my-cluster \
  --addon-name coredns \
  --query 'addon.addonVersion'

버전이 낮으면 그냥 add-on 업데이트하면 된다. 만약 본인이 직접 advanced configuration으로 topologySpreadConstraints를 override 하고 있다면? 그건 그것대로 우선되니까 안심하고 add-on 업데이트해도 된다.

추가로 한 가지. 노드 수가 적은 환경에서는 topology.kubernetes.io/zone 외에 kubernetes.io/hostname 키로도 spread를 한 번 더 걸어두는 걸 추천한다. 같은 노드에 CoreDNS가 몰리는 건 사실 더 흔한 사고다.

2. 오토스케일링 — replicaCount 박지 말고 proportional autoscaler

EKS 콘솔에서 add-on 만질 때 replicaCount 박아두고 끝내는 팀이 많은데, 노드 수가 변동이 큰 클러스터에서는 이게 문제가 된다. 노드 50대일 때도 CoreDNS 2개, 5대일 때도 2개. 노드 늘면 DNS QPS도 비례해서 늘 텐데 CoreDNS는 그대로다.

해결책은 cluster-proportional-autoscaler. CoreDNS replica를 노드 수에 비례해서 자동으로 늘려준다.

# coredns-autoscaler configmap
linear: |
  {
    "coresPerReplica": 256,
    "nodesPerReplica": 16,
    "min": 2,
    "max": 20,
    "preventSinglePointFailure": true
  }

nodesPerReplica: 16 으로 두면 노드 16대마다 CoreDNS 1개씩. 노드 80대면 5개. 우리 팀은 작년에 노드 30대 클러스터에서 점심시간만 되면 DNS 타임아웃이 튀길래 뭔가 했는데, 결국 CoreDNS가 2개로 고정되어 있었던 게 원인이었다. autoscaler 붙이고 나서는 조용해졌다.

HPA를 쓰는 팀도 있는데, CoreDNS 같은 시스템 컴포넌트는 메트릭 의존도가 낮은 proportional autoscaler가 더 안정적이라고 본다. metric-server가 잠깐 흔들려도 영향 안 받는다.

3. NodeLocal DNSCache, 진짜 필요할 때만 켜자

NodeLocal DNSCache는 노드마다 DNS 캐시 데몬을 띄워서 conntrack 부담을 줄이고 P99를 안정화시키는 도구다. 효과는 분명히 있다. 근데 무조건 켜라는 건 아니다.

체크리스트 먼저 보자.

  • 외부 도메인 호출이 많은가? (S3 endpoint, RDS, 외부 API 등)
  • conntrack table full 에러나 DNS timeout이 메트릭에 잡히는가?
  • P99 DNS resolution이 50ms를 넘기는가?

세 개 중 둘 이상 해당되면 켜는 걸 검토해 볼 만하다. 그게 아니면 그냥 CoreDNS 잘 튜닝하는 게 더 효율적이다. NodeLocal은 추가 데몬셋이 노드마다 떠야 하니 메모리 사용량도 그만큼 늘고, hostNetwork에 169.254 link-local IP를 박는 방식이라 디버깅 난이도가 한 단계 올라간다.

실제로 우리 팀은 처음에 무지성으로 켰다가, 다음 번 클러스터 업그레이드할 때 NodeLocal 이미지 호환성 때문에 한참 헤맸다. 그 이후로는 "정말 필요한가?" 한 번 더 묻고 결정한다.

켜기로 했다면 kube-proxy 모드(iptables vs ipvs)에 따라 데몬셋 yaml이 조금 달라진다는 점만 주의하자. 공식 문서에 두 가지 매니페스트가 같이 올라와 있다.

정리

노드 늘리기 버튼 누르기 전에:

  1. CoreDNS add-on 버전 확인하고 topologySpreadConstraints 들어와 있는지 본다
  2. replica 고정 박혀 있으면 proportional autoscaler로 바꾼다
  3. DNS 메트릭(타임아웃, P99) 확인하고 필요하면 NodeLocal DNSCache 검토

세 가지 점검만 해도 "노드 부족 같은데요" 라는 진단이 사실은 DNS 문제였다는 결론에 도달하는 경우가 꽤 있다. 노드 추가는 비용이고, DNS 튜닝은 설정값 몇 줄이다. 어느 쪽을 먼저 해야 할지는 자명하다.

혹시 다른 DNS 튜닝 팁 있으신 분 있으면 댓글로 알려주세요. NodeLocal 켜고 안 켜고로 토론 한번 해보고 싶다.

반응형