如果 Pod 無法連線至服務,且 Google Kubernetes Engine (GKE) 叢集使用 Cloud DNS 做為 DNS 供應商,您可能會遇到 dial tcp: i/o timeout
或 no such host
等錯誤。這類錯誤通常表示 Cloud DNS 設定有問題,例如私人區域設定錯誤或 Cloud DNS 範圍不正確。
本頁面可協助您診斷及解決使用 GKE 管理的 Cloud DNS 服務時的常見問題,確保工作負載的 DNS 解析作業穩定可靠。
平台管理員和營運人員,以及設定及管理 GKE 與 Cloud DNS 整合的網路專家,請務必詳閱本文資訊。如果應用程式開發人員遇到服務探索問題,這項工具也很有幫助。如要進一步瞭解我們在 Google Cloud 內容中提及的常見角色和範例工作,請參閱「常見的 GKE 使用者角色和工作」。
找出 Cloud DNS 中的 DNS 問題來源
下列各節有助於診斷 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
如果 Pod 在現有叢集上啟用 Cloud DNS 後仍使用 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 頻道,取得更多社群支援。 - 使用公開問題追蹤工具回報錯誤或提出功能要求。