cloudwithbass

[Kubernetes] DNS Deep Dive in Kubernetes with CoreDNS 본문

Kubernetes

[Kubernetes] DNS Deep Dive in Kubernetes with CoreDNS

여영클 2024. 11. 17. 17:39
  • 이 포스팅은 유튜브 CNCF 채널의 KubeCon North America 2024의 강연 중 DNS Deep Dive in Kubernetes with Core DNS의 내용을 한글로 정리한 글입니다. 영어 강의이므로 저의 의역이 포함되었습니다.
  • 타임라인을 작성했으니 더 자세한 내용은 아래 강의를 참고바랍니다.
  • 또한 강의 후반부에서 multi cluster에서의 도메인과 Istio에 대해 다루는데, 저는 해당 내용을 경험해본 적이 없어서 잘못된 정보를 작성할 것 같아서 이 내용은 생략했습니다. 강의를 참고 바랍니다.

https://youtu.be/lAUmdIGP_fE?si=axHUGfr0g0_gUoFr

목차


     

    02:32 | Life of a DNS Request in Kubernetes Cluster

     

    • DNS resolver는 pod의 /etc/resolv.conf에 정의된 DNS resolve를 사용하여 DNS를 IP로 해석합니다. 
    • 이 파일에는 네임 서버의 IP를 포함합니다. 만약 네임 서버로 클러스터 dns server를 사용하고 싶다면, 이 값을 cluster dns service의 cluster ip로 설정해야 합니다.
      • 위 사진을 예시로 들면(중앙 하단), 이 서비스의 이름은 kube-dns이며 그 ip는 10.32.0.10입니다.
    • 이제 DNS resolver는 /etc/resolv.conf의 내용에 따라 10.32.0.10으로 트래픽을 전송합니다.
    • 트래픽이 kube-dns 서비스로 전송된 후, kube-proxy가 cluster dns server pod로 라우팅합니다.
      • 이 예시의 경우 Cluster DNS Server는 CoreDNS입니다.
      • CoreDNS는 유연하고 확장 가능한 DNS 서버이며, 쿠버네티스 클러스터에서 디폴트로 사용됩니다.
      • CoreDNS는 kube API Server와 상호 작용하며, 비동기적으로 쿠버네티스 DNS를 해석합니다.
    • 클러스터에 정의되지 않은 DNS는 Amazon Route 53과 같은 Upstream DNS Server로 발송되어 해석됩니다.
      • 참고: 쿠버네티스 리소스 간의 통신은 DNS로 이루어집니다. 위 사진에서 .cluster.local과 같은 DNS가 이에 해당합니다.

     

    이제 /etc/reslov.conf 파일이 DNS 쿼리에 어떻게 영향을 미치는지 확인해 보겠습니다.


    04:23 | Pod DNS Configuration

    /etc/resolv.conf 파일을 확인하면 nameserver, search path, options 필드를 확인할 수 있습니다.

    (설명만 들으면 모호하겠지만 아래에 예시가 있습니다.)

     

    • nameserver: DNS IP 주소를 설정합니다. 
    • search: DNS에 추가할 도메인 이름의 목록입니다. 
    • options: 리졸버 내부의 세팅을 변경할 수 있습니다.
      • 흔히 사용되는 옵션은 다음과 같습니다.
      • ndots: 처음 쿼리 이전에 도메인 이름에 표시돼야 할 점의 개수를 나타냅니다. 
      • timeout: resolver가 원격 네임 서버의 응답을 기다릴 시간을 설정
      • attempts: resolver가 네임 서버에 쿼리할 횟수를 설정

    이해가 안 되는 것이 당연합니다. 예시를 들어 설명하겠습니다.


    05:38 | DNS Resolution Example 1

    현재 /etc/resolv.conf이 내용에 ndots가 2로 설정되어 있습니다.

    도메인 'www.airbnb.com'에는 두 개의 dot이 있으므로 쿼리를 곧바로 네임 서버에 전송합니다.

    DNS Server는 성공적으로 이에 응답할 수 있습니다.

     

    다른 예시를 보겠습니다.


    06:02 | PQDN vs FQDN, DNS Resolution Example 2

     

    쿠버네티스는 서비스의 DNS를 다음과 같은 형식으로 저장합니다: service_name.namespace.svc.cluster_domain

     

    예를 들어 서비스 이름은 foo, 네임 스페이스 이름은 bar, 클러스터 도메인 이름은 cluster.local이라면 

    예시의 서비스 도메인은 foo.bar.svc.cluster.local.이 됩니다.

    이때 이 도메인을 FQDN(Fully Qualified Domain Names, 전체 도메인 이름)이라고 합니다.

     

    또한 foo.bar와 같이 도메인의 부분적인 이름을 PQDN( Partially Qualified Domain Names, 도메인 이름의 부분)이라고 합니다.

     

    여기서 도메인을 해석할 때 문제가 있습니다.

    이 예시에서 PQDN을 해석하려면 nodts가 1이여야 하고(foo.bar에는 점이 하나이므로), FQDN에는 ndots가 4여야 합니다.

    서로 다른 도메인을 어떻게 같은 서비스로 해석해야 할까요?

    resolve.conf 세팅을 적절하게 한다면, PQDN과 FQDN 모두 적절한 IP 주소로 해석될 수 있습니다.

     

    (참고: 도메인 이름의 있는 점의 개수가 ndots 이상이면 FQDN으로, 그 미만이면 PQDN으로 인식됩니다.)

     

    이제 예시를 들어 그 방법을 알아보겠습니다.


    07:17 | DNS Resolution Example 3

    • 위 예시에서 ndots는 1입니다.
    • foo.bar에는 dot가 한 개 이며, ndots가 1로 설정되어 있으므로 쿼리를 DNS 서버에 전송할 수 있습니다.
    • 하지만 이전에서 말씀드렸듯, 쿠버네티스에서 서비스의 DNS는 service_name.namespace.svc.cluster_domain 꼴로 저장됩니다. 
    • 따라서 foo.bar라는 도메인으로 해당 서비스를 찾을 수 없고, cluster dns 서버는 이를 해석할 수 없습니다.
    • 그래서 서버는 NXDOMAIN(the domain name is not exist)을 반환할 것입니다.

    07:44 | DNS Resolution Example 4

    이전 예시와 다른 것은 search 필드입니다. 

    4:23의 슬라이드에서 search 필드를 'DNS에 추가할 도메인 이름의 목록'이라고 설명했던 것을 기억하시나요?

     

    현재 설정에서 search 필드는 'bar.svc.cluster.local', 'svc.cluster.local', 'cluster.local', 'ec2.internal', 'svc.us.east', 'us.east' 총 6개의 항목으로 구성되어 있습니다.

     

    resolver는 search 필드의 각 항목을 DNS에 차례로 추가하여 네임 서버에 질의합니다.

     

    위의 예시로 설명하겠습니다.

     

    • 첫 번째 search: bar.svc.cluster.local
      • 도메인 이름인 foo.bar에 이 항목을 붙이면 'foo.bar.bar.svc.cluster.local'이 됩니다.
      • 이런 도메인은 존재하지 않으므로 다음 서치 도메인을 붙여봅니다.

     

    • 두 번째 search: svc.cluster.local
      • 도메인 이름인 foo.bar에 붙이면 'foo.bar.svc.cluster.local'이 됩니다.
      • 이 도메인은 FQDN 형식인 ' service_name.namespace.svc.cluster_domain' 꼴과 일치합니다.
      • 따라서 DNS 리졸버는 이 DNS를 해석할 수 있고, 그 결과를 클라이언트에 반환합니다.

    참고

    그러면 만약 같은 /etc/resolv.conf 설정에서, foo.bar가 아닌 foo.bar.svc.cluster.local'을 질의하면 어떻게 될까요?

    위에서 말씀드렸듯, 도메인 이름의 있는 점의 개수가 ndots 이상이면 FQDN으로, 그 미만이면 PQDN으로 인식됩니다.

    현재 설정에서 ndots는 1이고 이도메인에는 dot가 5개이므로 그 자체로 FQDN으로 인식되어 search 필드의 항목을들 붙이지 않습니다.


     

    08:41 | Default ndots

    흥미로운 점은, 'ndots:5'가 쿠버네티스 클러스터의 기본 세팅입니다.

    이로 인해 도메인에 점이 5개가 없는 도메인 네임에 순차적으로 search domain을 추가하여 질의합니다.

     

    클라이언트는 여전히 정확한 응답을 반환받을 수 있지만, 이로 인해 생기는 DNS latency는 좋지 않습니다.

     


    09:20 | How to Customize Pod DNS Configuration

     

    Kubelet Configuration

    Kubelet은 pod가 생성될 때 Pod DNS configuration을 구성할 로직이 있습니다.

    • Kubelet Configuration
      • clusterDNS
        • Cluster DNS 서버의 IP 주소 리스트를 설정합니다.
        • 만약 설정되면, Kubelet은 클러스터 내의 DNSpolicy를 clusterFirst로 설정한 모든 컨테이너에게 이 IP 주소를 첫 번째 DNS 서버로 사용하도록 합니다.
        • 예를 들어 Airbnb에선 coreDNS의 서비스 ip를 clusterDNS로 설정합니다.
      • clusterDomain
        • 클러스터에서 사용되는 DNS 기본 도메인을 지정합니다.
        • 만약 설정되면, Kubelet은 클러스터 내의 DNSpolicy를 clusterFirst로 설정한 모든 컨테이너의 search path에 이 도메인을 추가합니다.
      • resolvConf
        • Pod의 DNS 설정을 구성할 때 참조할 노드의 resolv.conf 파일 경로를 지정합니다.
    • Pod's DNS Policy
      • Default
        • host나 kubelet의 기본 컨테이너 dns reslove 구성을 사용 
      • ClusterFirst
        • Cluster DNS  서버를 사용
        • Defualt가 아니라, ClusterFirst가 디폴트 DNS Policy로 사용됩니다.
      • ClusterFirstWithHostNet
        • host network에서 실행되는 pod를 위한 정책 

    15:25 | CoreDNS: Plugin Based DNS Server/Forwarder

    CoreDNS를 쿠버네티스의 DNS Server로 사용하기위해 Kubernetes 플러그인(그림의 화살표 부분)을 활성화하고 구성해야 합니다.

    그 외에도 ready plug-in, health plug-in 등이 있습니다.

     

    또한 CoreDNS는 커스터마이즈된 플러그인을 지원합니다. 

     

    • 플러그인 순서는 아주 중요합니다.
    • 커스텀 플러그인을 개발할 경우 적절한 위치에 플러그인을 삽입해야 합니다.
    • 각 플러그인은 각기 다른 도메인이나 Zone을 처리하기 위해 구성됩니다.

     

     

     

    • CoreDNS는 configmap에 저장된 core 파일을 사용합니다.
    • 위 파일은 cluster.local 도메인을 kubernetes 플러그인을 사용하여 처리하며, 다른 도메인들은 forward 플러그인에 의해 처리됩니다.
    • forward 플러그인은 dns 요청을 upstream DNS 서버로 포워드합니다.

    CoreDNS에 대한 더 자세한 설명은 CoreDNS 공식 문서의 plugin 문서를 참고해주세요.


    17:35 | Example of Core File

    쿼리 로깅이나 프론트엔드 캐시 TTL 등 다른 유용한 구성을 적용할 수 있습니다.

     


    18:17 | Latency: kube-dns vs CoreDNS 

    2024년 3월, 에어비앤비는 CoreDNS로 완전 통합했습니다 (fully integrated with CoreDNS).

    CoreDNS의 지연 시간은 kube-dns보다 월등히 낮음을 확인할 수 있습니다.

    'Kubernetes' 카테고리의 다른 글

    [Kubernetes] ★Ingress란?, alb-ingress-controller 사용하기  (0) 2024.08.11
    [K8S] EKS Basics  (0) 2024.07.29
    [k8s] Kubernetes Basics  (0) 2024.07.28
    [k8s] 로컬에 kubectl 환경 구성하기  (0) 2024.07.27