Cloud DNS for GKE 简介

本文档可帮助您确定 Cloud DNS for GKE 是否是适合您集群的 DNS 解决方案。您可以使用 Cloud DNS 来处理 Pod 和 Service DNS 解析,作为 kube-dns 等集群托管 DNS 提供商的替代方案。

对于 Autopilot 集群,Cloud DNS 已是默认 DNS 提供商。对于 Standard 集群,您可以从 kube-dns 切换到 Cloud DNS。

本文档适用于 GKE 用户,包括开发者、管理员和架构师。如需详细了解 Google Cloud中的常见角色和示例任务,请参阅常见的 GKE Enterprise 用户角色和任务

本文档假定您熟悉以下概念:

Cloud DNS for GKE 的工作原理

将 Cloud DNS 用作 GKE 的 DNS 提供商时,Cloud DNS 可提供 Pod 和 Service DNS 解析,而无需集群托管的 DNS 提供商。系统会自动在 Cloud DNS 中为集群 IP 地址、无头和外部名称 Service 预配 Pod 和 Service 的 DNS 记录。

Cloud DNS 支持完整的 Kubernetes DNS 规范,并为 GKE 集群中的 Service 提供 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 使用 Cloud DNS 请求服务的 IP 地址。
使用 Cloud DNS 解析集群名称

在该图中,服务后端选择正在运行的后端 Pod。clouddns-controller 为服务后端创建 DNS 记录。

Pod 前端向 169.254.169.254 处的 Compute Engine 本地元数据服务器发送 DNS 请求,以解析名为 backend 的 Service 的 IP 地址。元数据服务器在节点上本地运行,并向 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.local DNS 名称重叠或冲突。此模式为默认模式
    • Cloud DNS 附加 VPC 范围:Cloud DNS 附加 VPC 范围是一项可选功能,可扩展 GKE 集群范围,从而可从 VPC 中的其他资源(例如 Compute Engine 虚拟机,或是使用 Cloud VPN 或 Cloud Interconnect 连接的本地客户端)解析无头 Service。此模式是与集群范围一起启用的附加模式。您可以在集群中启用停用此模式,而不会影响 DNS 正常运行时间或集群范围功能。
  • VPC 范围:DNS 记录在整个 VPC 中可解析。Compute Engine 虚拟机和本地客户端可以使用 Cloud Interconnect 或 Cloud VPN 进行连接,并可以直接解析 GKE 服务名称。您必须为每个集群设置唯一自定义网域,这意味着所有 Service 和 Pod DNS 记录在 VPC 中都是唯一的。此模式可以减少 GKE 与非 GKE 资源之间的通信冲突。

下表列出了 DNS 范围之间的区别:

特性 GKE 集群范围 Cloud DNS 额外的 VPC 范围 VPC 范围
DNS 公开范围 仅在 GKE 集群中 仅限集群,无头服务可在整个 VPC 网络中解析 整个 VPC 网络
无头 Service 解析 可在集群中解析 可使用“cluster.local”网域在集群内解析,并使用集群后缀在整个 VPC 中解析 可使用集群后缀在集群内和整个 VPC 中解析
唯一网域要求 否;使用默认的“*.cluster.local”网域 有,您必须设置唯一自定义网域 有,您必须设置唯一自定义网域
设置配置 默认,无额外步骤 创建集群时可选
可以随时启用或停用
必须在创建集群期间配置

Cloud DNS 资源

使用 Cloud DNS 作为 GKE 集群的 DNS 提供商时,Cloud DNS 控制器会在 Cloud DNS 中为您的项目创建资源。GKE 创建的资源取决于 Cloud DNS 范围。

范围 正向查找区域 反向查找区域
集群范围 每个 Compute Engine 区域的每个集群有 1 个专用区域(在地区中) 每个 Compute Engine 区域的每个集群有 1 个响应政策区域(在地区中)
Cloud DNS 额外的 VPC 范围 每个集群(全球区域)的每个 Compute Engine 区域(在地区中)的每个集群有 1 个专用区域
每个集群(全球区域)有 1 个 VPC 范围专用区域
每个集群(全球区域)的每个 Compute Engine 区域(在地区中)的每个集群有 1 个响应政策区域
每个集群(全球区域)有 1 个 VPC 范围响应政策区域
VPC 范围 每个集群有 1 个专用区域(全球区域) 每个集群有 1 个响应政策区域(全球区域)

这些 Cloud DNS 资源使用的命名惯例如下:

范围 正向查找区域 反向查找区域
集群范围 gke-CLUSTER_NAME-CLUSTER_HASH-dns gke-CLUSTER_NAME-CLUSTER_HASH-rp
Cloud DNS 额外的 VPC 范围 gke-CLUSTER_NAME-CLUSTER_HASH-dns(适用于集群范围区域)
gke-CLUSTER_NAME-CLUSTER_HASH-dns-vpc(适用于 VPC 范围区域)
gke-CLUSTER_NAME-CLUSTER_HASH-rp(适用于集群范围区域)
gke-NETWORK_NAME_HASH-rp(适用于 VPC 范围区域)
VPC 范围 gke-CLUSTER_NAME-CLUSTER_HASH-dns gke-NETWORK_NAME_HASH-rp

除了上表提到的区域之外,Cloud DNS 控制器还会根据您的配置在项目中创建以下区域:

自定义 DNS 配置 区域类型 区域命名惯例
存根网域 转发(全球区域) 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-aus-central1-bus-central1-cus-central1-f 中创建托管式区域。

对于每个 DNS stubDomain,Cloud DNS 控制器都会创建一个转发区域。

Cloud DNS 使用具有 . DNS 名称的一个托管区域来处理每个上游 DNS。

配额

Cloud DNS 使用配额来限制 GKE 可为 DNS 条目创建的资源数量。Cloud DNS 的配额和限制可能与项目的 kube-dns 限制不同。

使用 Cloud DNS for GKE 时,系统会为项目中的每个托管区域应用以下默认配额:

Kubernetes DNS 资源 相应的 Cloud DNS 资源 Quota
DNS 记录数 每个代管区域的字节数上限 2,000,000(托管区域最大 50 MB)
每个无头 Service 的 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 资源限制,如下表所示:

限制 计入限制
每个托管式区域的资源记录集数 每个集群的服务数加上具有有效主机名的无头服务端点数。
每个资源记录集的记录数 每个无头服务的端点数。不会影响其他服务类型。
每项响应政策的规则数 对于集群范围,每个集群的服务数加上具有有效主机名的无头服务端点数。 对于 VPC 范围,VPC 中所有集群的服务数加上具有主机名的无头端点数。

如需详细了解如何为 Kubernetes 创建 DNS 记录,请参阅 Kubernetes 基于 DNS 的服务发现

每个服务项目有多个集群

从 1.22.3-gke.700 和 1.21.6-gke.1500 版开始,您可以在多个引用同一宿主项目中的 VPC 的服务项目中创建集群。

支持自定义存根域和上游域名服务器

Cloud DNS for GKE 支持使用 kube-dns ConfigMap 配置的自定义存根域和上游域名服务器。此支持仅适用于 GKE Standard 集群。

Cloud DNS 会将 stubDomainsupstreamNameservers 值转换为 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 命名空间中的服务。此服务为具有三个 pod 的部署公开了两个端口: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 搭配使用时可能会遇到的常见问题,以及可能的解决方法。

由于 dns_config 更改,Terraform 尝试重新创建 Autopilot 集群

如果使用 terraform-provider-googleterraform-provider-google-beta,您可能会遇到 Terraform 尝试重新创建 Autopilot 集群的问题。发生此错误是因为运行 1.25.9-gke.400、1.26.4-gke.500 或 1.27.1-gke.400 及更高版本的新建 Autopilot 集群使用 Cloud DNS(而不是 kube-dns)作为 DNS 提供商。

此问题已在 Google Cloud的 Terraform 提供程序 4.80.0 版中得到解决

如果您无法更新 terraform-provider-googleterraform-provider-google-beta 的版本,则可以将 lifecycle.ignore_changes 设置添加到资源中,以帮助确保 google_container_cluster 忽略对 dns_config 的更改:

  lifecycle {
    ignore_changes = [
      dns_config,
    ]
  }

kube-dns 迁移到 Cloud DNS 后,DNS 解析失败(NodeLocal DNSCache 已启用)

本部分介绍了 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-dns IP 地址(例如 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 用作缓存,kube-dns Pod 上的负载极小。

迁移后

  • 在控制平面更新为使用 Cloud DNS 后,Pod 仍具有配置为 kube-dns IP 地址(例如 x.x.x.10)的 resolv.conf 文件。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-dns Pod。此设置会在 pod 上生成高流量。

在节点重新创建或节点池升级后

  • Pod 已配置 resolv.conf 文件,以使用 NodeLocal DNSCache IP 地址 (169.254.20.10)。
  • NodeLocal DNSCache Pod 仅侦听 NodeLocal DNSCache 地址 (bind 169.254.20.10),并接收来自此 IP 地址上 Pod 的 DNS 请求。

当节点池在重新创建之前使用 resolv.conf 文件中的 kube-dns IP 地址时,DNS 查询流量的增加也会增加 kube-dns Pod 上的流量。这种增加可能会导致 DNS 请求间歇性失败。为尽量减少错误,您必须在停机期间规划此迁移。

后续步骤