使用 Cloud DNS for GKE


本页面介绍如何将 Cloud DNS 用作 Google Kubernetes Engine (GKE) 的 Kubernetes DNS 提供商。

使用 Cloud DNS 作为 DNS 提供商不会允许集群外部的客户端直接解析和访问 Kubernetes 服务。您仍然需要使用负载均衡器在外部公开 Service,并在您的 DNS 基础架构上注册其集群外部 IP 地址。

如需详细了解如何将 kube-dns 用作 DNS 提供商,请参阅服务发现和 DNS

如需了解如何使用自定义版本的 kube-dns 或自定义 DNS 提供商,请参阅设置自定义 kube-dns Deployment

Cloud DNS for GKE 的工作原理

Cloud DNS 可用作 GKE 的 DNS 提供商,提供具有代管式 DNS (无需集群托管的 DNS 提供商) 的 Pod 和 Service 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 实例,因为它是由高度可扩缩的 Google 基础架构托管的全托管式服务。
  • 每个 GKE 节点上 DNS 查询的本地解析。与 NodeLocal DNSCache 类似,Cloud DNS 在本地缓存 DNS 响应,提供低延迟和高可伸缩性 DNS 解析。

架构

当 Cloud DNS 是 GKE 的 DNS 提供商时,控制器作为 GKE 管理的 Pod 运行。此 Pod 在集群的控制平面节点上运行,并将集群 DNS 记录同步到代管专用 DNS 区域。

下图展示了 Cloud DNS 控制平面和数据平面如何解析集群名称:

Pod 使用 Cloud DNS 请求服务的 IP 地址。
图表:解析集群名称

在该图中,Service backend 选择正在运行的 backend Pod。clouddns-controller 为 Service backend 创建 DNS 记录。

Pod frontendCompute Engine 本地元数据服务器 (169.254.169.254) 发送 DNS 请求以解析名为 backend 的 Service 的 IP 地址。元数据服务器在节点上本地运行,并向 Cloud DNS 发送未命中的缓存。

Cloud DNS 数据平面在每个 GKE 节点或 Compute Engine 虚拟机 (VM) 实例中本地运行。根据 Kubernetes Service 的类型,Cloud DNS 会将 Service 名称解析为其虚拟 IP 地址(对于集群 IP Service)或端点 IP 地址列表(对于无头 Service)。

Pod frontend 解析 IP 地址后,Pod 可以将流量发送到 Service backend 以及 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。额外的 VPC 范围是与集群范围一起启用的额外模式,您可以在集群中启用停用它,而不会影响 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 范围 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 Standard 集群的 DNS 提供商时,来自 GKE 集群内 Pod 的 DNS 查询根据 Cloud DNS 价格结算。

对由 GKE 管理的 VPC 级 DNS 区域的查询按标准 Cloud DNS 价格计费。

要求

必须在项目中启用 Cloud DNS API。

Cloud DNS for GKE 对集群范围具有以下要求:

  • 对于标准版,需要 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 for GKE 对额外的 VPC 范围具有以下要求:

  • 对于标准版,需要 GKE 1.24.7-gke.800、1.25.3-gke.700 或更高版本。
  • 对于 Autopilot,需要 GKE 1.28 或更高版本。
  • Google Cloud CLI 471.0.0 版。
  • GKE 集群必须使用 Cloud DNS 集群范围作为默认 DNS 提供商。

Cloud DNS for GKE 对 VPC 范围具有以下要求:

  • 对于标准版,需要 GKE 1.19 或更高版本。
  • Google Cloud CLI 364.0.0 或更高版本。
  • 必须在项目中启用 Cloud DNS API。

限制和局限

存在以下限制:

  • Autopilot 集群不支持 VPC 范围,仅支持集群范围。如果您需要解析在 GKE Autopilot 集群中运行的无头 Service 名称,则必须使用额外的 VPC 范围。
  • Cloud DNS 不符合 Impact Level 4 (IL4) 合规性制度。Cloud DNS for GKE 不能在采用 IL4 合规性制度的 Assured Workloads 工作负载中使用。您需要在此类受监管环境中使用 kube-dns。 对于 GKE Autopilot 集群,系统会根据您的合规性制度自动选择 kube-dns 或 Cloud DNS。
  • 对代管专用 DNS 区域所做的手动更改不受支持,会被 Cloud DNS 控制器覆盖。控制器重启时不会保留这些区域中的 DNS 记录修改。
  • 使用 --cluster-dns-scope 标志设置范围后,您将无法更改集群中的 DNS 范围。如果您需要更改 DNS 范围,请使用其他 DNS 范围重新创建集群。
  • 自定义存根网域和上游 DNS 服务器配置适用于 Pod 和节点的 DNS 配置。使用主机网络或直接在主机上运行的进程的 Pod 也会使用存根域和上游域名服务器配置。仅 Standard 支持此功能。
  • 通过 kube-dns Configmap 配置的自定义存根域和上游域名服务器会自动应用于 Cloud DNS 以获取集群范围 DNS。VPC 范围 DNS 会忽略 kube-dns ConfigMap,您必须直接在 Cloud DNS 上应用这些配置。 仅 Standard 支持此功能。
  • 从 kube-dns 到 VPC 范围没有迁移路径,操作是中断性的。从 kube-dns 切换到 VPC 范围或从 VPC 范围切换到 kube-dns 时重新创建集群。
  • 对于 VPC 范围,Service 的次要 IP 地址范围不得与该子网中的任何其他集群共享。
  • 对于 VPC 范围,与 PTR 记录关联的响应政策会附加到 VPC 网络。如果有任何其他响应政策绑定到集群网络,则 PTR 记录解析将不适用于 Kubernetes 服务 IP 地址。
  • 如果您尝试创建无头 Service,但使用的 Pod 数量超出允许的配额,Cloud DNS 不会为该 Service 创建记录集或记录。

配额

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

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

Kubernetes DNS 资源 相应的 Cloud DNS 资源 配额
DNS 记录数 每个代管区域的字节数上限 2,000,000(代管区域最大 50MB)
每个无头 Service 的 Pod 数 (IPv4/IPv6) 每个资源记录集的记录数 GKE 1.24 到 1.25:1,000 (IPv4/IPv6)
GKE 1.26 及更高版本:3,500/2,000 (IPv4/IPv6)
项目中的 GKE 集群数量 每个项目的响应政策数 100
每个集群的 PTR 记录数 每项响应政策的规则数 100000

资源限制

您为每个集群创建的 Kubernetes 资源会计入 Cloud DNS 资源限制,如下表所示:

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

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

准备工作

在开始之前,请确保您已执行以下任务:

  • 启用 Google Kubernetes Engine API。
  • 启用 Google Kubernetes Engine API
  • 如果您要使用 Google Cloud CLI 执行此任务,请安装初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请运行 gcloud components update 以获取最新版本。

启用集群范围 DNS

在集群范围 DNS 中,只有在 GKE 集群中运行的节点才能解析服务名称,并且服务名称在集群之间不会冲突。此行为与 GKE 集群中的 kube-dns 相同,这意味着您可以将集群从 kube-dns 迁移到 Cloud DNS 集群范围,而无需停机或更改您的应用。

下图展示了 Cloud DNS 如何为 GKE 集群创建专用 DNS 区域。只有在集群节点上运行的进程和 Pod 才能解析集群的 DNS 记录,因为只有节点位于 DNS 范围内。

不同节点上的 Pod 解析 GKE 集群中的 Service。
图表 :集群范围 DNS

在新集群中启用集群范围 DNS

GKE Autopilot 集群

1.25.9-gke.400、1.26.4-gke.500 或更高版本的新 Autopilot 集群默认使用 Cloud DNS 集群范围。

GKE 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 控制台中的 Google Kubernetes Engine 页面。

    转到 Google Kubernetes Engine

  2. 点击 创建

  3. 在导航窗格的集群下,点击网络

  4. DNS 提供商部分,点击 Cloud DNS

  5. 选择集群范围

  6. 根据需要配置集群。

  7. 点击创建

在现有集群中启用集群范围 DNS

GKE Autopilot 集群

您无法将现有 GKE Autopilot 集群从 kube-dns 迁移到 Cloud DNS 集群范围。如需启用 Cloud DNS 集群范围,请重新创建 1.25.9-gke.400、1.26.4-gke.500 或更高版本的 Autopilot 集群。

GKE Standard 集群

您可以在 GKE Standard 集群中使用 gcloud CLI 或 Google Cloud 控制台将现有 GKE Standard 集群从 kube-dns 迁移到 Cloud DNS 集群范围。

迁移现有集群时,除非您重新创建节点,否则集群中的节点不会将 Cloud DNS 用作 DNS 提供商。

为集群启用 Cloud DNS 后,相应设置仅在您升级现有节点池或向集群添加新节点池时适用。升级节点池时,系统会重新创建节点。

您还可以通过单独将 Cloud DNS 作为每个节点池中的 DNS 提供商来迁移具有正在运行应用的集群,而不会中断集群通信。部分节点始终处于运行状态,因为某些节点池使用 kube-dns 而部分节点池使用 Cloud DNS。

在以下步骤中,您将为集群启用 Cloud DNS,然后升级节点池。升级节点池会重新创建节点。然后,节点使用 Cloud DNS 而不是 kube-dns 进行 DNS 解析。

gcloud

  1. 更新现有集群:

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

    替换以下内容:

    响应类似于以下示例:

    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. 网络下的 DNS 提供商字段中,点击 修改 DNS 提供商

  4. 点击 Cloud DNS

  5. 点击集群范围

  6. 点击保存更改

启用 Cloud DNS 额外的 VPC 范围

本部分介绍了启用或停用 Cloud DNS 额外的 VPC 范围(作为 Cloud DNS 集群范围的附加组件)的步骤。

在新集群中启用 Cloud DNS 额外的 VPC 范围

您可以使用 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 解析可能会失败。

对于 Standard

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

替换以下内容:

  • CLUSTER_NAME:集群的名称。
  • UNIQUE_CLUSTER_DOMAIN:网域的名称。您必须确保此名称在 VPC 中具有唯一性,因为 GKE 不会确认此值。此值一经设置便无法更改。请勿使用以“.local”结尾的网域,否则 DNS 解析可能会失败。

在现有集群中启用 Cloud DNS 额外的 VPC 范围

如需在现有集群中启用 Cloud DNS 额外的 VPC 范围,请先为集群启用 Cloud DNS,然后升级节点池。升级节点池会重新创建节点。节点随后会使用 Cloud DNS 而不是 kube-dns 进行 DNS 解析。

如需在现有集群中启用 Cloud DNS 额外的 VPC 范围,请运行以下命令:

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

替换以下内容:

  • CLUSTER_NAME:集群的名称。
  • UNIQUE_CLUSTER_DOMAIN:网域的名称。您必须确保此名称在 VPC 中具有唯一性,因为 GKE 不会确认此值。此值一经设置便无法更改。请勿使用以“.local”结尾的网域,否则 DNS 解析可能会失败。

启用 VPC 范围 DNS

在 VPC 范围的 DNS 中,集群的 DNS 名称可在整个 VPC 内进行解析。VPC 中的任何客户端都可以解析集群 DNS 记录。

VPC 范围 DNS 可实现以下使用场景:

  • 同一 VPC 中非 GKE 客户端的无头服务发现。
  • 来自本地或第三方云客户端的 GKE 服务解析。如需了解详情,请参阅入站服务器政策
  • 服务解析,客户端可以使用自定义集群 DNS 网域决定要与哪个集群通信。

在下图中,两个 GKE 集群在同一 VPC 中使用 VPC 范围 DNS。这两个集群都具有自定义 DNS 网域 .cluster1.cluster2,而不是默认的 .cluster.local 网域。虚拟机通过解析 backend.default.svc.cluster1 与无头后端服务进行通信。Cloud DNS 将无头 Service 解析为 Service 中的各个 Pod IP,并且虚拟机直接与 Pod IP 进行通信。

从 GKE 集群外部解析到无头服务的客户端。
图表:VPC 范围 DNS

当通过 Cloud Interconnect 或 Cloud VPN 连接到 VPC 时,您还可以在其他网络中执行此类解析。DNS 服务器政策允许来自 VPC 所连接网络的客户端解析 Cloud DNS 中的名称;如果集群使用 VPC 范围 DNS,则包括 GKE 服务。

在现有集群中启用 VPC 范围 DNS

只有 GKE Standard 支持此迁移,而 GKE Autopilot 不支持。

GKE Autopilot 集群

您无法将 GKE Autopilot 集群从 kube-dns 迁移到 Cloud DNS VPC 范围。

GKE Standard 集群

您可以使用 gcloud CLI 或 Google Cloud 控制台将现有 GKE 集群从 kube-dns 迁移到 Cloud DNS VPC 范围。

为集群启用 Cloud DNS 后,相应设置仅在您升级现有节点池或向集群添加新节点池时适用。升级节点池时,系统会重新创建节点。

在以下步骤中,您将为集群启用 Cloud DNS,然后升级节点池。升级节点池会重新创建节点。然后,节点使用 Cloud DNS 而不是 kube-dns 进行 DNS 解析。

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. 网络下的 DNS 提供商字段中,点击 修改 DNS 提供商

  4. 点击 Cloud DNS

  5. 点击 VPC 范围

  6. 点击保存更改

验证 Cloud DNS

验证 Cloud DNS for GKE 是否在集群中正常运行:

  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. 验证 Service 已成功部署:

    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. 验证您的 Service 名称是否已在集群的专用 DNS 区域中作为记录创建:

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

    PRIVATE_DNS_ZONE 替换为代管 DNS 区域的名称。

    输出类似于以下内容:

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

停用 Cloud DNS for GKE

GKE Autopilot 集群

默认情况下,您无法在使用 Cloud DNS 创建的 GKE Autopilot 集群中停用 Cloud DNS。如需详细了解默认使用 Cloud DNS 的 GKE Autopilot 集群,请参阅要求

GKE Standard 集群

您可以在 GKE Standard 集群中使用 gcloud CLI 或 Google Cloud 控制台停用 Cloud DNS 集群范围。

gcloud

更新集群以使用 kube-dns:

gcloud container clusters update CLUSTER_NAME \
    --cluster-dns=default

控制台

  1. 转到 Google Cloud 控制台中的 Google Kubernetes Engine 页面。

    转到 Google Kubernetes Engine

  2. 点击要修改的集群的名称。

  3. 网络下的 DNS 提供商字段中,点击 修改 DNS 提供商

  4. 点击 Kube-dns

  5. 点击保存更改

停用 Cloud DNS 额外的 VPC 范围

为集群停用 Cloud DNS 额外的 VPC 范围时,只有连接到 VPC 网络的专用区域中的 DNS 记录会被删除。GKE 集群的专用 DNS 区域中的记录将保留,由 Cloud DNS for GKE 管理,直到无头 Service 从集群中删除。

如需停用 Cloud DNS 额外的 VPC 范围,请运行以下命令:

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 与共享 VPC 搭配使用

Cloud DNS for GKE 支持 VPC 和集群范围的共享 VPC。

GKE 控制器会在 GKE 集群所在的项目中创建托管式专用区域。

GKE 集群的 GKE 服务账号不需要在其自身项目之外使用 DNS 的 Identity and Access Management (IAM),因为托管地区和 GKE 集群位于同一项目中。

每个服务项目有多个集群

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

如果您已拥有使用共享 VPC 和 Cloud DNS VPC 范围的集群,则必须按照以下步骤手动迁移它们:

您可以使用 Google Cloud 控制台迁移响应政策。

在服务项目中执行以下步骤:

  1. 转到 Cloud DNS 区域页面。

    转到 Cloud DNS 区域

  2. 点击响应政策区域标签页。

  3. 点击您的 VPC 网络的响应政策。您可以通过说明识别响应政策,这与“网络 NETWORK_NAME 上的 GKE 集群的响应政策”类似。

  4. 点击使用者标签页。

  5. 在宿主项目的名称旁边,点击 以移除网络绑定。

  6. 点击响应政策规则标签页。

  7. 选择表中的所有条目。

  8. 点击移除响应政策规则

  9. 点击 删除响应政策

删除响应政策后,DNS 控制器会自动在宿主项目中创建响应政策。其他服务项目中的集群共享此响应政策。

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

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

Cloud DNS 会将 stubDomainsupstreamNameservers 值转换为 Cloud DNS 转发地区。

已知问题

由于 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,
    ]
  }

问题排查

如需了解如何启用 DNS 日志记录,请参阅为专用代管区域启用和停用日志记录功能

如需详细了解如何排查 DNS 问题,请参阅排查 GKE 中的 DNS 问题

无法更新现有集群或创建启用了 Cloud DNS 的集群

请确保您使用的版本正确。Cloud DNS for GKE 要求使用 VPC 范围的集群使用 GKE 1.19 或更高版本,或者使用集群范围的集群使用 GKE 1.24.7-gke.800、1.25.3-gke.700 或更高版本。

即使在现有集群上启用了 Cloud DNS,Pod 也会使用 kube-dns

在集群上启用 Cloud DNS 后,确保您已升级或重新创建节点池。在此步骤完成之前,Pod 将继续使用 kube-dns。

Pod 无法解析 DNS 查询

  1. 通过连接到 Pod 并运行命令 cat /etc/resolv.conf,验证 Pod 是否正在使用 Cloud DNS:

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

    POD_NAME 替换为 Pod 的名称。

    输出类似于以下内容:

    nameserver 169.254.169.254
    

    如果输出是类似于 10.x.y.1034.118.224.10 的 IP 地址(仅在 1.27 及更高版本的 GKE Autopilot 集群中),则说明 Pod 使用的是 kube-dns。如果输出为 169.254.20.10,则说明 Pod 使用的是 NodeLocal DNSCache

  2. 确认该托管地区存在且包含必要的 DNS 条目:

    gcloud dns managed-zones list --format list
    

    输出类似于以下内容:

     - creationTime: 2021-02-12T19:24:37.045Z
       description: Private zone for GKE cluster "cluster1" with cluster suffix "cluster.local" in project "project-243723"
       dnsName: cluster.local.
       id: 5887499284756055830
       kind: dns#managedZone
       name: gke-cluster1-aa94c1f9-dns
       nameServers: ['ns-gcp-private.googledomains.com.']
       privateVisibilityConfig: {'kind': 'dns#managedZonePrivateVisibilityConfig'}
       visibility: private
    

    响应中的 name 值表明 Google Cloud 创建了一个名为 gke-cluster1-aa94c1f9-dns 的专用地区。

  3. 验证 Cloud DNS 是否包含集群的条目:

    gcloud dns record-sets list --zone ZONE_NAME | grep SERVICE_NAME
    

    替换以下内容:

    • ZONE_NAME:专用地区的名称。
    • SERVICE_NAME:服务的名称。

    输出显示 Cloud DNS 包含网域 dns-test.default.svc.cluster.local. 和集群的 IP 地址 10.47.255.11 的 A 记录:

    dns-test.default.svc.cluster.local.                A     30     10.47.255.11
    
  4. 启用 Cloud DNS 日志记录以跟踪查询。每个日志条目都包含有关查询的信息,包括 DNS 延迟时间。

在集群上启用 Cloud DNS 后,节点上的 DNS 查找会失败

如果您在具有自定义存根域或上游域名服务器的 GKE 集群中启用集群范围 Cloud DNS,则自定义配置将应用于集群中的节点和 Pod,因为 Cloud DNS 无法区分 Pod 和节点 DNS 请求。如果自定义上游服务器无法解析查询,节点上的 DNS 查找可能会失败。

无法更新现有集群或创建启用了 Cloud DNS 额外的 VPC 范围的集群

请确保您使用的版本正确。Cloud DNS 额外的 VPC 范围需要 GKE 1.28 或更高版本。

Pod 无法解析 DNS 查询

  1. 通过连接到 Pod 并运行命令 cat /etc/resolv.conf,验证 Pod 是否正在使用 Cloud DNS:

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

    POD_NAME 替换为 Pod 的名称。

    输出类似于以下内容:

    nameserver 169.254.169.254
    

    如果输出是类似于 10.x.y.1034.118.224.10 的 IP 地址(仅在 1.27 及更高版本的 GKE Autopilot 集群中),则说明 Pod 使用的是 kube-dns。如果输出为 169.254.20.10,则说明 Pod 使用的是 NodeLocal DNSCache

  2. 确认该托管地区存在且包含必要的 DNS 条目:

    gcloud dns managed-zones list --format list
    

    输出类似于以下内容:

    gke-cluster-1-cbdc0678-dns  cluster.local.   Private zone for GKE cluster "cluster-1" with cluster suffix "cluster.local." in project "PROJECT_NAME" with scope "CLUSTER_SCOPE"  private
    gke-cluster-1-cbdc-dns-vpc  CLUSTER_DOMAIN.  Private zone for GKE cluster "cluster-1" with cluster suffix "CLUSTER_DOMAIN." in project "PROJECT_NAME" with scope "VPC_SCOPE"     private
    

    响应中的 name 值表明 Google Cloud 创建了一个名为 gke-cluster1-aa94c1f9-dns 的专用地区。

  3. 验证 Cloud DNS 是否在两个托管式区域中都包含集群的对应条目:

    gcloud dns record-sets list --zone ZONE_NAME | grep SERVICE_NAME
    

    替换以下内容:

    • ZONE_NAME:专用地区的名称。
    • SERVICE_NAME:服务的名称。

    输出类似于以下内容:

    my-service.default.svc.cluster.local.                A     30     10.47.255.11
    

    响应中的 name 值表明 Google Cloud 创建了一个名为 gke-cluster1-aa94c1f9-dns 的专用地区。

  4. 对于 DNS 反向查找,请验证 Cloud DNS 是否在响应政策中包含集群的对应条目:

    gcloud dns response-policies list --format="table(responsePolicyName, description)"
    

    输出类似于以下内容:

      gke-NETWORK_HASH-rp        Response Policy for GKE clusters on network "VPC_NAME".
      gke-cluster-1-52c8f518-rp  Response Policy for GKE cluster "cluster-1" with cluster suffix "cluster.local." in project "khamed-gke-dev" with scope "CLUSTER_SCOPE".
    

    响应中的 name 值表明 Google Cloud 创建了一个名为 gke-cluster1-aa94c1f9-rp 的专用地区。

  5. 对于 DNS 反向查找,请验证 Cloud DNS 是否在响应政策中包含集群的对应条目:

      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.
    

后续步骤