이 문서는 GKE용 Cloud DNS가 클러스터에 적합한 DNS 솔루션인지 결정하는 데 도움이 됩니다. Cloud DNS를 사용하여 kube-dns와 같은 클러스터 호스팅 DNS 제공업체 대신 포드 및 서비스 DNS 변환을 처리할 수 있습니다.
Autopilot 클러스터의 경우 Cloud DNS가 이미 기본 DNS 제공업체입니다. Standard 클러스터의 경우 kube-dns에서 Cloud DNS로 전환할 수 있습니다.
이 문서는 개발자, 관리자, 설계자를 비롯한 GKE 사용자를 대상으로 합니다. Google Cloud의 일반적인 역할과 예시 태스크에 대해 자세히 알아보려면 일반 GKE Enterprise 사용자 역할 및 태스크를 참고하세요.
이 문서에서는 사용자가 다음 개념에 익숙하다고 가정합니다.
GKE용 Cloud DNS 작동 방식
Cloud DNS를 GKE의 DNS 제공업체로 사용하면 Cloud DNS에서 클러스터 호스팅 DNS 제공업체 없이 포드 및 서비스 DNS 변환을 제공합니다. 포드와 서비스의 DNS 레코드는 클러스터 IP 주소, 헤드리스, 외부 이름 서비스에 대해 Cloud DNS에서 자동으로 프로비저닝됩니다.
Cloud DNS는 전체 Kubernetes DNS 사양을 지원하고 GKE 클러스터 내 서비스에 A, AAAA, SRV, PTR 레코드 확인을 제공합니다. PTR 레코드는 응답 정책 규칙을 사용하여 구현됩니다. Cloud DNS를 GKE의 DNS 제공업체로 사용하면 다음과 같이 클러스터 호스팅되는 DNS보다 다양한 이점이 있습니다.
- 오버헤드 감소: 클러스터 호스팅 DNS 서버를 관리할 필요가 없습니다. Cloud DNS는 완전 관리형 서비스이므로 DNS 인스턴스를 수동으로 확장, 모니터링 또는 관리할 필요가 없습니다.
- 높은 확장성과 성능: 각 GKE 노드에 대해 로컬로 쿼리를 해결하여 지연 시간이 짧고 확장성이 높은 DNS 변환을 제공합니다. 특히 대규모 클러스터에서 최적의 성능을 위해 노드에 추가 캐싱 레이어를 제공하는 NodeLocal DNSCache를 사용 설정하는 것이 좋습니다.
- Google Cloud Observability와 통합: DNS 모니터링 및 로깅을 지원합니다. 자세한 내용은 비공개 관리 영역의 로깅 사용 설정 및 사용 중지를 참고하세요.
아키텍처
Cloud DNS가 GKE의 DNS 제공업체일 때 컨트롤러는 GKE 관리형 포드로 실행됩니다. 이 포드는 클러스터의 컨트롤 플레인 노드에서 실행되며 클러스터 DNS 레코드를 관리형 비공개 DNS 영역에 동기화합니다.
다음 다이어그램에서는 Cloud DNS 컨트롤 플레인과 데이터 영역이 클러스터 이름을 변환하는 방법을 보여줍니다.
다이어그램에서 서비스 백엔드는 실행 중인 백엔드 포드를 선택합니다. clouddns-controller는 서비스 백엔드의 DNS 레코드를 만듭니다.
포드 프런트엔드는 백엔드라는 서비스의 IP 주소를 변환하기 위한 DNS 요청을 169.254.169.254의 Compute Engine 로컬 메타데이터 서버로 전송합니다. 메타데이터 서버는 노드에서 로컬로 실행되어 캐시 부적중을 Cloud DNS로 전송합니다.
Cloud DNS는 Kubernetes 서비스 유형에 따라 서비스 이름을 서로 다른 IP 주소로 변환합니다. ClusterIP 서비스의 경우 Cloud DNS는 서비스 이름을 가상 IP 주소로 변환하고, 헤드리스 서비스의 경우 서비스 이름을 엔드포인트 IP 주소 목록으로 변환합니다.
포드 프런트엔드가 IP 주소를 변환하면 포드는 서비스 백엔드 및 서비스 뒤에 있는 포드로 트래픽을 전송할 수 있습니다.
DNS 범위
Cloud DNS에는 다음과 같은 DNS 범위가 있습니다. 클러스터는 여러 모드에서 동시에 작동할 수 없습니다.
- GKE 클러스터 범위: DNS 레코드는 클러스터 내에서만 확인할 수 있으며
kube-dns와 동일하게 동작합니다. GKE 클러스터에서 실행되는 노드만 서비스 이름을 확인할 수 있습니다. 기본적으로 클러스터에는*.cluster.local로 끝나는 DNS 이름이 있습니다. 이러한 DNS 이름은 클러스터 내에서만 표시되며 같은 프로젝트에 있는 다른 GKE 클러스터의*.cluster.localDNS 이름과 겹치거나 충돌하지 않습니다. 이 모드는 기본 모드입니다.- Cloud DNS 추가 VPC 범위: Cloud DNS 추가 VPC 범위는 Compute Engine VM 또는 Cloud VPN이나 Cloud Interconnect를 사용하여 연결된 온프레미스 클라이언트와 같은 VPC의 다른 리소스에서 헤드리스 서비스를 해결할 수 있도록 GKE 클러스터 범위를 확장하는 선택적 기능입니다. 이 모드는 클러스터 범위와 함께 사용 설정되는 추가 모드입니다. DNS 가동 시간이나 클러스터 범위 기능에 영향을 주지 않고 클러스터에서 이 모드를 사용 설정하거나 사용 중지할 수 있습니다.
- VPC 범위: DNS 레코드를 전체 VPC 내에서 변환할 수 있습니다. Compute Engine VM 및 온프레미스 클라이언트는 Cloud Interconnect 또는 Cloud VPN을 사용하여 연결하고 GKE 서비스 이름을 직접 변환할 수 있습니다. 각 클러스터에 고유한 커스텀 도메인을 설정해야 합니다. 즉, 모든 서비스 및 포드 DNS 레코드가 VPC 내에서 고유해야 합니다. 이 모드는 GKE 리소스와 GKE 이외 리소스 간의 통신 문제를 줄입니다.
다음 표에는 DNS 범위 간 차이점이 나와 있습니다.
| 기능 | GKE 클러스터 범위 | Cloud DNS 추가 VPC 범위 | VPC 범위 |
|---|---|---|---|
| DNS 가시성 범위 | GKE 클러스터 내에서만 | 클러스터 전용, VPC 네트워크에서 변환 가능한 헤드리스 서비스 | 전체 VPC 네트워크 |
| 헤드리스 서비스 확인 | 클러스터 내에서 변환 가능 | `cluster.local` 도메인을 사용하여 클러스터 내에서, 클러스터 서픽스를 사용하여 VPC 전반에서 확인 가능 | 클러스터 서픽스를 사용하여 클러스터 내에서 그리고 VPC 전반에서 확인 가능 |
| 고유 도메인 요구사항 | 아니요. 기본 `*.cluster.local` 도메인을 사용합니다. | 예. 고유한 커스텀 도메인을 설정해야 합니다. | 예. 고유한 커스텀 도메인을 설정해야 합니다. |
| 설정 구성 | 기본값, 추가 단계 없음 | 클러스터 생성 시 선택사항 언제든지 사용 설정 또는 사용 중지 가능 |
클러스터 생성 중에 구성해야 함 |
Cloud DNS 리소스
Cloud DNS를 GKE 클러스터의 DNS 제공업체로 사용하면 Cloud DNS 컨트롤러에서 프로젝트의 Cloud DNS에 리소스를 만듭니다. GKE에서 만드는 리소스는 Cloud DNS 범위에 따라 달라집니다.
| 범위 | 정방향 조회 영역 | 역방향 조회 영역 |
|---|---|---|
| 클러스터 범위 | (리전의) Compute Engine 영역별 클러스터당 비공개 영역 1개 | (리전의) Compute Engine 영역별 클러스터당 응답 정책 영역 1개 |
| Cloud DNS 추가 VPC 범위 | 클러스터 (전역 영역)당 Compute Engine 영역(리전)별 클러스터당 비공개 영역 1개, 클러스터 (전역 영역)당 VPC 범위 비공개 영역 1개 |
클러스터 (전역 영역)당 Compute Engine 영역(리전)별 클러스터당 응답 정책 영역 1개, 클러스터 (전역 영역)당 VPC 범위 응답 정책 영역 1개 |
| VPC 범위 | 클러스터(전역 영역)당 비공개 영역 1개 | 클러스터(전역 영역)당 응답 정책 영역 1개 |
이러한 Cloud DNS 리소스에 사용되는 이름 지정 규칙은 다음과 같습니다.
| 범위 | 정방향 조회 영역 | 역방향 조회 영역 |
|---|---|---|
| 클러스터 범위 | gke-CLUSTER_NAME-CLUSTER_HASH-dns |
gke-CLUSTER_NAME-CLUSTER_HASH-rp |
| Cloud DNS 추가 VPC 범위 | 클러스터 범위 영역의 경우 gke-CLUSTER_NAME-CLUSTER_HASH-dns
VPC 범위 영역의 경우 gke-CLUSTER_NAME-CLUSTER_HASH-dns-vpc
|
gke-CLUSTER_NAME-CLUSTER_HASH-rp
클러스터 범위 영역의 경우
gke-NETWORK_NAME_HASH-rp VPC 범위 영역의 경우 |
| VPC 범위 | gke-CLUSTER_NAME-CLUSTER_HASH-dns |
gke-NETWORK_NAME_HASH-rp |
이전 표에 나온 영역 외에도 Cloud DNS 컨트롤러가 구성에 따라 프로젝트에 다음 영역을 만듭니다.
| 커스텀 DNS 구성 | 영역 유형 | 영역 이름 지정 규칙 |
|---|---|---|
| 스텁 도메인 | 전달(전역 영역) | gke-CLUSTER_NAME-CLUSTER_HASH-DOMAIN_NAME_HASH |
| 맞춤 업스트림 네임서버 | 전달(전역 영역) | gke-CLUSTER_NAME-CLUSTER_HASH-upstream |
커스텀 스텁 도메인 또는 커스텀 업스트림 네임서버를 만드는 방법에 대한 자세한 내용은 스텁 도메인에 커스텀 리졸버 추가를 참고하세요.
관리형 영역 및 전달 영역
클러스터 범위를 사용하여 내부 DNS 트래픽을 처리하는 클러스터의 경우 Cloud DNS 컨트롤러는 클러스터가 속한 리전의 각 Compute Engine 영역에 관리형 DNS 영역을 만듭니다.
예를 들어 클러스터를 us-central1-c 영역에 배포하면 Cloud DNS 컨트롤러가 us-central1-a, us-central1-b, us-central1-c, us-central1-f에 관리형 영역을 만듭니다.
Cloud DNS 컨트롤러는 DNS stubDomain마다 전달 영역을 하나씩 만듭니다.
Cloud DNS는 . DNS 이름을 사용하는 관리형 영역 한 개를 사용하여 각 DNS 업스트림을 처리합니다.
할당량
Cloud DNS는 할당량을 사용하여 GKE가 DNS 항목에 만들 수 있는 리소스 수를 제한합니다. Cloud DNS의 할당량 및 한도는 프로젝트의 kube-dns 제한사항과 다를 수 있습니다.
GKE용 Cloud DNS를 사용할 때는 프로젝트의 각 관리형 영역에 다음 기본 할당량이 적용됩니다.
| Kubernetes DNS 리소스 | 해당 Cloud DNS 리소스 | 할당량 |
|---|---|---|
| DNS 레코드 수 | 관리형 영역당 최대 바이트 | 2,000,000개 (관리형 영역의 최대 50MB) |
| 헤드리스 서비스당 포드 수 (IPv4 또는 IPv6) | 리소스 레코드 세트당 레코드 수 | GKE 1.24~1.25: 1,000 (IPv4 또는 IPv6) GKE 1.26 이상: IPv4의 경우 3,500, IPv6의 경우 2,000 |
| 프로젝트당 GKE 클러스터 수 | 프로젝트당 응답 정책 수 | 100 |
| 클러스터당 PTR 레코드 수 | 응답 정책당 규칙 수 | 100,000 |
리소스 한도
클러스터별로 만드는 Kubernetes 리소스는 다음 표에 설명된 대로 Cloud DNS 리소스 한도에 반영됩니다.
| 한도 | 한도에 반영 |
|---|---|
| 관리형 영역당 리소스 레코드 세트 | 서비스 수 및 클러스터당 유효한 호스트 이름이 있는 헤드리스 서비스 엔드포인트 수 |
| 리소스 레코드 세트당 레코드 | 헤드리스 서비스당 엔드포인트 수. 다른 서비스 유형에는 영향을 미치지 않습니다. |
| 응답 정책당 규칙 수 | 클러스터 범위의 경우 서비스 수와 클러스터당 유효한 호스트 이름이 있는 헤드리스 서비스 엔드포인트 수의 합 VPC 범위의 경우 서비스 수와 VPC에 있는 모든 클러스터의 호스트 이름이 있는 헤드리스 엔드포인트 수의 합 |
Kubernetes에서 DNS 레코드가 생성되는 방법에 대한 자세한 내용은 Kubernetes DNS 기반 서비스 검색을 참고하세요.
서비스 프로젝트당 두 개 이상의 클러스터
GKE 버전 1.22.3-gke.700 및 1.21.6-gke.1500부터는 동일한 호스트 프로젝트에서 VPC를 참조하는 여러 서비스 프로젝트에 클러스터를 만들 수 있습니다.
커스텀 스텁 도메인 및 업스트림 네임서버 지원
GKE용 Cloud DNS는 kube-dns ConfigMap을 사용하여 구성된 커스텀 스텁 도메인과 업스트림 네임서버를 지원합니다. 이 지원은 GKE Standard 클러스터에만 제공됩니다.
Cloud DNS는 stubDomains 및 upstreamNameservers 값을 Cloud DNS 전달 영역으로 변환합니다.
사양 확장 프로그램
다양한 클라이언트 및 시스템과의 서비스 검색과 호환성을 개선하기 위해 일반적인 Kubernetes DNS 사양 외에 추가 사항을 사용할 수 있습니다.
이름이 지정된 포트
이 섹션에서는 이름이 지정된 포트가 Kubernetes 클러스터용 Cloud DNS에서 생성된 DNS 레코드에 미치는 영향을 설명합니다. Kubernetes는 필수 DNS 레코드의 최소 집합을 정의하지만 Cloud DNS는 자체 작업을 위해 그리고 다양한 Kubernetes 기능을 지원하기 위해 추가 레코드를 만들 수 있습니다. 다음 표에서는 예상 가능한 최소 레코드 세트 수를 보여줍니다. 여기서 'E'는 엔드포인트 수를, 'P'는 포트 수를 나타냅니다.
Cloud DNS에서 추가 레코드를 만들 수 있습니다.
| IP 스택 유형 | 서비스 유형 | 레코드 모음 |
|---|---|---|
| 단일 스택 | ClusterIP | $$2+P$$ |
| Headless | $$2+P+2E$$ |
|
| 이중 스택 | ClusterIP | $$3+P$$ |
| Headless | $$3+P+3E$$ |
|
| 단일 스택 서비스와 이중 스택 서비스에 대한 자세한 내용은 단일 및 이중 스택 서비스를 참고하세요. | ||
Cloud DNS에서 생성된 추가 DNS 레코드
Cloud DNS는 최소 레코드 세트 수 외에 추가 DNS 레코드를 만들 수 있습니다. 이러한 레코드는 다음과 같은 다양한 용도로 사용됩니다.
- SRV 레코드: 서비스 검색의 경우 Cloud DNS는 SRV 레코드를 자주 만듭니다. 이러한 레코드는 서비스의 포트 및 프로토콜에 대한 정보를 제공합니다.
- AAAA 레코드 (이중 스택용): IPv4와 IPv6를 모두 사용하는 이중 스택 구성에서 Cloud DNS는 엔드포인트마다 A 레코드 (IPv4용)와 AAAA 레코드 (IPv6용)를 모두 만듭니다.
- 내부 레코드: Cloud DNS는 자체 관리 및 최적화를 위해 내부 레코드를 만들 수 있습니다. 이러한 레코드는 일반적으로 사용자와 직접적인 관련이 없습니다.
- LoadBalancer 서비스:
LoadBalancer유형 서비스의 경우 Cloud DNS는 외부 부하 분산기 IP 주소와 연결된 레코드를 만듭니다. - 헤드리스 서비스: 헤드리스 서비스에는 고유한 DNS 구성이 있습니다. 각 포드는 자체 DNS 레코드를 가져오므로 클라이언트가 포드에 직접 연결할 수 있습니다. 이 접근 방식으로 인해 헤드리스 서비스 레코드 계산에서 포트 번호가 곱해지지 않습니다.
예: my-http-server이라는 서비스가 backend 네임스페이스에 있다고 가정해 보겠습니다. 이 서비스는 포드가 3개 있는 배포에 포트 2개(80 및 8080)을 노출합니다. 따라서 E = 3 및 P = 2입니다.
| IP 스택 유형 | 서비스 유형 | 레코드 모음 |
|---|---|---|
| 단일 스택 | ClusterIP | $$2+2$$ |
| Headless | $$2+2+2*3$$ |
|
| 이중 스택 | ClusterIP | $$3+2$$ |
| Headless | $$3+2+3*3$$ |
이러한 최소 레코드 외에도 Cloud DNS는 SRV 레코드를 만들 수 있으며 이중 스택 네트워킹의 경우 AAAA 레코드를 만들 수 있습니다. my-http-server가 LoadBalancer 유형 서비스이면 부하 분산기 IP의 추가 레코드가 생성됩니다. 참고: Cloud DNS는 필요에 따라 보조 DNS 레코드를 추가합니다. 생성되는 구체적인 레코드는 서비스 유형 및 구성과 같은 요인에 따라 다릅니다.
알려진 문제
이 섹션에서는 GKE와 함께 Cloud DNS를 사용할 때 발생할 수 있는 일반적인 문제와 가능한 해결 방법을 설명합니다.
dns_config 변경으로 인해 Terraform에서 Autopilot 클러스터를 다시 만들려고 함
terraform-provider-google 또는 terraform-provider-google-beta를 사용하는 경우 Terraform에서 Autopilot 클러스터를 다시 만들려고 하는 문제가 발생할 수 있습니다. 이 오류는 버전 1.25.9-gke.400, 1.26.4-gke.500, 1.27.1-gke.400 이상을 실행하는 새로 생성된 Autopilot 클러스터가 kube-dns 대신 DNS 제공업체로 Cloud DNS를 사용하기 때문에 발생합니다.
이 문제는 Google Cloud의 Terraform 제공업체 버전 4.80.0에서 해결되었습니다.
terraform-provider-google 또는 terraform-provider-google-beta 버전을 업데이트할 수 없는 경우 리소스에 lifecycle.ignore_changes 설정을 추가하여 google_container_cluster가 dns_config에 대한 변경사항을 무시하도록 할 수 있습니다.
lifecycle {
ignore_changes = [
dns_config,
]
}
NodeLocal DNSCache가 사용 설정된 상태에서 kube-dns에서 Cloud DNS로 마이그레이션한 후 DNS 변환 실패
이 섹션에서는 Cloud DNS에 있고 클러스터 범위에서 NodeLocal DNSCache를 사용 설정한 GKE 클러스터의 알려진 문제를 설명합니다.
클러스터에서 NodeLocal DNSCache가 사용 설정된 상태에서 kube-dns에서 Cloud DNS로 마이그레이션하면 클러스터에 간헐적인 변환 오류가 발생할 수 있습니다.
클러스터에서 NodeLocal DNSCache가 사용 설정된 상태로 kube-dns를 사용하는 경우 NodeLocal DNSCache는 NodeLocal DNSCache 주소와 kube-dns 주소라는 두 주소를 모두 리슨하도록 구성됩니다.
NodeLocal DNSCache 상태를 확인하려면 다음 명령어를 실행합니다.
kubectl get cm -n kube-system node-local-dns -o json | jq .data.Corefile -r | grep bind
출력은 다음과 비슷합니다.
bind 169.254.20.10 x.x.x.10
bind 169.254.20.10 x.x.x.10
클러스터에서 GKE Dataplane V2가 사용 설정되어 있고 클러스터에서 kube-dns를 사용하는 경우 NodeLocal DNSCache가 격리된 네트워크에서 실행되고 모든 포드 IP 주소 (0.0.0.0)에서 리슨하도록 구성됩니다. 출력은 다음과 비슷합니다.
bind 0.0.0.0
bind 0.0.0.0
클러스터가 Cloud DNS로 업데이트되면 NodeLocal DNSCache 구성이 변경됩니다. NodeLocal DNSCache 구성을 확인하려면 다음 명령어를 실행합니다.
kubectl get cm -n kube-system node-local-dns -o json | jq .data.Corefile -r | grep bind
출력은 다음과 비슷합니다.
bind 169.254.20.10
bind 169.254.20.10
다음 워크플로에서는 마이그레이션 및 노드 재생성 전후의 resolv.conf 파일 항목을 설명합니다.
마이그레이션 전
- 포드에
kube-dnsIP 주소(예:x.x.x.10)로 구성된resolv.conf파일이 있습니다. - NodeLocal DNSCache 포드는 포드의 DNS 요청을 가로채고 다음에서 리슨합니다.
- (DPv1) 두 주소 모두(169.254.20.10 x.x.x.10 바인딩)
- (DPv2) 모든 포드 IP 주소(0.0.0.0 바인딩)
- NodeLocal DNSCache는 캐시로 작동하며
kube-dns포드에 가해지는 부하가 최소화됩니다.
이전 후
- 컨트롤 플레인이 Cloud DNS를 사용하도록 업데이트된 후에도 포드에는
kube-dnsIP 주소 (예:x.x.x.10)로 구성된resolv.conf파일이 있습니다. 포드는 노드가 다시 생성될 때까지 이resolv.conf구성을 유지합니다. NodeLocal DNSCache가 사용 설정된 Cloud DNS의 경우 Pod가169.254.20.10를 네임서버로 사용하도록 구성해야 하지만 이 변경사항은 Cloud DNS로 마이그레이션된 후 생성되거나 다시 생성된 노드의 Pod에만 적용됩니다. - NodeLocal DNSCache 포드는 NodeLocal DNSCache 주소에서만 리슨합니다 (169.254.20.10 바인딩). 요청이 NodeLocal DNSCache 포드로 이동하지 않습니다.
- 포드의 모든 요청은
kube-dns포드로 직접 전송됩니다. 이 설정은 포드에서 높은 트래픽을 생성합니다.
노드 재생성 또는 노드 풀 업그레이드 후
- 포드에는 NodeLocal DNSCache IP 주소 (169.254.20.10)를 사용하도록 구성된
resolv.conf파일이 있습니다. - NodeLocal DNSCache 포드는 NodeLocal DNSCache 주소에서만 리슨하고 (169.254.20.10 바인딩) 이 IP 주소의 포드에서 DNS 요청을 수신합니다.
노드 풀을 다시 만들기 전에 노드 풀이 resolv.conf 파일에서 kube-dns IP 주소를 사용하는 경우 DNS 쿼리 트래픽이 증가하면 kube-dns 포드의 트래픽도 증가합니다. 이러한 증가로 인해 DNS 요청이 간헐적으로 실패할 수 있습니다. 오류를 최소화하려면 다운타임 기간 중에 이 마이그레이션을 계획해야 합니다.