使用 GKE 適用的 Cloud DNS

本文說明如何設定及使用 Cloud DNS 做為 Google Kubernetes Engine (GKE) 叢集的 DNS 供應商。

Cloud DNS 會自動管理 Kubernetes 服務的 DNS 記錄。 根據預設,這些記錄只能從叢集內存取 (叢集範圍)。

如要從叢集外部 (例如 Compute Engine VM) 解析無標頭服務,必須啟用「VPC 範圍」或「附加 VPC 範圍」

本文適用於 GKE 使用者,包括開發人員、管理員和架構師。如要進一步瞭解 Google Cloud中的常見角色和範例工作,請參閱「常見的 GKE Enterprise 使用者角色和工作」。

如要充分善用本文,您應該熟悉下列內容:

如要讓叢集外部可存取 ClusterIPNodePort 服務,您必須使用 LoadBalancer 或其他方法公開服務,並在 Cloud DNS 中註冊服務的外部 IP 位址。

如要進一步瞭解如何使用 kube-dns 做為 DNS 供應商,請參閱「服務探索和 DNS」。

如要瞭解如何使用自訂版本的 kube-dns 或自訂 DNS 供應商,請參閱「設定自訂 kube-dns 部署作業」。

定價

如果 Cloud DNS 是 GKE Standard 叢集的 DNS 供應商,系統會根據 Cloud DNS 定價,針對 GKE 叢集內 Pod 發出的 DNS 查詢計費。

查詢由 GKE 管理的 VPC 範圍 DNS 區域時,系統會根據標準 Cloud DNS 定價計費。

規定與限制

限制如下:

  • Autopilot 叢集不支援 VPC 範圍,僅支援叢集範圍。如要解析在 GKE Autopilot 叢集中執行的無標題 Service 名稱,必須使用加法虛擬私有雲範圍。
  • 您只能在建立叢集時,為 GKE Autopilot 叢集啟用加法 VPC 範圍。現有 GKE Autopilot 叢集不支援啟用或停用附加型虛擬私有雲範圍。
  • 不支援在共用 VPC 網路的服務專案中,建立附加型 VPC 範圍叢集。
  • Cloud DNS for GKE 不適用於 IL4 法規遵循制度的 Assured Workloadkube-dns
  • 系統不支援手動變更代管不公開 DNS 區域,且 Cloud DNS 控制器會覆寫這些變更。如果控制器重新啟動,這些區域的 DNS 記錄修改內容將不會保留。
  • 在叢集中啟用 Cloud DNS for GKE 後,kube-dns 會繼續在叢集中執行。如要停用 kube-dns,請kube-dns Deployment 和自動調度器調度至零
  • 使用 --cluster-dns-scope 旗標設定範圍後,您就無法變更叢集中的 DNS 範圍。如要變更 DNS 範圍,請使用不同的 DNS 範圍重新建立叢集。
  • 適用 Cloud DNS 資源的限制。具體來說,一次最多只能將一個回應政策區域繫結至 VPC 網路。如果是虛擬私有雲和附加虛擬私有雲範圍,如果已有不符合命名慣例的回應政策區域,且該區域已繫結至叢集的虛擬私有雲網路,叢集建立作業就會失敗。
  • 自訂存根網域和上游 DNS 伺服器設定會套用至 Pod 和節點的 DNS 設定。使用主機網路的 Pod 或直接在主機上執行的程序,也會使用存根網域和上游名稱伺服器設定。這項行為僅適用於標準版。
  • 透過 kube-dns Configmap 設定的自訂存根網域和上游名稱伺服器,會自動套用至叢集範圍 DNS 的 Cloud DNS。虛擬私有雲範圍 DNS 會忽略 kube-dns ConfigMap,您必須直接在 Cloud DNS 上套用這些設定。這項行為僅適用於標準模式。
  • kube-dns 遷移至 VPC 範圍是中斷性作業。從 kube-dns 切換至 VPC 範圍時,或反向切換時,請重新建立叢集。
  • 如果是 VPC 範圍,Service 的次要 IP 位址範圍不得與該子網路中的任何其他叢集共用。
  • 如果是虛擬私有雲範圍,與 PTR 記錄相關聯的回應政策會附加至虛擬私有雲網路。如果叢集網路繫結了任何其他回應政策,Kubernetes 服務 IP 位址的 PTR 記錄解析就會失敗。
  • 如果您嘗試建立無標題服務,但 Pod 數量超過允許配額,Cloud DNS 就不會為該服務建立記錄集或記錄。
  • 服務和連接埠名稱長度不得超過 62 個字元,即使 DNS 標籤的長度上限為 63 個字元也一樣。這是因為 GKE 會在 DNS 記錄中新增底線前置字元。

事前準備

開始之前,請確認您已完成下列工作:

  • 啟用 Google Kubernetes Engine API。
  • 啟用 Google Kubernetes Engine API
  • 如要使用 Google Cloud CLI 執行這項工作,請安裝初始化 gcloud CLI。如果您先前已安裝 gcloud CLI,請執行 gcloud components update 指令,取得最新版本。較舊的 gcloud CLI 版本可能不支援執行本文中的指令。
  • 在專案中啟用 Cloud DNS API:

    啟用 Cloud DNS API

  • 如要在叢集範圍內使用 Cloud DNS,您需要下列其中一個版本:

    • 標準叢集:GKE 1.24.7-gke.800 以上版本或 1.25.3-gke.700 以上版本。
    • Autopilot:GKE 1.25.9-gke.400 以上版本或 1.26.4-gke.500 以上版本。
    • Google Cloud CLI 411.0.0 以上版本。
  • 如要在附加型虛擬私有雲範圍中使用 Cloud DNS,您必須使用下列其中一個版本:

    • GKE 1.28.3-gke.1430000 以上版本。
    • Google Cloud CLI 503.0.0 以上版本。

啟用叢集範圍 DNS

在叢集範圍 DNS 中,只有在 GKE 叢集中執行的節點可以解析服務名稱,且服務名稱不會在叢集之間發生衝突。這項行為與 GKE 叢集中的 kube-dns 相同,也就是說,您可以將叢集從 kube-dns 遷移至 Cloud DNS 叢集範圍,應用程式不會停機或變更。

下圖說明 Cloud DNS 如何為 GKE 叢集建立私人 DNS 區域。只有在叢集節點上執行的程序和 Pod 才能解析叢集的 DNS 記錄,因為只有節點位於 DNS 範圍內。

不同節點上的 Pod 解析 GKE 叢集內的服務。
圖表: 叢集範圍 DNS

在新叢集中啟用叢集範圍

使用 1.25.9-gke.400、1.26.4-gke.500 以上版本的新 Autopilot 叢集,預設會採用 Cloud DNS 叢集範圍。下一節說明如何在新的 Standard 叢集中啟用叢集範圍。

建立啟用叢集範圍的標準叢集

您可以使用 gcloud CLI 或 Google Cloud 控制台,建立已啟用 Cloud DNS 叢集範圍的 GKE Standard 叢集:

gcloud

使用 --cluster-dns 旗標建立叢集:

gcloud container clusters create CLUSTER_NAME \
    --cluster-dns=clouddns \
    --cluster-dns-scope=cluster \
    --location=COMPUTE_LOCATION

更改下列內容:

指令中的 --cluster-dns-scope=cluster 旗標為選用,因為 cluster 是預設值。

控制台

  1. 在 Google Cloud 控制台中,前往「建立 Kubernetes 叢集」頁面。

    前往「建立 Kubernetes 叢集」

  2. 在導覽窗格的「叢集」底下,按一下 [網路]

  3. 在「DNS provider」(DNS 供應商) 部分,按一下「Cloud DNS」

  4. 選取「叢集範圍」

  5. 視需要設定叢集。

  6. 點選「建立」

在現有叢集中啟用叢集範圍

不支援將現有 Autopilot 叢集從 kube-dns 遷移至 Cloud DNS 叢集範圍。如要啟用 Cloud DNS 叢集範圍,請在 GKE 1.25.9-gke.400、1.26.4-gke.500 以上版本中重新建立 Autopilot 叢集。

您可以使用 gcloud CLI 或Google Cloud 控制台,將現有的標準叢集從 kube-dns 遷移至 Cloud DNS 叢集範圍。

kube-dns 遷移現有叢集至 Cloud DNS 時,您必須重新建立節點,變更才會生效。為每個節點集區分別啟用 Cloud DNS 做為 DNS 供應商,即可遷移執行應用程式的叢集,且不會中斷叢集通訊。由於部分節點集區使用 kube-dns,部分節點集區使用 Cloud DNS,因此節點子集會隨時運作。

gcloud

  1. 更新現有叢集:

    gcloud container clusters update CLUSTER_NAME \
        --cluster-dns=clouddns \
        --cluster-dns-scope=cluster \
        --location=COMPUTE_LOCATION
    

    更改下列內容:

    指令中的 --cluster-dns-scope=cluster 旗標為選用,因為 cluster 是預設值。

    回覆內容大致如下:

    All the node-pools in the cluster need to be re-created by the user to start using Cloud DNS for DNS lookups. It is highly recommended to complete this step
    shortly after enabling Cloud DNS.
    Do you want to continue (Y/n)?
    

    確認後,Cloud DNS 控制器會在 GKE 控制層上執行。不過,在您升級節點集區或在叢集中新增節點集區之前,Pod 不會使用 Cloud DNS 進行 DNS 解析。

  2. 升級叢集中的節點集區,改用 Cloud DNS:

    gcloud container clusters upgrade CLUSTER_NAME \
        --node-pool=POOL_NAME \
        --location=COMPUTE_LOCATION
    

    更改下列內容:

    • CLUSTER_NAME:叢集名稱。
    • POOL_NAME:要升級的節點集區名稱。

    如果節點集區和控制層執行相同版本,請先升級控制層,如「手動升級控制層」一文所述。然後執行節點集區升級作業。

    確認回應,並針對叢集中的每個節點集區重複執行這個指令。如果叢集只有一個節點集區,請省略 --node-pool 標記。

控制台

  1. 前往 Google Cloud 控制台的「Google Kubernetes Engine」頁面。

    前往「Google Kubernetes Engine」

  2. 按一下您要修改的叢集名稱。

  3. 在「Networking」(網路) 下方的「DNS provider」(DNS 供應商) 欄位中,按一下「Edit DNS provider」(編輯 DNS 供應商)

  4. 按一下「Cloud DNS」

  5. 按一下「叢集範圍」

  6. 按一下 [儲存變更]。

啟用附加型虛擬私有雲範圍

本節說明如何啟用或停用附加型虛擬私有雲範圍,做為 Cloud DNS 叢集範圍的附加元件。

在新叢集中啟用附加型虛擬私有雲範圍

您可以使用 gcloud CLI 或 Google Cloud 控制台,在新 GKE 叢集中啟用附加的 VPC 範圍 DNS。

建立具有附加型虛擬私有雲範圍的 Autopilot 叢集

gcloud container clusters create-auto CLUSTER_NAME \
    --additive-vpc-scope-dns-domain=UNIQUE_CLUSTER_DOMAIN

更改下列內容:

  • CLUSTER_NAME:叢集名稱。
  • UNIQUE_CLUSTER_DOMAIN:網域名稱。您必須確保這個名稱在 VPC 中不得重複,因為 GKE 不會確認這個值。設定後即無法變更這個值。 請勿使用以 .local 結尾的網域,否則可能會發生 DNS 解析失敗的情況。

建立具有附加型虛擬私有雲範圍的標準叢集

gcloud container clusters create CLUSTER_NAME \
    --cluster-dns=clouddns \
    --cluster-dns-scope=cluster \
    --additive-vpc-scope-dns-domain=UNIQUE_CLUSTER_DOMAIN

--cluster-dns-scope=cluster 是選用旗標,因為 cluster 是預設值。

更改下列內容:

  • CLUSTER_NAME:叢集名稱。
  • UNIQUE_CLUSTER_DOMAIN:網域名稱。您必須確保這個名稱在 VPC 中不得重複,因為 GKE 不會確認這個值。設定後即無法變更這個值。 請勿使用以 .local 結尾的網域,否則可能會發生 DNS 解析失敗的情況。
前往

在現有 Standard 叢集中啟用附加型虛擬私有雲範圍

現有 Autopilot 叢集不支援啟用附加型虛擬私有雲範圍。

如要在現有的 Standard 叢集中啟用加法虛擬私有雲範圍,請執行下列指令:

gcloud container clusters update CLUSTER_NAME \
    --additive-vpc-scope-dns-domain=UNIQUE_CLUSTER_DOMAIN \
    --location=COMPUTE_LOCATION

更改下列內容:

  • CLUSTER_NAME:叢集名稱。
  • UNIQUE_CLUSTER_DOMAIN:網域名稱。您必須確保這個名稱在 VPC 中不得重複,因為 GKE 不會確認這個值。設定後即無法變更。請勿使用結尾為 .local 的網域,否則可能會發生 DNS 解析失敗的情況。
  • COMPUTE_LOCATION:叢集的 Compute Engine 位置

啟用虛擬私有雲範圍 DNS

在虛擬私有雲範圍的 DNS 中,叢集的 DNS 名稱可在整個虛擬私有雲中解析。虛擬私有雲中的任何用戶端都可以解析叢集 DNS 記錄。

虛擬私有雲範圍 DNS 可用於下列用途:

  • 在相同 VPC 中,為非 GKE 用戶端探索無頭服務。
  • 從地端或第三方雲端用戶端解析 GKE 服務。詳情請參閱「輸入伺服器政策」。
  • 服務解析:用戶端可使用自訂叢集 DNS 網域,決定要與哪個叢集通訊。

在下圖中,兩個 GKE 叢集在同一個虛擬私有雲中使用虛擬私有雲範圍 DNS。兩個叢集都有自訂 DNS 網域 (.cluster1.cluster2),而非預設的 .cluster.local 網域。VM 會解析 backend.default.svc.cluster1,與無頭後端服務通訊。Cloud DNS 會將無標頭服務解析為服務中的個別 Pod IP 位址,而 VM 會直接與 Pod IP 位址通訊。

從 GKE 叢集外部解析無頭服務的用戶端。
圖表: 虛擬私有雲範圍 DNS

透過 Cloud Interconnect 或 Cloud VPN 連線至 VPC 時,您也可以從其他網路執行這類解析作業。DNS 伺服器政策可讓連線至虛擬私有雲的網路中的用戶端,解析 Cloud DNS 中的名稱,包括叢集使用虛擬私有雲範圍 DNS 時的 GKE 服務。

在現有叢集中啟用 VPC 範圍

只有 Standard 叢集支援遷移至虛擬私有雲範圍,Autopilot 叢集則不支援。

您可以使用 gcloud CLI 或 Google Cloud 控制台,將現有標準叢集從 kube-dns 遷移至 Cloud DNS VPC 範圍。

遷移至 VPC 範圍時,您必須重新建立節點,變更才會生效。

gcloud

  1. 更新現有叢集:

    gcloud container clusters update CLUSTER_NAME \
        --cluster-dns=clouddns \
        --cluster-dns-scope=vpc \
        --cluster-dns-domain=CUSTOM_DOMAIN \
        --location=COMPUTE_LOCATION
    

    更改下列內容:

    • CLUSTER_NAME:叢集名稱。
    • COMPUTE_LOCATION:叢集的 Compute Engine 位置
    • CUSTOM_DOMAIN:網域名稱。您必須確保這個名稱在 VPC 中不得重複,因為 GKE 不會確認這個值。設定後即無法變更。請勿使用結尾為 .local 的網域,否則可能會發生 DNS 解析失敗的情況。

    回覆內容大致如下:

    All the node-pools in the cluster need to be re-created by the user to start using Cloud DNS for DNS lookups. It is highly recommended to complete this step
    shortly after enabling Cloud DNS.
    Do you want to continue (Y/n)?
    

    確認後,Cloud DNS 控制器會在 GKE 控制層上執行。升級節點集區或在叢集中新增節點集區後,Pod 才會使用 Cloud DNS 進行 DNS 解析。

  2. 升級叢集中的節點集區,改用 Cloud DNS:

    gcloud container clusters upgrade CLUSTER_NAME \
        --node-pool=POOL_NAME
    

    更改下列內容:

    • CLUSTER_NAME:叢集名稱。
    • POOL_NAME:要升級的節點集區名稱。

    如果節點集區和控制層執行相同版本,請先升級控制層,如「手動升級控制層」一文所述。然後執行節點集區升級作業。

    確認回應,並針對叢集中的每個節點集區重複執行這個指令。如果叢集只有一個節點集區,請省略 --node-pool 標記。

控制台

  1. 前往 Google Cloud 控制台的「Google Kubernetes Engine」頁面。

    前往「Google Kubernetes Engine」

  2. 按一下要修改的叢集名稱。

  3. 在「Networking」(網路) 下方的「DNS provider」(DNS 供應商) 欄位中,按一下「Edit DNS provider」(編輯 DNS 供應商)

  4. 按一下「Cloud DNS」

  5. 按一下「虛擬私有雲範圍」

  6. 按一下 [儲存變更]。

驗證 Cloud DNS

確認 GKE 適用的 Cloud DNS 是否正常運作:

  1. 連線至節點上的 Pod 並執行 cat /etc/resolv.conf 指令,確認節點使用 Cloud DNS:

    kubectl exec -it POD_NAME -- cat /etc/resolv.conf | grep nameserver
    

    POD_NAME 替換為 Pod 名稱。

    輸出結果會與下列內容相似 (視叢集模式而定):

    GKE Autopilot 叢集

    nameserver 169.254.20.10
    

    由於 GKE Autopilot 預設會啟用 NodeLocal DNSCache,因此 Pod 會使用 NodeLocal DNSCache

    如果本機快取沒有要查詢名稱的項目,NodeLocal DNSCache 會將要求轉送至 Cloud DNS。

    GKE Standard 叢集

    nameserver 169.254.169.254
    

    這個 Pod 範例會使用 169.254.169.254 做為 nameserver,這是中繼資料伺服器的 IP 位址,Cloud DNS 資料平面會監聽通訊埠 53 上的要求。節點不再使用 kube-dns 服務位址進行 DNS 解析,所有 DNS 解析作業都會在本地節點上進行。

    如果輸出內容是類似 10.x.y.10 的 IP 位址,則 Pod 會使用 kube-dns。如要瞭解為何 Pod 仍使用 kube-dns,請參閱「疑難排解」一節。

    如果輸出內容為 169.254.20.10,表示您已在叢集中啟用 NodeLocal DNSCache,且 Pod 使用 NodeLocal DNSCache

  2. 將範例應用程式部署至叢集:

    kubectl run dns-test --image us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0
    
  3. 使用 Service 公開範例應用程式:

    kubectl expose pod dns-test --name dns-test-svc --port 8080
    
  4. 確認服務是否已成功部署:

    kubectl get svc dns-test-svc
    

    輸出結果會與下列內容相似:

    NAME           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
    dns-test-svc   ClusterIP   10.47.255.11    <none>        8080/TCP   6m10s
    

    CLUSTER-IP」欄的值是叢集的虛擬 IP 位址。在本範例中,虛擬 IP 位址為 10.47.255.11

  5. 確認服務名稱已在叢集的私有 DNS 區域中建立為記錄:

    gcloud dns record-sets list \
        --zone=PRIVATE_DNS_ZONE \
        --name=dns-test-svc.default.svc.DOMAIN_NAME.
    

    更改下列內容:

    • PRIVATE_DNS_ZONE:GKE 建立的代管 DNS 區域名稱。您可以在 Google Cloud 控制台的「Cloud DNS zones」(Cloud DNS 區域) 頁面中找到區域名稱,也可以參閱命名慣例
    • DOMAIN_NAMEcluster.local (如果您使用叢集範圍,但未新增虛擬私有雲範圍),或您啟用虛擬私有雲範圍或新增虛擬私有雲範圍時設定的自訂網域。

    輸出結果會與下列內容相似:

    NAME: dns-test-svc.default.svc.cluster.local.
    TYPE: A
    TTL: 30
    DATA: 10.47.255.11
    

在標準叢集中停用 Cloud DNS

如果 Autopilot 叢集預設啟用 Cloud DNS,則不支援停用這項服務。

標準版不支援停用虛擬私有雲範圍。您必須以 kube-dns 做為 DNS 供應商,重新建立叢集。

您可以使用 gcloud CLI 或Google Cloud 主控台,在 Standard 叢集中停用叢集範圍並還原為 kube-dns

gcloud

更新叢集以使用 kube-dns

gcloud container clusters update CLUSTER_NAME \
    --cluster-dns=kube-dns \
    --location=COMPUTE_LOCATION

更改下列內容:

控制台

  1. 前往 Google Cloud 控制台的「Google Kubernetes Engine」頁面。

    前往「Google Kubernetes Engine」

  2. 按一下要修改的叢集名稱。

  3. 在「Networking」(網路) 下方的「DNS provider」(DNS 供應商) 欄位中,按一下「Edit DNS provider」(編輯 DNS 供應商)

  4. 按一下「Kube-dns」

  5. 按一下 [儲存變更]。

停用 Cloud DNS 後,您必須重新建立節點集區,節點才能使用 kube-dns 進行解析。如果您先前已kube-dns 縮放至零個節點,則必須先將 kube-dns 放大,節點才能使用該節點進行 DNS 解析。如果您未重新建立節點集區,現有節點上的 Pod 會繼續使用 Cloud DNS 進行 DNS 解析,因為節點重新建立之前,系統不會更新 Pod 的 /etc/resolv.conf 檔案。

停用附加型虛擬私有雲範圍

停用叢集的加法虛擬私有雲範圍後,系統只會刪除附加至虛擬私有雲網路的不公開區域中的 DNS 記錄。在從叢集刪除無頭服務之前,GKE 叢集的私人 DNS 區域中的記錄會保留,並由 Cloud DNS for GKE 管理。

如要停用加法虛擬私有雲範圍,請執行下列指令:

gcloud container clusters update CLUSTER_NAME \
    --disable-additive-vpc-scope

CLUSTER_NAME 替換為叢集名稱。

這項設定會讓叢集保持啟用 Cloud DNS 叢集範圍,從而提供叢集內的 DNS 解析服務。

清除所用資源

完成本文件的練習後,請按照下列步驟移除資源,以免您的帳戶產生不必要的費用:

  1. 刪除服務:

    kubectl delete service dns-test-svc
    
  2. 刪除 Pod:

    kubectl delete Pod dns-test
    
  3. 您也可以刪除叢集

疑難排解

如要瞭解如何排解 Cloud DNS 問題,請參閱下列頁面:

後續步驟