CoreDNS 모니터링 및 최적화 가이드
📅 작성일: 2025-05-20 | 수정일: 2026-02-18 | ⏱️ 읽는 시간: 약 13분
Amazon EKS와 최신 Kubernetes 클러스터에서 CoreDNS는 클러스터 내 모든 서비스 디스커버리와 외부 도메인 이름 해석을 담당하는 핵심 컴포넌트입니다. CoreDNS의 성능과 가용성은 애플리케이션 응답 시간과 안정성에 직접적인 영향을 미치기 때문에, 효과적인 모니터링 및 최적화 아키텍처를 구축하는 것이 중요합니다. 이 아티클에서는 CoreDNS 성능 모니터링 메트릭, TTL 설정 가이드, 모니터링 아키텍처 모범 사례, AWS 권장 사항 및 실무 사례를 분석합니다. 각 섹션에서는 Prometheus 메트릭, Amazon EKS 환경에서의 적용 예시를 활용하여 CoreDNS 모니터링 전략을 알아봅니다.
1. CoreDNS 성능 모니터링: 주요 Prometheus 메트릭과 의미
CoreDNS는 metrics 플러그인을 통해 Prometheus 형식의 메트릭을 제공하며, 기본적으로 EKS에서는 kube-dns 서비스의 9153 포트로 노출됩니다. 핵심 메트릭들은 DNS 요청의 처리량, 지연 시간, 오류, 캐 싱 효율 등을 보여주며, 이를 모니터링함으로써 DNS 성능 병목이나 장애 징후를 빠르게 포착할 수 있습니다.
CoreDNS 4 Golden Signals
CoreDNS 핵심 Prometheus 메트릭
이 외에도 요청/응답 크기(coredns_dns_request_size_bytes, ...response_size_bytes), DO 비트 설정 여부(coredns_dns_do_requests_total) 등의 메트릭이 제공되며, CoreDNS에 로드된 플러그인별 추가 메트릭도 존재할 수 있습니다. 예를 들어 Forward 플러그인을 통한 업스트림 질의 시간(coredns_forward_request_duration_seconds)이나 kubernetes 플러그인의 API 업데이트 지연(coredns_kubernetes_dns_programming_duration_seconds) 등이 있습니다.
주요 메트릭 의미 및 활용
예를 들어 coredns_dns_requests_total의 초당 증가율로 DNS QPS를 파악하고, 이를 CoreDNS Pod별로 나누어 부하가 균등한지 확인합니다. QPS가 지속적으로 증가하면 CoreDNS 스케일 아웃이 필요한지 검토합니다. coredns_dns_request_duration_seconds의 99퍼센타일이 평소보다 높아지면, CoreDNS가 응답 지연을 겪고 있다는 의미이므로 업스트림 DNS 지연이나 CoreDNS CPU/메모리 포화 여부를 점검합니다. 이 때 CoreDNS 캐시(coredns_cache_hits_total) hit 비율이 낮다면, TTL이 너무 짧아 캐시효과가 떨어지는지 확인하고 조정합니다. coredns_dns_responses_total에서 SERVFAIL 또는 REFUSED 비율이 증가하면 CoreDNS 외부 통신 문제나 접근 권한 문제가 없는지 로그를 점검해야 합니다. 한편 NXDOMAIN 증가가 특정 도메인에 대해 급증한다면, 애플리케이션이 잘못된 도메인을 조회하고 있을 수 있으므로 해당 부분을 수정해야 합니다.
또한 시스템 리소스 메트릭 (CPU/메모리)도 중요합니다. CoreDNS Pod의 CPU/메모리 사용률을 모니터링하여, 각 Pod가 리소스 한계에 근접하는 경우 알림을 설정합니다. 예를 들어 EKS의 기본 CoreDNS 메모리 요청/제한은 70Mi/170Mi로 설정되어 있으므로, 메모리 사용량이 150Mi를 넘어서는지 추적하여 임계치 도달 시 경보를 울리고 메모리 한계를 늘리거나 Pod을 추가하는 등의 조치를 취할 수 있습니다. CPU도 제한 에 도달하면 kubelet이 CoreDNS 프로세스를 스로틀링하여 DNS 지연을 초래할 수 있으므로, CPU 사용률이 제한치에 근접하면 확장이나 자원 할당 증설을 고려해야 합니다.
각 노드 ENI는 초당 1024개의 DNS 패킷만 허용합니다. CoreDNS의 max_concurrent 한계를 풀어도, ENI PPS 한계(1024 PPS)의 제한으로 인하여 원하는 성능에 도달하지 못할 수도 있습니다.
2. CoreDNS TTL 설정 가이드 및 Amazon EKS 적용 예시
**TTL(Time-To-Live)**은 DNS 레코드의 유효 캐시 시간을 의미하며, 적절한 TTL 설정은 DNS 트래픽 부하와 정보 신선도 사이의 균형을 좌우합니다. CoreDNS에서는 두 가지 수준에서 TTL을 다룹니다:
- 권한 영역 레코드(SOA, Start of Authority) TTL: Kubernetes 클러스터 내부 도메인(
cluster.local등)에 대한 kubernetes 플러그인 응답 TTL로, 기본 값은 5초입니다. CoreDNSCorefile에서kubernetes섹션에ttl옵션을 지정하여 변경할 수 있으며, 최소 0초(캐싱 안 함)에서 최대 3600초까지 설정 가능합니다. - 캐시 TTL: cache 플러그인에서 캐시된 항목을 보관하는 최대 시간으로, 기본값은 **최대 3600초 (성공 응답)**이며 CoreDNS 설정에서
cache [TTL]형태로 조정할 수 있습니다. 지정된 TTL은 상한치로 동작하며, 실제 DNS 레코드의 TTL이 그보다 짧으면 그 짧은 값에 따라 캐시에서 제거됩니다. (cache플러그인의 기본 최소 TTL은 5초이며,MINTTL로 조정 가능).
Amazon EKS 기본 CoreDNS 설정
EKS에 배포되는 기본 CoreDNS Corefile을 살펴보면, kubernetes 플러그인에 별도의 TTL이 지정되지 않아 기본 5초가 사용되고 있고, 대신 cache 30 설정을 통해 모든 DNS 응답을 최대 30초까지 캐시하도록 구성되어 있습니다. 즉 내부 서비스 레코드의 TTL은 응답 패킷상 5초이지만, CoreDNS 자체는 cache 플러그인으로 최대 30초간 응답을 캐싱하여 동일한 질의에 대해 빈번히 Kubernetes API를 조회하지 않도록 최적화합니다. 또한 외부 도메인 조회 시에도 최대 30초간 결과를 캐싱하여, 예를 들어 TTL이 매우 큰 외부 레코드라도 30초 이후에는 갱신하도록 함으로써 지나치게 오래된 DNS 정보를 들고 있지 않도록 합니다.
TTL 설정 가이드
일반적으로 **짧은 TTL(예: 5초 이하)**은 DNS 레코드 변경사항(예: 새로운 서비스 IP나 Pod IP 변화)이 신속히 반영되는 장점이 있으나, 클라이언트나 DNS 캐시에 의한 반복 조회가 많아 CoreDNS 부하가 증가할 수 있습니다. 반대로 **긴 TTL(예: 수분 이상)**은 DNS 질의 빈도를 줄여 성능을 높이지만, 변경 사항 전파가 지연되어 구형 정보로 인한 일시적 연결 실패 가능성이 커집니다. 권장되는 접근법은 클러스터 크기와 워크로드 패턴에 따라 TTL을 적당히 (수십 초 단위) 늘려 캐시 적중률을 높이면서 심각한 정보 지연은 피하는 것입니다. 많은 Kubernetes 환경에서 TTL 30초 전후가 하나의 기준으로 사용됩니다.
Amazon EKS 적용 예시
EKS에서 TTL을 조정하려면 CoreDNS ConfigMap을 수정해야 합니다. 예를 들어 내부 도메인 캐시 시간을 늘리고자 한다면, Corefile의 kubernetes cluster.local ... 블록에 ttl 30을 추가할 수 있습니다. 이렇게 하면 클러스터 내부 DNS 응답의 TTL 필드가 30초로 증가하여, 클라이언트 측(예: NodeLocal DNSCache나 애플리케이션 런타임)이 이를 참고해 캐싱할 경우 30초간 재조회하지 않게 됩니다. 다만 Kubernetes 환경에서는 일반적인 리눅스 glibc resolver가 자체 캐시를 하지 않고 매번 CoreDNS에 조회하기 때문에, NodeLocal DNSCache와 같은 보조 캐시가 없으면 TTL을 늘려도 클라이언트 측 이점은 제한적입니다. 주로 CoreDNS 자체의 부하 경감을 위하여 TTL을 조정하게 됩니다.
AWS Aurora와 같이 **DNS 로드밸런싱을 위해 매우 낮은 TTL(1초)**을 사용하는 서비스가 있습니다. 이 경우 CoreDNS가 기본 최소 TTL 5초로 인해 원래 1초 TTL을 5초로 과도 캐싱하여 Aurora 리더 엔드포인트 트래픽 분산이 왜곡되는 문제가 보고되었습니다. 이러한 상황에서는 특정 도메인에 한해 TTL을 낮추는 설정을 도입해야 합니다.
실제 사례에서는 NodeLocal DNSCache CoreDNS 설정에 amazonaws.com 영역에 대해 cache 1 및 success/denial 1 TTL 세부 설정을 적용함으로써, Aurora 엔드포인트의 원래 TTL 1초를 준수하도록 구성하여 문제를 해결했습니다. 따라서 외부 서비스의 TTL 정책도 고려하여 CoreDNS의 TTL과 캐시 전략을 튜닝해야 합니다.
3. CoreDNS 모니터링 아키텍처 모범 사례
CoreDNS 모니터링 아키텍처는 **메트릭 수집(Prometheus 등)**과 로그 수집(예: Fluent Bit 등), 그리고 시각화 및 알림 체계를 모두 포함하는 통합적인 관찰성 파이프라인으로 구축하는 것이 이상적입니다. Amazon EKS 환경에서는 Managed 서비스와 오픈소스 도구를 조합하여 안정적이고 확장 가능한 모니터링 시스템을 구현할 수 있습니다.
메트릭 수집 및 저장
Amazon EKS에서는 CoreDNS의 Prometheus 메트릭을 수집하기 위해 두 가지 접근이 일반적입니다:
-
Amazon Managed Service for Prometheus (AMP): AWS에서 제공하는 완전 관리형 Prometheus 호환 서비스로, 클러스터 내 메트릭을 원격 수집(remote write)하여 확장성 높은 시계열 DB에 보관합니다. EKS 클러스터에는 ADOT(AWS Distro for OpenTelemetry) Collector 또는 Prometheus 서버를 설치하여 CoreDNS 메트릭을 스크랩한 후 AMP로 전송합니다. AMP에 저장된 메트릭은 PromQL로 쿼리 가능하며, 장기 보관 및 대규모 클러스터 지원에 적합합니다.
-
CloudWatch Container Insights (및 CloudWatch 에이전트): AWS의 CloudWatch를 활용하여 Prometheus 메트릭을 CloudWatch로 수집하는 방법입니다. CloudWatch 에이전트를 DaemonSet으로 배포하고,
kube-system/kube-dns서비스의 9153 포트로부터 CoreDNS 메트릭을 스크랩하도록 설정합니다.
Amazon EKS의 kube-dns 서비스는 metrics 포트를 제공하므로, Prometheus Operator를 사용한다면 ServiceMonitor를 생성하여 kube-system 네임스페이스의 k8s-app=kube-dns 레이블을 가진 서비스를 대상으로 9153포트를 스크랩할 수 있습니다.
로그 수집
CoreDNS의 쿼리 로그와 에러 로그는 성능 문제를 진단하거나 보안 모니터링(예: 특정 도메인에 대한 폭주 조회) 측면에서 유용한 정보원입니다. CoreDNS의 기본 Corefile에는 log 플러그인이 없지만, 필요에 따라 log 또는 errors 플러그인을 활성화할 수 있습니다. 실무에서는 CoreDNS Pod의 표준 출력(stdout/stderr)에 기록되는 로그를 수집하기 위해 Fluent Bit이나 Fluentd를 DaemonSet으로 운용하여 CloudWatch Logs로 내보내는 패턴이 흔합니다.
과도한 로그 수집으로 인한 부하를 피하기 위해 필요 수준으로만 로그를 남기는 것이 중요합니다. EKS 모범 사례에서는 Fluent Bit 등 에이전트가 Kubernetes API를 반복 조회하지 않도록 메타데이터 캐싱을 설정하고 (Kube_Meta_Cache_TTL=60 등) 불필요한 필드 수집을 줄이는 것을 권장합니다.
시각화 및 대시보드
수집된 CoreDNS 메트릭은 Grafana를 통해 모니터링 대시보드로 시각화하는 것이 일반적입니다. Amazon Managed Grafana(AMG)는 AMP나 CloudWatch와 네이티브 통합되어 데이터 소스로 활용할 수 있고, IAM 연동 SSO로 접근을 제어할 수 있습니다. Grafana에서 CoreDNS 대시보드를 구축할 때, 요청률(QPS), 응답 지연(histogram), 오류율(rcode 분포), 캐시 히트율 등의 패널을 구성합니다.
알람/Alerting
Prometheus Alertmanager 또는 CloudWatch Alarms를 활용하여 DNS 이상 징후에 대한 경보를 설정해야 합니다. 대표적인 CoreDNS 관련 Alertmanager 규칙 예시는 다음과 같습니다:
- CoreDNSDown: 일정 시간 동안 (
for: 15m등) CoreDNS 메트릭(up{job="kube-dns"}등)가 보고되지 않을 때 경보. - HighDNSLatency:
coredns_dns_request_duration_seconds의 p99 지연 시간이 예를 들어 100ms를 초과하고 평소보다 높을 때 경보. - DNSErrorsSpike:
coredns_dns_responses_total에서rcode라벨이SERVFAIL또는NXDOMAIN인 값의 비율이 일정 임계치 이상일 때 경보. - ENIThrottling: AWS 환경 특화 메트릭으로, EC2 네트워크 인터페이스(ENI)의 DNS 패킷 제한 초과를 모니터링하는 경보입니다.
- HighCoreDNSCPU/Memory: CoreDNS Pod의 CPU/메모리 사용률 모니터링 경보.
4. Amazon EKS 모범 사례 및 고객 사례 (DNS 병목 대응 등)
AWS 클라우드 환경에 특화된 EKS DNS 운용 모범사례를 문서와 블로그를 통해 제공하고 있습니다. 주요 권장사항과 고객 사례에서 자주 등장하는 시나리오는 다음과 같습니다:
CoreDNS Horizontal Scaling (복제수 조정)
EKS 클러스터 생성 시 기본 CoreDNS Deployment 복제수는 2개로 고정되지만, 노드 수와 워크로드 증가에 따라 수평 확장이 필요할 수 있습니다. AWS 모범 사례는 Cluster Proportional Autoscaler를 사용해 CoreDNS 복제수를 노드 수 또는 CPU 코어 수에 비례하여 자동 증가시키는 것입니다.
NodeLocal DNSCache 도입
대규모 클러스터나 DNS 트래픽이 매우 빈번한 워크로드에서는, CoreDNS를 중앙에서 처리하는 방식이 네트워크 지연 및 ENI 한계로 병목이 될 수 있습니다. Kubernetes의 공식 애드온인 NodeLocal DNSCache는 모든 노드에서 DNS 캐시 에이전트(CoreDNS 기반)를 데몬셋으로 실행하여, 각 Node에서 로컬 DNS를 제공하는 방식입니다.
DNS 패킷 한계 및 트래픽 분산
AWS 환경의 흔한 병목으로 **VPC DNS 패킷 한도(1024 PPS/ENI)**가 있습니다. 실무 사례로, 대량의 외부 DNS 조회를 하는 애플리케이션이 있을 경우 CoreDNS Pod 2개가 모두 동일한 노드에 떠 있다면, 그 노드의 ENI 하나로 모든 외부 DNS 질의가 나가 한도를 넘을 위험이 있습니다.
Graceful Termination 설정 (Lameduck & Ready 플러그인)
CoreDNS Pod를 재시작하거나 축소할 때 발생하는 일시적인 DNS 실패를 막기 위한 설정입니다. AWS 모범 사례는 CoreDNS에 lameduck 30s 설정을 적용하고, Readiness Probe를 /ready 엔드포인트로 구성하는 것입니다.
더 높은 QPS가 필요할 때
-
max_concurrent상향:2000이상으로 조정할 수 있지만, 메모리 사용량(2 KB × 동시 질의 수)과 upstream DNS 지연 시간을 함께 고려해야 합니다. -
CoreDNS 수평 확장: Replica 수를 늘리거나 Cluster Proportional Autoscaler, HPA, 혹은 NodeLocal DNSCache로 질의를 노드 단으로 분산합니다.
-
ENI 한계 모니터링:
aws_ec2_eni_allowance_exceeded(CloudWatch) 또는linklocal_allowance_exceeded지표에 알람을 걸어 ENI PPS 초과를 조기에 탐지합니다.
핵심 요약
dnsperf -s <COREDNS_IP> -d queries.txt -c 10 -T 10 으로 CoreDNS QPS 및 레이턴시를 측정할 수 있습니다.- 모니터링 메트릭:
requests_total,request_duration_seconds,cache_hits/misses,responses_total{rcode}, CPU/메모리 - TTL 권장치: 서비스 레코드 30s, cache (success 30, denial 5-10), prefetch 5 60s
- 모니터링: kube-prometheus-stack 기본 대시보드 + Alertmanager 룰, 필요 시 NodeLocal DNSCache로 스케일-아웃
부록: 구성 예시
Corefile 권장 구성
.:53 {
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30 # Service/POD 레코드 TTL
}
cache 30 { # 최대 30초 보존
success 10000 30 # capacity 10k, maxTTL 30s
denial 2000 10 # negative cache 2k, maxTTL 10s
prefetch 5 60s # 동일 질의 5회↑면 60s 전에 갱신
}
forward . /etc/resolv.conf {
max_concurrent 2000
prefer_udp
}
prometheus :9153
health {
lameduck 30s
}
ready
reload
log
}
Alertmanager 룰 예시
- alert: CoreDNSHighErrorRate
expr: >
(sum(rate(coredns_dns_responses_total{rcode!~"NOERROR"}[5m])) /
sum(rate(coredns_dns_requests_total[5m]))) > 0.01
for: 10m
labels:
severity: critical
annotations:
description: "CoreDNS error rate > 1% for 10 min"
- alert: CoreDNSP99Latency
expr: >
histogram_quantile(0.99,
sum(rate(coredns_dns_request_duration_seconds_bucket[5m])) by (le)) > 0.05
for: 5m
labels:
severity: warning
대규모 클러스터 (>100 노드 또는 QPS > 5k)
- NodeLocal DNSCache (DaemonSet 형태)로 노드 로컬에서 캐시하여 RTT 단축
- nodelocaldns 메트릭도 Prometheus에 수집해 CoreDNS와 비교
- CloudWatch Container Insights (EKS 전용)
- Prometheus 수집이 어려운 환경이라면
cwagent + adot-internal-metrics옵션으로 CoreDNS 컨테이너 메트릭을 CloudWatch로 전송 가능 (별도 요금 발생)
- Prometheus 수집이 어려운 환경이라면