本页介绍了如何解决 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
:Service 的名称。
输出类似如下:
dns-test.default.svc.cluster.local. A 30 10.47.255.11
此输出显示 Cloud DNS 包含网域
dns-test.default.svc.cluster.local.
的 A 记录,并且集群的 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 虚拟机解析 GKE 集群服务
如果您无法从 Compute Engine 虚拟机解析 GKE 集群服务,请验证集群的 Cloud DNS 范围。
您在 Cloud DNS 中使用的范围决定了可以解析哪些资源:
集群范围:DNS 解析仅限于 Kubernetes 集群内的资源(Pod 和 Service)。这是默认设置,适用于您无需解析 Kubernetes 集群或 GKE Virtual Private Cloud (VPC) 之外的外部资源的情况。
VPC 范围:DNS 解析会扩展到整个 VPC,包括 Compute Engine 虚拟机等资源。这样,集群就可以解析 GKE 集群外部但位于同一 VPC 内的资源的内部 DNS 记录,例如 Google Cloud VM。
如需验证集群的 Cloud DNS 范围,请完成以下步骤:
在 Google Cloud 控制台中,前往 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 要求使用 VPC 范围的集群使用 GKE 1.19 或更高版本,或者使用集群范围的集群使用 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 额外的 VPC 范围的集群
请确保您使用的版本正确无误。Cloud DNS 额外的 VPC 范围需要 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 配额错误排查指南操作。
错误:未能绑定响应政策
当响应政策绑定到集群网络且 Cloud DNS for GKE 尝试将响应政策绑定到网络时,会发生以下事件:
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 Policy Analyzer 获取具有
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 Customer Care 联系。