本文可協助您判斷 Cloud DNS for GKE 是否適合叢集使用。您可以透過 Cloud DNS 處理 Pod 和服務 DNS 解析,取代叢集代管的 DNS 供應商,例如 kube-dns。
Autopilot 叢集的預設 DNS 供應商已是 Cloud DNS。如果是 Standard 叢集,您可以從 kube-dns 切換至 Cloud DNS。
本文適用於 GKE 使用者,包括開發人員、管理員和架構師。如要進一步瞭解 Google Cloud中的常見角色和範例工作,請參閱常見的 GKE 使用者角色和工作。
本文假設您已熟悉下列概念:
Cloud DNS for GKE 的運作方式
將 Cloud DNS 做為 GKE 的 DNS 供應商時,Cloud DNS 會提供 Pod 和 Service DNS 解析,不需要叢集託管的 DNS 供應商。系統會自動在 Cloud DNS 中為叢集 IP 位址、無頭和外部名稱服務,佈建 Pod 和服務的 DNS 記錄。
Cloud DNS 支援完整的 Kubernetes DNS 規格,並為 GKE 叢集內的 Service 提供 A、AAAA、SRV 和 PTR 記錄解析。PTR 記錄是透過回應政策規則實作。相較於叢集託管的 DNS,使用 Cloud DNS 做為 GKE 的 DNS 供應商有下列優點:
- 減少負擔:不必管理叢集託管的 DNS 伺服器。Cloud DNS 是全代管服務,因此您不必手動調度資源、監控或管理 DNS 執行個體。
- 高擴充性和效能:為每個 GKE 節點在本機解析查詢,提供低延遲且高度可擴充的 DNS 解析服務。為達到最佳效能,尤其是在大型叢集中,建議啟用 NodeLocal DNSCache,在節點上提供額外的快取層。
- 與 Google Cloud Observability 整合:啟用 DNS 監控和記錄功能。詳情請參閱「啟用及停用私人代管區域的記錄功能」。
架構
如果 Cloud DNS 是 GKE 的 DNS 供應商,控制器會以 GKE 管理的 Pod 形式執行。這個 Pod 會在叢集的控制層節點上執行,並將叢集 DNS 記錄同步至代管私人 DNS 區域。
下圖顯示 Cloud DNS 控制層和資料層如何解析叢集名稱:
在圖表中,Service 後端會選取執行中的後端 Pod。clouddns-controller 會為 Service 後端建立 DNS 記錄。
Pod 前端會傳送 DNS 要求,將名為「backend」的服務 IP 位址解析為 Compute Engine 本機中繼資料伺服器 (169.254.169.254)。中繼資料伺服器會在本機節點上執行,並將快取失敗傳送至 Cloud DNS。
Cloud DNS 會根據 Kubernetes Service 的類型,將 Service 名稱解析為不同的 IP 位址。如果是 ClusterIP Service,Cloud DNS 會將 Service 名稱解析為虛擬 IP 位址;如果是無頭 Service,則會將 Service 名稱解析為端點 IP 位址清單。
Pod 前端解析 IP 位址後,Pod 即可將流量傳送至 Service 後端,以及 Service 後方的任何 Pod。
DNS 範圍
Cloud DNS 具有下列 DNS 範圍。叢集無法同時以多種模式運作。
- GKE 叢集範圍:DNS 記錄只能在叢集內解析,行為與
kube-dns相同。只有在 GKE 叢集中執行的節點才能解析 Service 名稱。根據預設,叢集的 DNS 名稱結尾會是*.cluster.local。這些 DNS 名稱只能在叢集內查看,且不會與同一專案中其他 GKE 叢集的*.cluster.localDNS 名稱重疊或衝突。這是預設模式。- Cloud DNS 附加虛擬私有雲範圍:Cloud DNS 附加虛擬私有雲範圍是選用功能,可擴充 GKE 叢集範圍,讓無頭 Service 可從虛擬私有雲中的其他資源解析,例如 Compute Engine VM 或使用 Cloud VPN 或 Cloud Interconnect 連線的地端部署用戶端。這個模式是與叢集範圍一併啟用的額外模式。您可以在叢集中啟用或停用這項模式,不會影響 DNS 正常運作時間或叢集範圍功能。
- 虛擬私有雲範圍:DNS 記錄可以在整個虛擬私有雲中解析。Compute Engine VM 和地端部署用戶端可透過 Cloud Interconnect 或 Cloud VPN 連線,並直接解析 GKE 服務名稱。您必須為每個叢集設定專屬的自訂網域,也就是說,所有服務和 Pod DNS 記錄在 VPC 中都是獨一無二的。這個模式可減少 GKE 和非 GKE 資源之間的通訊阻礙。
下表列出 DNS 範圍的差異:
| 功能 | GKE 叢集範圍 | Cloud DNS 附加型虛擬私有雲範圍 | 虛擬私有雲範圍 |
|---|---|---|---|
| DNS 可見範圍 | 僅限 GKE 叢集內 | 僅限叢集,無頭 Service 可在虛擬私有雲網路中解析 | 整個虛擬私有雲網路 |
| 無頭服務解析 | 可在叢集內解析 | 可使用 `cluster.local` 網域在叢集內解析,以及使用叢集後置字串在虛擬私有雲中解析 | 使用叢集後置字串,即可在叢集內和整個虛擬私有雲中解析 |
| 專屬網域規定 | 否;使用預設的 `*.cluster.local` 網域 | 是,您必須設定專屬的自訂網域 | 是,您必須設定專屬的自訂網域 |
| 設定 | 預設,無須額外步驟 | 建立叢集時可選擇是否啟用 隨時都能啟用或停用 |
必須在建立叢集時設定 |
Cloud DNS 資源
使用 Cloud DNS 做為 GKE 叢集的 DNS 供應商時,Cloud DNS 控制器會在 Cloud DNS 中為專案建立資源。GKE 建立的資源取決於 Cloud DNS 範圍。
| 範圍 | 正向查詢區 | 反向查詢區 |
|---|---|---|
| 叢集範圍 | 每個 Compute Engine 可用區 (位於該區域) 的每個叢集有 1 個私人區域 | 每個叢集在每個 Compute Engine 可用區 (位於區域中) 都有 1 個回應政策區域 |
| Cloud DNS 附加型虛擬私有雲範圍 | 每個叢集在每個 Compute Engine 區域 (位於該區域內) 的 1 個私人區域
每個叢集 (全球區域) 的 1 個 VPC 範圍私人區域 (全球區域) |
每個叢集、每個 Compute Engine 可用區 (位於區域內) 1 個回應政策區域 (全域可用區)
每個叢集 1 個虛擬私有雲範圍回應政策區域 (全域可用區) |
| 虛擬私有雲範圍 | 每個叢集 1 個私人區域 (全域區域) | 每個叢集 1 個回應政策區域 (全域區域) |
這些 Cloud DNS 資源的命名慣例如下:
| 範圍 | 正向查詢區 | 反向查詢區 |
|---|---|---|
| 叢集範圍 | gke-CLUSTER_NAME-CLUSTER_HASH-dns |
gke-CLUSTER_NAME-CLUSTER_HASH-rp |
| Cloud DNS 附加型虛擬私有雲範圍 | gke-CLUSTER_NAME-CLUSTER_HASH-dns
(適用於叢集範圍區域)
gke-CLUSTER_NAME-CLUSTER_HASH-dns-vpc
(適用於虛擬私有雲範圍區域)
|
gke-CLUSTER_NAME-CLUSTER_HASH-rp (叢集範圍區域)
gke-NETWORK_NAME_HASH-rp (虛擬私有雲範圍區域) |
| 虛擬私有雲範圍 | 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 限制不同。
使用 Cloud DNS for GKE 時,系統會對專案中的每個代管區域套用下列預設配額:
| Kubernetes DNS 資源 | 對應的 Cloud DNS 資源 | 配額 |
|---|---|---|
| DNS 記錄數量 | 每個代管區域的位元組數上限 | 2,000,000 (代管區域上限為 50 MB) |
| 每個無頭 Service 的 Pod 數量 (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 資源限制,如下表所示:
| 限制 | 對上限的影響 |
|---|---|
| 每個代管區域的資源記錄集數 | 每個叢集的服務數量,加上具有有效主機名稱的無標題服務端點數量。 |
| 每個資源記錄集的記錄數 | 每個無標頭服務的端點數量。不會影響其他服務類型。 |
| 每項回應政策的規則數量 | 如果是叢集範圍,則為每個叢集的服務數量加上具有有效主機名稱的無頭服務端點數量。如果是虛擬私有雲範圍,則為服務數量加上虛擬私有雲中所有叢集內含有主機名稱的無頭端點數量。 |
如要進一步瞭解如何為 Kubernetes 建立 DNS 記錄,請參閱「Kubernetes DNS-Based Service Discovery」(Kubernetes 服務探索:以 DNS 為基礎)。
每個服務專案有多個叢集
從 GKE 1.22.3-gke.700 和 1.21.6-gke.1500 版開始,您可以在多個服務專案中建立叢集,並參照同一主機專案中的 VPC。
支援自訂虛設常式網域和上游名稱伺服器
Cloud DNS for GKE 支援使用 kube-dns ConfigMap 設定的自訂虛設常式網域和上游名稱伺服器。這項支援服務僅適用於 GKE Standard 叢集。
Cloud DNS 會將 stubDomains 和 upstreamNameservers 值轉換為 Cloud DNS 轉送區域。
規格擴充功能
如要改善服務探索作業,並提升與各種用戶端和系統的相容性,您可以在一般 Kubernetes DNS 規格的基礎上新增內容。
已命名的通訊埠
本節說明命名通訊埠如何影響 Cloud DNS 為 Kubernetes 叢集建立的 DNS 記錄。Kubernetes 會定義一組最低限度的必要 DNS 記錄,但 Cloud DNS 可能會建立額外記錄,用於自身作業及支援各種 Kubernetes 功能。下表說明預期最少會有的記錄集數量,其中「E」代表端點數量,「P」代表連接埠數量。Cloud DNS 可能會建立其他記錄。
| IP 堆疊類型 | 服務類型 | 記錄集 |
|---|---|---|
| 單一堆疊 | ClusterIP | $$2+P$$ |
| 無頭 | $$2+P+2E$$ |
|
| 雙堆疊 | ClusterIP | $$3+P$$ |
| 無頭 | $$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 位址相關聯的記錄。 - Headless 服務:headless 服務具有不同的 DNS 設定。每個 Pod 都會取得自己的 DNS 記錄,讓用戶端直接連線至 Pod。因此,在無標題服務記錄計算中,通訊埠號碼不會相乘。
範例:假設有名為 my-http-server 的 Service,且位於 backend 命名空間中。這項 Service 會為含有三個 Pod 的 Deployment 公開兩個通訊埠 (80 和 8080)。因此,E = 3,P = 2。
| IP 堆疊類型 | 服務類型 | 記錄集 |
|---|---|---|
| 單一堆疊 | ClusterIP | $$2+2$$ |
| 無頭 | $$2+2+2*3$$ |
|
| 雙堆疊 | ClusterIP | $$3+2$$ |
| 無頭 | $$3+2+3*3$$ |
除了這些最低記錄外,Cloud DNS 也可能會建立 SRV 記錄,如果是雙堆疊網路,則會建立 AAAA 記錄。如果 my-http-server 是 LoadBalancer 類型的 Service,系統會為負載平衡器 IP 建立額外記錄。注意:Cloud DNS 會視需要新增補充 DNS 記錄。建立的特定記錄取決於服務類型和設定等因素。
已知問題
本節說明將 Cloud DNS 與 GKE 搭配使用時可能遇到的常見問題,以及可能的解決方法。
Terraform 會因 dns_config 變更而嘗試重新建立 Autopilot 叢集
如果您使用 terraform-provider-google 或 terraform-provider-google-beta,可能會遇到 Terraform 嘗試重新建立 Autopilot 叢集的問題。發生這項錯誤的原因是,新建立的 Autopilot 叢集若執行 1.25.9-gke.400、1.26.4-gke.500 或 1.27.1-gke.400 以上版本,會使用 Cloud DNS 做為 DNS 供應商,而非 kube-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,
]
}
從 kube-dns 遷移至 Cloud DNS 後,啟用 NodeLocal DNSCache 時 DNS 解析失敗
本節說明 Cloud DNS 中 GKE 叢集的已知問題,這些叢集已在叢集範圍內啟用 NodeLocal DNSCache。
如果叢集已啟用 NodeLocal DNSCache,且您從 kube-dns 遷移至 Cloud DNS,叢集可能會發生間歇性解析錯誤。
如果您使用 kube-dns,並在叢集上啟用 NodeLocal DNSCache,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 會在隔離的網路中執行,並設為監聽所有 Pod 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 檔案中的項目:
遷移之前
- Pod 的
resolv.conf檔案已設為kube-dnsIP 位址 (例如x.x.x.10)。 - NodeLocal DNSCache Pod 會攔截 Pod 的 DNS 要求,並監聽下列項目:
- (DPv1) 兩個位址 (繫結 169.254.20.10 x.x.x.10)。
- (DPv2) 所有 Pod IP 位址 (繫結 0.0.0.0)。
- NodeLocal DNSCache 會做為快取,並盡可能減少
kube-dnsPod 的負載。
遷移之後
- 控制層更新為使用 Cloud DNS 後,Pod 仍會將
resolv.conf檔案設為kube-dnsIP 位址 (例如x.x.x.10)。Pod 會保留這項resolv.conf設定,直到重新建立節點為止。啟用 Cloud DNS 和 NodeLocal DNSCache 時,Pod 必須設為使用169.254.20.10做為名稱伺服器,但這項變更只會套用至節點上的 Pod,且這些節點是在遷移至 Cloud DNS 後建立或重新建立。 - NodeLocal DNSCache Pod 只會監聽 NodeLocal DNSCache 位址 (繫結 169.254.20.10)。要求不會傳送至 NodeLocal DNSCache Pod。
- Pod 的所有要求都會直接傳送至
kube-dnsPod。這項設定會在 Pod 上產生大量流量。
節點重新建立或節點集區升級後
- Pod 的
resolv.conf檔案已設為使用 NodeLocal DNSCache IP 位址 (169.254.20.10)。 - NodeLocal DNSCache Pod 只會監聽 NodeLocal DNSCache 位址 (繫結 169.254.20.10),並接收來自這個 IP 位址上 Pod 的 DNS 要求。
如果節點集區在重新建立前,使用 resolv.conf 檔案中的 kube-dns IP 位址,則 DNS 查詢流量增加時,kube-dns Pod 的流量也會增加。這項增加可能會導致 DNS 要求間歇性失敗。為盡可能減少錯誤,請務必在停機期間規劃這項遷移作業。