本頁面說明如何解決 Google Kubernetes Engine (GKE) 中的 Cloud DNS 問題。
找出 Cloud DNS 中的 DNS 問題來源
如果發生 dial tcp: i/o timeout
、no such
host
或 Could not resolve host
等錯誤,通常表示 Cloud DNS 無法解析查詢。
如果看到上述錯誤訊息,但不知道原因,請參閱下列章節,找出問題所在。各節內容的安排順序,是從最可能解決問題的步驟開始,因此請依序嘗試各節的步驟。
確認基本設定
如果 Pod 無法解析 DNS 查詢,請確認 Cloud DNS 設定符合您的需求。本節將協助您確認是否使用 Cloud DNS、確認 GKE 叢集是否有私人 DNS 區域,以及確保目標服務的 DNS 記錄正確無誤。
如要驗證這些設定,請完成下列指令:
檢查 Pod 使用的 DNS 伺服器:
kubectl exec -it POD_NAME -- cat /etc/resolv.conf | grep nameserver
將
POD_NAME
替換為 DNS 解析發生問題的 Pod 名稱。如果您使用 Cloud DNS,輸出內容如下:
nameserver 169.254.169.254
如果看到其他值,表示您並未使用 Cloud DNS。確認 Cloud DNS 已正確啟用。
確認受管理區域存在:
gcloud dns managed-zones list --format list
輸出結果會與下列內容相似:
- creationTime: 2021-02-12T19:24:37.045Z description: Private zone for GKE cluster "" with cluster suffix "CLUSTER_DOMAIN" in project "PROJECT_ID" dnsName: CLUSTER_DOMAIN. id: 5887499284756055830 kind: dns#managedZone name: gke-CLUSTER_NAME-aa94c1f9-dns nameServers: ['ns-gcp-private.googledomains.com.'] privateVisibilityConfig: {'kind': 'dns#managedZonePrivateVisibilityConfig'} visibility: private
這項輸出內容包含下列值:
CLUSTER_DOMAIN
:自動指派給叢集的 DNS 網域後置字串。PROJECT_ID
:您的專案 ID。CLUSTER_NAME
:具有私人區域的叢集名稱。
在這個輸出內容中,
name
欄位中的值顯示Google Cloud 建立名為gke-CLUSTER_NAME-aa94c1f9-dns
的區域。如果沒有看到代管區域,表示叢集未建立私人區域,或是您可能未正確通過驗證。如要排解問題,請參閱 Cloud DNS 說明文件中的私人區域。
驗證服務的 DNS 記錄:
gcloud dns record-sets list --zone ZONE_NAME | grep SERVICE_NAME
更改下列內容:
ZONE_NAME
:私人區域的名稱。SERVICE_NAME
:服務名稱。
輸出結果會與下列內容相似:
dns-test.default.svc.cluster.local. A 30 10.47.255.11
這項輸出內容顯示 Cloud DNS 含有網域的 A 記錄
dns-test.default.svc.cluster.local.
,且叢集的 IP 位址為10.47.255.11
。如果記錄有誤,請參閱 Cloud DNS 說明文件中的「修補資源記錄集」一節,瞭解如何更新記錄。
驗證回覆政策
確認回應政策存在且名稱正確:
查看所有回覆政策的清單:
gcloud dns response-policies list --format="table(responsePolicyName, description)"
輸出結果會與下列內容相似:
RESPONSE_POLICY_NAME DESCRIPTION gke-CLUSTER_NAME-52c8f518-rp Response Policy for GKE cluster "CLUSTER_NAME" with cluster suffix "cluster.local." in project "gke-dev" with scope "CLUSTER_SCOPE".
在這個輸出內容中,
gke-CLUSTER_NAME-52c8f518-rp
表示Google Cloud 已建立名為gke-CLUSTER_NAME-aa94c1f9-rp
的私人區域。Google Cloud 建立的回應政策會加上gke-
前置字元。查看特定私有區域中的回應政策:
gcloud dns response-policies rules list ZONE_NAME \ --format="table(localData.localDatas[0].name, localData.localDatas[0].rrdatas[0])"
將
ZONE_NAME
替換成發生問題的私有區域名稱。輸出結果會與下列內容相似:
1.240.27.10.in-addr.arpa. kubernetes.default.svc.cluster.local. 52.252.27.10.in-addr.arpa. default-http-backend.kube-system.svc.cluster.local. 10.240.27.10.in-addr.arpa. kube-dns.kube-system.svc.cluster.local. 146.250.27.10.in-addr.arpa. metrics-server.kube-system.svc.cluster.local.
第一欄會顯示規則比對的 IP 位址或網域名稱模式。第二欄是與 IP 位址相關聯的主機名稱。
如果發現這些指令的輸出內容有任何問題,請參閱 Cloud DNS 說明文件中的更新回應政策規則。
透過記錄、資訊主頁和指標進行調查
Cloud DNS 提供多種記錄和監控選項,可協助您進一步調查 DNS 問題:
如要查看區域和記錄等資源的記錄,請為 Cloud DNS 啟用 Cloud Logging。
如要查看 DNS 查詢的圖表,以及私人區域的錯誤率、每秒查詢次數 (QPS) 和第 99 個百分位數延遲時間資料,請使用 Cloud DNS 監控資訊主頁。
如要以視覺化方式呈現 DNS 查詢的延遲時間和成功率,請在 Metrics Explorer 中使用
query/latencies
和query/response_count
指標。
查看是否有新記錄
查看記錄,確認受管理的 Cloud DNS 私人區域中是否已建立任何新記錄。如果叢集突然發生 DNS 解析失敗的情況,這項功能就很有幫助。
如要檢查是否有新記錄,請完成下列步驟:
前往 Google Cloud 控制台的「Logs Explorer」頁面。
在查詢窗格中,輸入下列查詢:
resource.type="dns_managed_zone" protoPayload.request.change.additions.name="headless-svc-stateful.default.svc.cluster.local." protoPayload.methodName="dns.changes.create"
點選「執行查詢」
查看輸出內容。如果發現變更與您首次發現錯誤的時間相符,請考慮還原變更。
驗證自訂存根網域和名稱伺服器
如果您使用 GKE Standard 叢集,並搭配自訂存根網域或上游名稱伺服器,請檢查 ConfigMap 並確認值正確無誤。
Cloud DNS 會將 stubDomains
和 upstreamNameservers
值轉換為 Cloud DNS 轉送區域。這些資源由 Google 管理,因此如果發現任何錯誤,請與 Cloud Customer Care 團隊聯絡,尋求協助。
與 Cloud Customer Care 聯絡
如果已完成上述各節的步驟,但仍無法診斷問題原因,請與 Cloud Customer Care 團隊聯絡。
解決特定錯誤
如果遇到特定錯誤或問題,請參閱下列各節的建議。
問題:無法從 Compute Engine VM 解析 GKE 叢集服務
如果無法從 Compute Engine VM 解析 GKE 叢集服務,請確認叢集的 Cloud DNS 範圍。
您在 Cloud DNS 中使用的範圍會決定可解析的資源:
叢集範圍:DNS 解析僅限於 Kubernetes 叢集「內」的資源 (Pod 和服務)。這是預設設定,如果您不需要解析 Kubernetes 叢集或 GKE 虛擬私有雲 (VPC) 外部的資源,就適合使用這項設定。
虛擬私有雲範圍:DNS 解析會擴展至整個虛擬私有雲,包括 Compute Engine VM 等資源。這樣一來,叢集就能解析 GKE 叢集外部但位於同一虛擬私有雲內的資源 (例如 Google Cloud 虛擬機器) 的內部 DNS 記錄。
如要驗證叢集的 Cloud DNS 範圍,請完成下列步驟:
在 Google Cloud 控制台中,前往「Kubernetes clusters」(Kubernetes 叢集) 頁面。
按一下發生 DNS 問題的叢集名稱。
在叢集詳細資料頁面的「叢集網路」部分,查看「DNS 供應商」列中的資訊。
如果看到「Cloud DNS (叢集範圍)」,表示您使用的是叢集範圍。如要變更 DNS 範圍,請使用適當的 DNS 範圍重新建立叢集。
問題:啟用 Cloud DNS 後,Pod 仍使用 kube-dns
如果現有叢集啟用 Cloud DNS 後,Pod 仍使用 kube-dns,請務必在叢集啟用 Cloud DNS 後,升級或重新建立節點集區。完成這個步驟之前,Pod 會繼續使用 kube-dns。
問題:無法更新現有叢集或建立已啟用 Cloud DNS 的叢集
確認使用正確版本。如要使用 Cloud DNS for GKE,叢集必須使用 GKE 1.19 以上版本 (適用於使用 VPC 範圍的叢集),或是 GKE 1.24.7-gke.800、1.25.3-gke.700 以上版本 (適用於使用叢集範圍的叢集)。
問題:在叢集上啟用 Cloud DNS 後,節點上的 DNS 查詢失敗
如果您在具有自訂存根網域或上游名稱伺服器的 GKE 叢集中啟用叢集範圍 Cloud DNS,自訂設定會同時套用至叢集中的節點和 Pod,因為 Cloud DNS 無法區分 Pod 和節點 DNS 要求。如果自訂上游伺服器無法解析查詢,節點上的 DNS 查詢可能會失敗。
問題:無法更新或建立已啟用 Cloud DNS 附加型虛擬私有雲範圍的叢集
確認你使用的是正確版本。Cloud DNS 附加型虛擬私有雲範圍需要 GKE 1.28 以上版本。
錯誤:Cloud DNS 已停用
停用 Cloud DNS API 時,會發生下列事件:
Warning FailedPrecondition service/default-http-backend
Failed to send requests to Cloud DNS: Cloud DNS API Disabled. Please enable the Cloud DNS API in your project PROJECT_NAME: Cloud DNS API has not been used in project PROJECT_NUMBER before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/dns.googleapis.com/overview?project=PROJECT_NUMBER then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.
發生這項錯誤的原因是 Cloud DNS API 預設為停用。您必須手動啟用 Cloud DNS API。
如要解決這個問題,請啟用 Cloud DNS API。
錯誤:無法將要求傳送至 Cloud DNS:超出 API 速率限制。
專案超出 Cloud DNS 配額或限制時,會發生下列事件:
kube-system 27s Warning InsufficientQuota
managedzone/gke-cluster-quota-ee1bd2ca-dns Failed to send requests to Cloud DNS: API rate limit exceeded. Contact Google Cloud support team to request a quota increase for your project PROJECT_NAME: Quota exceeded for quota metric 'Write requests' and limit 'Write limit for a minute for a region' of service 'dns.googleapis.com' for consumer 'project_number:PROJECT_NUMBER.
如要解決這個問題,請查看 Cloud DNS 配額和 Compute Engine 配額與限制。您可以使用 Google Cloud 控制台增加配額。
錯誤:由於先前發生錯誤,因此無法將要求傳送至 Cloud DNS
當錯誤導致連鎖性故障時,會發生下列事件:
kube-system 27s Warning InsufficientQuota
managedzone/gke-cluster-quota-ee1bd2ca-dns Failed to send requests to Cloud DNS: API rate limit exceeded. Contact Google Cloud support team to request a quota increase for your project PROJECT_NAME: Quota exceeded for quota metric 'Write requests' and limit 'Write limit for a minute for a region' of service 'dns.googleapis.com' for consumer 'project_number:PROJECT_NUMBER.
kube-system 27s Warning FailedPrecondition service/default-http-backend Failed to send requests to Cloud DNS due to a previous error. Please check the cluster events.
如要解決這個問題,請檢查叢集事件,找出原始錯誤的來源,然後按照說明解決根本問題。
在上述範例中,代管區域的 InsufficientQuota
錯誤觸發了連鎖故障。FailedPrecondition
的第二個錯誤表示先前發生錯誤,也就是初始配額不足的問題。如要解決這個範例問題,請按照 Cloud DNS 配額錯誤的指南操作。
錯誤:無法繫結回覆政策
當回應政策繫結至叢集網路,且 GKE 適用的 Cloud DNS 嘗試將回應政策繫結至網路時,會發生下列事件:
kube-system 9s Warning FailedPrecondition responsepolicy/gke-2949673445-rp
Failed to bind response policy gke-2949673445-rp to test. Please verify that another Response Policy is not already associated with the network: Network 'https://www.googleapis.com/compute/v1/projects/PROJECT_NAME/global/networks/NETWORK_NAME' cannot be bound to this response policy because it is already bound to another response policy.
kube-system 9s Warning FailedPrecondition service/kube-dns
Failed to send requests to Cloud DNS due to a previous error. Please check the cluster events.
如要解決這個問題,請完成下列步驟:
取得繫結至網路的回應政策:
gcloud dns response-policies list --filter='networks.networkUrl: NETWORK_URL'
將
NETWORK_URL
替換為錯誤中的網路網址,例如https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/networks/NETWORK_NAME
。如果輸出內容為空白,表示回應政策可能不在同一個專案中。 請繼續下一個步驟,搜尋回覆政策。
如果輸出內容與下列內容類似,請跳至步驟 4,刪除回應政策。
[ { "description": "Response Policy for GKE cluster \"CLUSTER_NAME\" with cluster suffix \"cluster.local.\" in project \"PROJECT_ID\" with scope \"CLUSTER_SCOPE\".", ... "kind": "dns#responsePolicy", "responsePolicyName": "gke-CLUSTER_NAME-POLICY_ID-rp" } ]
使用 IAM 政策分析器,取得具有
dns.networks.bindDNSResponsePolicy
權限的專案清單。檢查每個專案是否都有繫結至網路的回應政策:
gcloud dns response-policies list --filter='networks.networkUrl:NETWORK_URL' \ --project=PROJECT_NAME
錯誤:kube-dns 中指定的設定無效
套用不適用於 Cloud DNS for GKE 的自訂 kube-dns ConfigMap 時,會發生下列事件:
kube-system 49s Warning FailedValidation configmap/kube-dns
Invalid configuration specified in kube-dns: error parsing stubDomains for ConfigMap kube-dns: dnsServer [8.8.8.256] validation: IP address "8.8.8.256" invalid
如要解決這個問題,請查看錯誤詳細資料,找出 ConfigMap 中的無效部分。在上述範例中,8.8.8.256
不是有效的 IP 位址。
後續步驟
如需診斷 Kubernetes DNS 問題的一般資訊,請參閱「偵錯 DNS 解析」。
查看 Cloud DNS 疑難排解。
如果無法在說明文件中找到問題的解決方法,請參閱「取得支援」一文,尋求進一步的協助, 包括下列主題的建議:
- 與 Cloud 客戶服務聯絡,建立支援案件。
- 在 StackOverflow 上提問,並使用
google-kubernetes-engine
標記搜尋類似問題,向社群尋求支援。你也可以加入#kubernetes-engine
Slack 頻道,取得更多社群支援。 - 使用公開問題追蹤工具回報錯誤或提出功能要求。