kubernetes DNS

snooby·2022년 11월 16일
0

🐳 Docker & K8S

목록 보기
49/51
post-thumbnail

쿠버네티스 클러스터 내 pod에서 어떤 도메인을 찾을 때 네인스페이스에서 실행되고있는 CoreDNS가 네임서버로 사용됩니다.

CoreDNS의 여러가지 기능은 Corefile 설정 파일에 원하는 것들만 플러그인처럼 추가할 수 있으며 이는 Corefile 파일에 ConfigMap 오브젝트에 저장되어 있습니다.

$ kubectl describe cm -n kube-system coredns

Name:         coredns
Namespace:    kube-system
Labels:       <none>
Annotations:  <none>

Data
====
Corefile:
----
.:53 {
    errors
    health {
       lameduck 5s
    }
    ready
    kubernetes cluster.local in-addr.arpa ip6.arpa {
       pods insecure
       fallthrough in-addr.arpa ip6.arpa
       ttl 30
    }
    prometheus :9153
    forward . /etc/resolv.conf
    cache 30
    loop
    reload
    loadbalance
}

Corefile 구성

errors : 에러가 발생하면 stdout으로 보낸다.
health : http://localhost:8080/health를 통해 CoreDNS 상태를 확인할 수 있다.
ready : 준비 요청이 되어 있는지 확인하기 위해 포트 http://localhost:8181/ready로 HTTP 요청을 보니면 200 OK가 반환된다.
kubenetes : 쿠버네티스의 Service 도메인과 POD IP 기반으로 DNS 쿼리를 응답한다. ttl 설정으로 타임아웃을 제어할 수 있다.
pods 옵션은 POD IP를 기반으로 DNS 질의를 제어하기 위한 옵션이다. 기본값은 disabled이며, insecure값은 kube-dns 하위 호환성을 위해서 사용한다.
pods disabled옵션을 설정하면 POD IP 기반 DNS 질의가 불가능하다. 예를 들어 testbed 네임스페이스에 있는 POD IP가 10.244.2.16라고 한다면, 10-244-2-16.testbed.pod.cluster.local질의에 A 레코드를 반환하지 않게 된다.
pods insecure 옵션은 같은 네임스페이스에 일치하는 POD IP가 있는 경우에만 A 레코드를 반환한다고 되어 있다. 하지만 간단하게 테스트 해보기 위해 다른 네임스페이스 상에 POD를 만들고 서로 호출했을 때 계속 통신이 되었다.
prometheus : 지정한 포트(:9153)로 프로메테우스 포맷의 메트릭 정보를 확인할 수 있다. 위에서 다룬 health의 :8080포트나 ready 옵션의 :8181포트를 포함해서 CoreDNS로 HTTP 요청을 보내려면 CoreDNS Service 오브젝트 설정에 :9153, :8080, :8181 포트를 바인딩을 설정해야 한다.

테스트용 POD를 만들어서 /etc/resolv.conf 파일을 확인해보자.

$ kubectl run -it --rm \
  busybox \
  --image=busybox \
  --restart=Never \
  -- cat /etc/resolv.conf
# /etc/resolv.conf

nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

/etc/resolv.conf 파일 내 구성 요소들

nameserver : DNS 쿼리를 보낼 곳. CoreDNS Service 오브젝트의 IP 주소
search : DNS에 질의할 부분 도메인 주소 경로들을 표시
ndots : FQDN으로 취급될 도메인에 포함될 .(점)의 최소 개수

만약 어떤 POD에서 test.dev 같은 도메인을 찾으려고 한다면, 이 도메인은 FQDN이기 때문에 클라이언트는 test.dev.형태로 DNS 서버에 질의를 하게 된다.

하지만 /etc/resolv.conf 에서 중 search 옵션을 추가로 고려해야합니다. 이 옵션에는 부분적인 도메인 목록들을 지정한다. 즉, 클라이언트가 DNS 서버로부터 결과가 없다는 응답을 받으면, 이 부분 도메인 목록을 차례대로 붙여가며 추가로 DNS 서버를 호출한다.

예를 들어 test.jonnung.dev라는 실제로 존재하지 않는 도메인을 DNS 서버에 조회하면 총 4번의 요청이 전달될 수 있다.
아래 결과는 실제 CoreDNS 서버에 남은 로그이다.

예를 들어 test.jonnun.dev 같은 도메인을 찾는다고 한다면, 도메인 끝에 점(.)을 붙이지 않았더라도 요청하는 클라이언트가 자동으로 점(.)을 붙인 뒤 test.jonnun.dev.형태로 요청을 할 것 이다.
하지만 실제로 저 도메인이 존재하지 않기 때문에 search 목록에 해당하는 default.svc.cluster.local, svc.cluster.local, cluster.local을 모두 붙여가며 추가로 DNS를 질의하게 된다.

따라서 만약 조금이라도 CoreDNS 서버에 부하를 줄이고 싶다면, 외부 도메인을 호출할 때 마지막 점(.)을 추가하면 딱 1번만 DNS 서버에 질의할 수 있게 된다.

profile
데이터를 가치있게 다루고 싶은 개발자 🐥

0개의 댓글