本文可協助您判斷 Cloud DNS for GKE 是否適合叢集使用。您可以透過 Cloud DNS 處理 Pod 和服務 DNS 解析,取代叢集代管的 DNS 供應商 (例如 kube-dns)。
如為 Autopilot 叢集,Cloud DNS 已是預設的 DNS 供應商。如果是標準叢集,可以從 kube-dns 切換至 Cloud DNS。
本文適用於 GKE 使用者,包括開發人員、管理員和架構師。如要進一步瞭解 Google Cloud中的常見角色和範例工作,請參閱「常見的 GKE Enterprise 使用者角色和工作」。
本文假設您熟悉下列概念:
Cloud DNS for GKE 的運作方式
將 Cloud DNS 做為 GKE 的 DNS 供應商時,Cloud DNS 會提供 Pod 和服務 DNS 解析功能,不需要叢集代管的 DNS 供應商。系統會自動在 Cloud DNS 中為叢集 IP 位址、無頭和外部名稱服務,佈建 Pod 和服務的 DNS 記錄。
Cloud DNS 支援完整的 Kubernetes DNS 規格,並為 GKE 叢集中的服務提供 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 控制平面和資料平面如何解析叢集名稱:
在圖表中,服務後端會選取正在執行的後端 Pod。clouddns-controller 會為服務後端建立 DNS 記錄。
Pod 前端會傳送 DNS 要求,將名為 backend 的 Service IP 位址解析為 Compute Engine 本機中繼資料伺服器 (169.254.169.254)。中繼資料伺服器會在節點上本機執行,並將快取未命中項目傳送至 Cloud DNS。
Cloud DNS 會根據 Kubernetes 服務類型,將服務名稱解析為不同的 IP 位址。如果是 ClusterIP 服務,Cloud DNS 會將服務名稱解析為虛擬 IP 位址;如果是無標頭服務,則會將服務名稱解析為端點 IP 位址清單。
Pod 前端解析 IP 位址後,Pod 就能將流量傳送至 Service 後端和 Service 後方的任何 Pod。
DNS 範圍
Cloud DNS 具有下列 DNS 範圍。叢集無法同時以多種模式運作。
- GKE 叢集範圍:DNS 記錄只能在叢集內解析,與
kube-dns的行為相同。只有在 GKE 叢集中執行的節點可以解析服務名稱。根據預設,叢集的 DNS 名稱結尾為*.cluster.local。這些 DNS 名稱只會在叢集內顯示,且不會與同一專案中其他 GKE 叢集的*.cluster.localDNS 名稱重疊或衝突。這是預設模式。- Cloud DNS 附加虛擬私有雲範圍: Cloud DNS 附加虛擬私有雲範圍是選用功能,可擴充 GKE 叢集範圍,讓虛擬私有雲中的其他資源 (例如 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 叢集內 | 僅限叢集,無頭服務可在虛擬私有雲網路中解析 | 整個虛擬私有雲網路 |
| 無頭服務解析度 | 可在叢集內解析 | 在叢集內使用 `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 個VPC 範圍的回應政策區域 |
| 虛擬私有雲範圍 | 每個叢集 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 設定 | 可用區類型 | 可用區命名慣例 |
|---|---|---|
| Stub 網域 | 轉送 (全球區域) | 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) |
| 每個無頭服務的 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 資源限制,如下表所示:
| 限制 | 貢獻額度 |
|---|---|
| 每個代管區域的資源記錄集 | 每個叢集的服務數量,加上具有有效主機名稱的無 Headless 服務端點數量。 |
| 每個資源記錄集的記錄 | 每個無頭服務的端點數量。不會影響其他服務類型。 |
| 每個回應政策的規則數量 | 如果是叢集範圍,則為每個叢集的服務數量,加上具有有效主機名稱的無標頭服務端點數量。如果是虛擬私有雲範圍,則為虛擬私有雲中所有叢集的服務數量,加上具有主機名稱的無伺服器端點數量。 |
如要進一步瞭解如何為 Kubernetes 建立 DNS 記錄,請參閱 Kubernetes DNS 服務探索。
每個服務專案有多個叢集
從 GKE 1.22.3-gke.700 和 1.21.6-gke.1500 版開始,您可以在多個服務專案中建立叢集,並參照相同主專案中的虛擬私有雲。
支援自訂存根網域和上游名稱伺服器
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 位址相關聯的記錄。 - 無頭服務:無頭服務具有不同的 DNS 設定。每個 Pod 都會取得自己的 DNS 記錄,讓用戶端直接連線至 Pod。因此,在無周邊裝置服務記錄計算中,通訊埠號碼不會相乘。
範例:假設有名為 my-http-server 的服務,且位於 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 類型的服務,系統會為負載平衡器 IP 建立額外記錄。注意:Cloud DNS 會視需要新增補充 DNS 記錄。建立的具體記錄取決於服務類型和設定等因素。
已知問題
本節說明使用 Cloud DNS 和 GKE 時可能遇到的常見問題,以及可能的解決方法。
Terraform 會因 dns_config 變更而嘗試重新建立 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 叢集,會使用 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 解析失敗
本節說明 GKE 叢集的已知問題,這些叢集位於 Cloud DNS 中,且已在叢集範圍內啟用 NodeLocal DNSCache。
在叢集上啟用 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 會在獨立網路中執行,並設為監聽所有 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 可做為快取,並將最少的負載放在 Pod 上。
kube-dns
遷移之後
- 控制平面更新為使用 Cloud DNS 後,Pod 仍會將
resolv.conf檔案設定為kube-dnsIP 位址 (例如x.x.x.10)。Pod 會保留這項resolv.conf設定,直到節點重新建立為止。啟用 Cloud DNS 和 NodeLocal DNSCache 後,Pod 必須設為使用169.254.20.10做為名稱伺服器,但這項變更只會套用至遷移至 Cloud DNS 後建立或重新建立的節點上的 Pod。 - 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 要求間歇性失敗。為盡量減少錯誤,您必須在停機期間規劃這項遷移作業。