-
CoreDNS의 주요 플러그인SW개발/Kubernetes 2025. 8. 24. 00:42
쿠버네티스 기본 DNS 애드온인 CoreDNS는 “플러그인”을 체인처럼 엮어 동작합니다. 각 플러그인은 요청을 직접 처리하거나(예: kubernetes, hosts) 체인을 보조합니다(예: cache, errors). 플러그인 체인의 처리 방식과 fallthrough 같은 동작은 공식 매뉴얼의 개념을 따르면 깔끔하게 이해됩니다.
정리할 플러그인은 아래와 같습니다
reload / errors / cache / kubernetes / forward / hosts / rewrite / loop
Cache
Client로부터 들어온 질의에 대한 응답을 TTL 한도 내에서 캐싱합니다(대체로 성능 향상).
기본 최대 TTL은 성공 응답 3600초, 부존재(denial) 1800초입니다.
기본문법
cache [TTL] [ZONES...]
- TTL: 캐시할 최대 TTL 상한(예: cache 300)
- ZONES: 캐싱할 존; 생략 시 서버 블록의 존 사용.
주요 세부설정
cache [TTL] [ZONES...] { success CAPACITY [TTL] [MINTTL] denial CAPACITY [TTL] [MINTTL] ... }
- Success: A/AAAA/CNAME 등의 정상 응답을 캐싱하는 영역. 기본 최대 TTL 상한은 3600초.
- Denial: NXDomain/NODATA/NOERROR+Empty Answer 등의 비정상 응답을 캐싱하는 영역. 기본 최대 TTL 상한은 1800초.
- CAPACITY: 캐시에 담을 최대 항목 수. 기본값 9984개(캐시는 256 샤드 × 39 아이템 구조).
- 기본 캐시용량(9984개)이 완전히 채워지면 약 30MB를 사용한다고 함.
- 공식은 Required Memory = (Pods + Services) / 1054
- CAPACITY: 캐시에 담을 최대 항목 수. 기본값 9984개(캐시는 256 샤드 × 39 아이템 구조).
참고) NodeLocalDNS Cache Flow
Reload
Corefile이 바뀌었는지 주기적으로 감지해 CoreDNS 프로세스를 무중단(graceful) 으로 새 설정으로 재시작하기 때문에, 굳이 설정 적용 후 CoreDNS를 재시작할 필요가 없습니다. 참고로 새 Corefile에 오류가 있으면 이전 설정을 계속 유지하고 로그에 에러만 남깁니다.
기본문법
reload [INTERVAL] [JITTER]
- Interval: 설정변경을 얼마나 자주 체크할지
- Jitter: 동시에 Corefile이 변경되는걸 방지하고자, Jitter 에 명시된 시간을 기준으로 Interval ± Jitter 로 시간을 계산해서 Corefile이 적용됨.
- 예를들어, Interval이 30초이고, Jitter가 15초라면, 변경된 Corefile이 CoreDNS Pod 들에 적용되는 시간은 15초~45초 사이에서 Pod별로 랜덤하게 적용이 됨.
Rewrite
DNS 요청/응답을 재작성합니다. 이름(name) 매칭은 exact|prefix|suffix|substring|regex를 지원하고, 응답 섹션(ANSWER)까지 일관되도록 answer auto|name|value로 보정할 수 있습니다.
기본문법
# 이름 재작성 rewrite [continue|stop] name [exact|prefix|suffix|substring|regex] FROM TO [answer auto|answer name REGEX REPL|answer value REGEX REPL] # TTL 재작성 rewrite [continue|stop] ttl [exact|prefix|suffix|substring|regex] NAME [SECONDS|MIN-MAX] # RCODE 재작성 rewrite [continue|stop] rcode [exact|...|regex] NAME FROM TO
예시
# schmoogle.com -> google.com 으로 리라이트 rewrite name suffix .schmoogle.com. .google.com. # 질문은 regex로 바꾸고, 응답도 이름을 원복해 일치 보장 rewrite stop { name regex (.*)-(us-west-1)\.example\.org {1}.service.{2}.consul answer name (.*)\.service\.(us-west-1)\.consul {1}-{2}.example.org }
Kubernetes
Kubernetes DNS 스펙을 구현해 svc.cluster.local 같은 서비스/엔드포인트/포드 레코드를 제공합니다. 일반적으로 CoreDNS는 in-cluster 서비스 계정으로 API 서버에 접속하며, stubDomains/upstreamNameservers 스타일의 동작은 forward 플러그인으로 구성합니다.
기본문법
kubernetes [ZONES...]
주요 세부설정
kubernetes [ZONES...] { pods disabled|insecure|verified fallthrough [ZONES...] ttl TTL ignore empty_service ... }
- pods: 기본 disabled. verified는 포드 존재 검증(메모리 사용↑), insecure는 요청 IP 그대로 반환(호환성용).
- ttl: 응답 TTL(기본 5초, 0~3600 허용). 0이면 캐시 방지.
- fallthrough [in-addr.arpa ip6.arpa]: 역방향 질의를 다음 플러그인으로 넘길 때 흔히 사용.
- ignore empty_service: 준비된 엔드포인트가 없는 서비스는 NXDOMAIN으로 반환(서치 패스의 다음 도메인 탐색 유도)
예시
cluster.local:53 { kubernetes cluster.local in-addr.arpa ip6.arpa { pods insecure fallthrough } }
Forward
외부 Resolver로 프록시하는 정책
기본문법
forward FROM TO
주요 세부설정
forward FROM TO... { force_tcp prefer_udp max_fails N max_concurrent MAX= ... }
- force_tcp: 외부 Resolver를 호출할 때, TCP로 호출
- prefer_udp: 외부 Resolver 호출시 UDP사용.
- max_fails: 연속 헬스체크 실패 N회 시 다운으로 간주(0이면 헬스체크 끔).
- max_concurrent: 동시 쿼리 제한(초과 시 REFUSED).
forward . /etc/resolv.conf { force_tcp prefer_udp max_fails 3 max_concurrent MAX=10 }
Hosts
특정 Zone에 대해 요청이 들어오면 DNS에서 캐시된 데이터 등을 검사하지 않고 직접 특정 IP를 리턴해줍니다.
아래에는 파일로 적혀있지만, /etc/hosts 등의 파일로도 적용가능하고, 127.0.0.1 등의 IP주소 명시도 가능합니다.
기본문법
hosts [FILE [ZONES...]] { [INLINE] # Corefile에 인라인 정의 가능 ttl SECONDS # 기본 3600 no_reverse # 자동 PTR 생성 끄기 reload DURATION # 파일 재로딩 주기(0이면 끔) fallthrough [ZONES...] }
Loop
시작 시 랜덤 HINFO 질의로 자기 자신으로 돌아오는 포워딩 루프를 감지하면 프로세스를 중단합니다. Kubernetes에서는 루프가 감지되면 Pod가 CrashLoopBackOff에 빠질 수 있습니다. 특히 노드의 systemd-resolved가 /etc/resolv.conf에 127.0.0.53을 넣는 구성에서 자주 발생하므로, kubelet의 resolvConf를 실제 업스트림이 담긴 파일로 지정하는 등의 우회가 권장됩니다.
기본문법
loop
'SW개발 > Kubernetes' 카테고리의 다른 글
ETCD 이해하기 (3) 2025.08.10 [k8s] watch/list 그리고 Thunder herd (2) 2025.07.20 [번역] Kubernetes의 resource memory limit 이해하기 (0) 2021.04.26