/etc/hosts 파일에 도메인명이 존재하지 않을 경우 /etc/resolv.conf에서 도메인명을 검색할 도메인 서버의 주소를 찾는다.
DNS in K8S
CoreDns
v.1.12 이후로 k8s에서 사용을 권장하고 있는 도메인 서버 서비스
클러스터를 지속적으로 모니터링하며, 새로운 service, pod가 추가되는 경우 → 도메인 서버에 업데이트
DNS setting in Pod
새로운 pod가 생성될 때, kubelet이 pod의 /etc/resolv.conf 파일에 clusterDNS서버의 IP주소를 추가 → pod에서 클러스터 내부의 DNS를 사용할 수 있도록 설정
coredns configmap - kubernetes: CoreDNS가 쿠버네티스의 서비스 및 파드의 IP를 기반으로 DNS 쿼리에 대해 응답 - forward: 쿠버네티스 클러스터 도메인에 없는 쿼리들은 모두 사전에 정의된 리졸버(/etc/resolv.conf)로 전달
Process
다시 위 문서의 해결 과정을 살펴보면..
application에는 문제가 없다고 판단 → tcpdump 확인 - tcpdump = commandline에서 실행하는 일반적인 패킷 가로채기 소프트웨어 - wireshark로 분석
A(IPv4), AAAA(IPv6)레코드 두 번 lookup 하는 것을 발견 by libc(표준 C 라이브러리)
IP worker-4 > domain: 33504+ A? service.domain. (75)
IP worker-4 > domain: 37094+ AAAA? service.domain. (75)
A queries were coming quickly
theAAAAqueries did not seem to be answered in a timely manner and were repeated afterfive seconds
클러스터 내에서 IPv6를 사용하는 곳이 없는데도 libc가 AAAA레코드를 lookup 하는 게 이상했지만 암튼 IPv6를 사용하지 않도록 config를 수정
single-request (since glibc 2.10)
Sets RES_SNGLKUP in _res.options. By default,
glibc performs IPv4 and IPv6 lookups in parallel
since version 2.9. Some appliance DNS servers
cannot handle these queries properly and make the
requests time out. This option disables the
behavior and makes glibc perform the IPv6 and IPv4
requests sequentially (at the cost of some slowdown
of the resolving process).
single-request-reopen (since glibc 2.9)
Sets RES_SNGLKUPREOP in _res.options. The resolver
uses the same socket for the A and AAAA requests.
Some hardware mistakenly sends back only one reply.
When that happens the client system will sit and
wait for the second reply. Turning this option on
changes this behavior so that if two requests from
the same port are not handled correctly it will
close the socket and open a new one before sending
the second request.
timeout:n
Sets the amount of time the resolver will wait for
a response from a remote name server before
retrying the query via a different name server.
This may not be the total time taken by any
resolver API call and there is no guarantee that a
single resolver API call maps to a single timeout.
Measured in seconds, the default is RES_TIMEOUT
(currently 5, see resolv.h). The value for this
option is silently capped to 30.