IL-0027 Backpackr · 2025-05-07 (게시일)kubernetesawsnetworking
백패커는 아이디어스를 운영하는 EKS 클러스터를 처음 구성할 때 CoreDNS 를 따로 최적화하지 않고 기본 설정 그대로 두었다. CoreDNS 파드는 2개였고, nodeSelector 로 온디맨드 타입의 운영 노드 그룹에만 배치했다. CoreDNS 파드에는 메모리 한도가 없어서 QoS 클래스가 BestEffort 였다.
쿠버네티스는 모든 파드의 /etc/resolv.conf 에 ndots:5 를 넣는다. 리졸버는 점이 다섯 개보다 적은 이름을 불완전한 이름으로 보고 검색 도메인을 하나씩 붙여 먼저 조회한다. 그 조회가 모두 실패한 뒤에야 원래 이름으로 조회한다. 그래서 idus.com 을 한 번 호출하면 idus.com.idus-backends.svc.cluster.local, idus.com.svc.cluster.local, idus.com.cluster.local, idus.com.ap-northeast-2.compute.internal, idus.com 순서로 최대 다섯 번 조회가 나갔고 마지막 조회만 성공했다. 트래픽이 급증하면 이 불필요한 조회가 고스란히 CoreDNS 에 몰렸다.
고가용성 설정도 없었다. 당시 EKS 버전의 CoreDNS 에는 PodDisruptionBudget 과 topologySpreadConstraints 가 기본으로 들어 있지 않았다. 어느 시점에 CoreDNS 파드가 모두 한 노드에 올라갔고, 그 노드의 메모리가 고갈되어 OOM 이 났다. kubelet 이 멈추면서 노드의 파드가 모두 CrashLoopBackOff 에 빠졌고, DNS 가 응답하지 않자 서비스 전체가 멈췄다.
백패커는 NodeLocalDNS Cache 를 도입하고, CoreDNS 에 고가용성 설정을 넣고, 워크로드의 ndots 를 2 로 낮춰 CoreDNS 부하를 나누었다. 도메인 끝에 점을 붙여 FQDN 으로 조회하는 방법은 모든 도메인 참조를 고쳐야 해서 유지보수가 어렵다고 보고 쓰지 않았다. Istio DNS 프록시도 검토했지만 NodeLocalDNS Cache 와 기능이 겹쳐 쓰지 않았다.
프로덕션 EKS 클러스터에서 원인을 바로 알기 어려운 서비스 에러가 간헐적으로 났다. RDS 나 Redis 같은 외부 서비스를 호출할 때 연결이 가끔 실패했다. DNS 요청이 몰릴 때는 도메인 조회 응답이 늦어지거나 조회가 아예 실패했다.
이 증상은 트래픽이 적은 개발 환경과 스테이징 환경에서는 잘 보이지 않았고, 트래픽이 큰 프로덕션 환경에서 두드러졌다.
팀은 처음에 애플리케이션 코드, 노드 리소스, 파드 상태, 컨테이너 설정을 차례로 점검했다. 자세히 조사한 끝에 외부 서비스 연결 실패의 근본 원인이 DNS 이름 해석 실패라는 것을 확인했다. 그다음 CoreDNS 의 캐시 설정과 bufsize 를 조정해 봤지만 증상이 잠깐 줄었을 뿐 근본 해결이 되지 않았다.
어느 시점에는 CoreDNS 파드가 모두 한 노드에 몰려 있었다. 그 노드의 메모리 사용률이 갑자기 치솟았고 노드에서 OOM 이 났다. kubelet 이 멈추면서 그 노드의 모든 파드가 CrashLoopBackOff 에 빠졌다. CoreDNS 도 응답하지 못했고 서비스 전체가 멈췄다.
원인 ? 용량 한계
글은 전면 장애를 어떻게 알아챘는지 적지 않았다. 그 전의 DNS 문제는 원인을 알기 어려운 서비스 에러가 간헐적으로 나면서 드러났다. 팀은 RDS 와 Redis 호출이 가끔 실패하는 현상을 추적하다가 DNS 이름 해석 실패가 근본 원인이라는 것을 확인했다.
–
쿠버네티스의 ndots:5 기본값은 점이 적은 외부 도메인을 조회할 때마다 질의를 여러 번 만든다. 이 부하는 트래픽이 큰 프로덕션 환경에서야 드러난다. CoreDNS 를 파드 2개의 기본 구성으로 두면 클러스터 전체의 단일 장애점이 된다. CoreDNS 파드는 노드와 가용 영역에 흩어 둔다. 별도 노드 그룹이나 Fargate 로 분리하면 다른 워크로드와 자원을 다투지 않는다. Affinity 와 PriorityClassName 으로 우선순위를 주면 더 안정적이다. CoreDNS 의 캐시와 bufsize 조정은 증상을 잠깐 줄였을 뿐이다. ndots 값은 여러 자료가 1이나 2를 권하지만 각 환경에 맞춰 정해야 한다.
같은 원인 · 공통 노드 풀, CoreDNS, 컨테이너 메모리 한도
같은 원인 · 공통 CoreDNS, 클라이언트 쪽 DNS 리졸버와 캐시, 컨테이너 메모리 한도
같은 원인 · 공통 노드 풀, CoreDNS
같은 원인 · 공통 CoreDNS, 클라이언트 쪽 DNS 리졸버와 캐시
같은 원인 · 공통 노드 풀, CoreDNS
같은 원인 · 공통 노드 풀, 컨테이너 메모리 한도
같은 원인 · 공통 kubelet, 컨테이너 메모리 한도
같은 원인 · 공통 노드 풀, 컨테이너 메모리 한도
같은 원인 · 공통 노드 풀, 컨테이너 메모리 한도
같은 원인 · 공통 kubelet
같은 원인 · 공통 CoreDNS
같은 원인 · 공통 컨테이너 메모리 한도
같은 원인 · 공통 CoreDNS
같은 원인 · 공통 컨테이너 메모리 한도
같은 원인 · 공통 컨테이너 메모리 한도
같은 원인 · 공통 노드 풀
같은 원인 · 공통 컨테이너 메모리 한도
같은 원인 · 공통 kubelet
같은 원인 · 공통 클라이언트 쪽 DNS 리졸버와 캐시
같은 원인 · 공통 컨테이너 메모리 한도
같은 원인 · 공통 kubelet