kube-dns 사용


이 페이지에서는 Google Kubernetes Engine(GKE)이 GKE 클러스터용 기본 DNS 프로바이더인 kube-dns를 사용하여 서비스 검색을 구현하는 방법을 설명합니다.

Autopilot 클러스터의 경우 기본 kube-dns 구성을 수정할 수 없습니다.

아키텍처

클러스터를 만들 때 GKE는 kube-system 네임스페이스에 kube-dns 포드를 자동으로 배포합니다. 포드는 kube-dns 포드를 그룹화하고 단일 IP 주소(ClusterIP)를 제공하는 해당 서비스를 통해 kube-dns 배포에 액세스합니다. 기본적으로 클러스터의 모든 포드는 이 서비스를 사용하여 DNS 쿼리를 확인합니다. 다음 다이어그램은 포드와 kube-dns 서비스 간의 관계를 보여줍니다.

kube-dns 포드와 kube-dns 서비스의 관계

kube-dns는 클러스터의 DNS 요구에 맞게 확장됩니다. 이 확장은 모든 GKE 클러스터에 기본적으로 배포되는 포드인 kube-dns-autoscaler에 의해 제어됩니다. kube-dns-autoscaler는 클러스터의 노드 및 코어 수를 기반으로 kube-dns 배포의 복제본 수를 조정합니다.

kube-dns는 헤드리스 서비스당 최대 1,000개의 엔드포인트를 지원합니다.

포드 DNS 구성 방법

각 노드에서 실행되는 kubelet은 kube-dns 서비스의 ClusterIP를 사용하도록 포드의 etc/resolv.conf를 구성합니다. 다음 구성 예시에서는 kube-dns 서비스의 IP 주소가 10.0.0.10임을 보여줍니다. 이 IP 주소는 다른 클러스터와 다릅니다.

nameserver 10.0.0.10
search default.svc.cluster.local svc.cluster.local cluster.local c.my-project-id.internal google.internal
options ndots:5

kube-dns는 클러스터 도메인(cluster.local)의 권한 있는 네임서버이며 외부 이름을 재귀적으로 확인합니다. 닉네임은 myservice와 같이 정규화되지 않은 이름이며 지역 검색 경로로 먼저 채워집니다.

스텁 도메인에 커스텀 리졸버 추가

kube-dns의 ConfigMap을 수정하여 클러스터 내에서 DNS 인프라에 속한 스텁 도메인을 설정할 수 있습니다.

스터브 도메인을 사용하면 이러한 도메인을 확인할 때 kube-dns가 DNS 요청을 특정 업스트림 DNS 서버로 전달하도록 도메인별 커스텀 리졸버를 구성할 수 있습니다.

kube-dns의 다음 ConfigMap 매니페스트에는 example.com 도메인의 커스텀 리졸버를 설정하는 stubDomains 구성이 포함되어 있습니다.

apiVersion: v1
kind: ConfigMap
metadata:
  labels:
    addonmanager.kubernetes.io/mode: EnsureExists
  name: kube-dns
  namespace: kube-system
data:
  stubDomains: |
    {
      "example.com": [
        "8.8.8.8",
        "8.8.4.4",
        "1.1.1.1",
        "1.0.0.1"
      ]
    }

다음 명령어를 실행하여 텍스트 편집기를 엽니다.

kubectl edit configmap kube-dns -n kube-system

파일의 콘텐츠를 매니페스트로 바꾼 다음 텍스트 편집기를 종료하여 매니페스트를 클러스터에 적용합니다.

업스트림 네임서버

upstreamNameservers를 포함하도록 kube-dns에 대한 ConfigMap을 수정하면 kube-dns에서 *.cluster.local을 제외한 모든 DNS 요청을 해당 서버로 전달합니다. 여기에는 업스트림 서버에서 확인할 수 없는 metadata.internal*.google.internal이 포함됩니다.

GKE용 워크로드 아이덴티티 제휴 또는 metadata.internal 변환을 사용하는 워크로드를 사용 설정한 경우, *.internal 이름 변환을 유지하기 위해 ConfigMap에 stubDomain을 추가합니다.

data:
  stubDomains: |
    {
      "internal": [
        "169.254.169.254"
      ]
    }
  upstreamNameservers: |
    ["8.8.8.8"]

알려진 문제

검색 도메인 한도

/etc/resolv.conf의 DNS 검색 도메인은 6개로 제한됩니다. 6개를 초과하는 검색 도메인을 정의하는 경우 kubectl describe pod 명령어를 실행할 때 다음 경고가 표시됩니다.

Search Line limits were exceeded, some search paths have been omitted, the applied search line is: default.svc.cluster.local svc.cluster.local cluster.local c.<project ID>.internal google.internal

이 경고는 Cloud Logging의 컨테이너 로그 섹션에 로깅됩니다.

이 문제를 해결하려면 구성에서 추가 검색 경로를 삭제하세요.

upstreamNameservers 한도 고려

Kubernetes는 upstreamNameservers 값을 최대 세 개로 제한합니다. upstreamNameservers를 네 개 이상 정의하면 Cloud Logging에서 kube-dns 배포 로그에 다음 오류가 표시됩니다.

Invalid configuration: upstreamNameserver cannot have more than three entries (value was &TypeMeta{Kind:,APIVersion:,}), ignoring update

이 경우 kube-dns는 upstreamNameservers가 구성되지 않은 것처럼 동작합니다. 이 문제를 해결하려면 구성에서 추가 upstreamNameservers를 삭제하세요.

kube-dns의 성능 제한사항

기본 kube-dns 프로바이더의 DNS 조회 지연 또는 DNS 변환 실패가 발생하는 경우 원인은 다음과 같습니다.

  • 워크로드 내에서 빈번한 DNS 조회 수행
  • 노드당 더 높은 포드 밀도 배포
  • 스팟 또는 선점형 VM에서 kube-dns 실행. 이럴 경우 예기치 않은 노드 삭제 및 후속 DNS 변환 문제가 발생할 수 있습니다.

DNS 조회 시간을 향상시키기 위해서는 다음 옵션 중 하나를 선택할 수 있습니다.

  • 스팟 또는 선점형 VM에서 kube-dns와 같은 중요한 시스템 구성요소를 실행하지 마세요. DNS에 스팟 또는 선점형 VM을 사용하면 오류가 발생하고 클러스터가 중단될 수 있습니다.
  • 권장사항에 따라 kube-dns와 같은 중요한 시스템 구성요소를 호스팅하기 위해 Standard(비 스팟 또는 선점형) VM으로 구성된 노드 풀을 하나 이상 만듭니다. 중요한 워크로드가 안정적인 노드 풀에서만 예약되어 스팟 또는 선점형 VM에서 실행되지 않도록 스팟 VM에 taint 및 톨러레이션(toleration)을 사용할 수 있습니다.
  • NodeLocal DNSCache 사용 설정
  • kube-dns 수직 확장
  • dns.lookup은 동기식이므로 애플리케이션이 dns.lookup 기반 함수가 아닌 dns.resolve* 기반 함수를 사용하는지 확인하세요. dns.resolve* 함수는 항상 네트워크에서 비동기식 DNS 쿼리를 수행합니다.

서비스 DNS 레코드

kube-dns는 엔드포인트{track-name="k8sLink" track-type="concept"}가 있는 서비스의 DNS 레코드만 만듭니다.

DNS 업스트림 서버의 대규모 TTL

kube-dns가 업스트림 DNS 리졸버로부터 대규모 TTL 또는 '무한' TTL로 DNS 응답을 받는 경우 캐시에 있는 DNS 항목의 TTL 값을 유지합니다. 항목은 만료되지 않으며 항목과 TTL 이름으로 확인된 실제 IP 주소 간에 불일치가 발생할 수 있습니다.

GKE는 TTL이 30초를 초과하는 DNS 응답에 대해 최대 TTL 값을 30초로 설정하여 다음 컨트롤 플레인 버전에서 이 문제를 해결합니다.

  • 1.21.14-gke.9100
  • 1.22.15-gke.2100
  • 1.23.13-gke.500
  • 1.24.7-gke.500
  • 1.25.2-gke.500 이상

이 동작은 NodeLocal DNSCache와 비슷합니다.

다음 단계

  • GKE의 클러스터 DNS 개요 읽어보기
  • 서비스 및 포드의 DNS를 참조하여 Kubernetes 클러스터에서 DNS가 사용되는 방식에 대한 일반적인 개요 알아보기