本页面介绍如何将 Cloud DNS 用作 Google Kubernetes Engine (GKE) 的 Kubernetes DNS 提供商。
使用 Cloud DNS 作为 DNS 提供商不会允许集群外部的客户端直接解析和访问 Kubernetes 服务。您仍然需要使用负载均衡器在外部公开 Service,并在您的 DNS 基础架构上注册其集群外部 IP 地址。
如需详细了解如何将 kube-dns 用作 DNS 提供商,请参阅服务发现和 DNS。
如需了解如何使用自定义版本的 kube-dns 或自定义 DNS 提供商,请参阅设置自定义 kube-dns 部署。
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 解析。
- 与 Google Cloud Observability 集成,用于 DNS 监控和日志记录。如需了解详情,请参阅为专用代管区域启用和停用日志记录功能。
架构
当 Cloud DNS 是 GKE 的 DNS 提供商时,控制器作为 GKE 管理的 Pod 运行。此 Pod 在集群的控制平面节点上运行,并将集群 DNS 记录同步到代管专用 DNS 区域。
下图展示了 Cloud DNS 控制平面和数据平面如何解析集群名称:
在该图中,Service backend
选择正在运行的 backend
Pod。clouddns-controller
为 Service backend
创建 DNS 记录。
Pod frontend
向 Compute 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 名称重叠或冲突。这是默认模式。
- 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-a
、us-central1-b
、us-central1-c
和 us-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 记录修改。
- 在集群中启用 Cloud DNS for GKE 后,kube-dns 会继续在集群中运行。您可以通过将 kube-dns Deployment 和自动扩缩器缩容到零来停用 kube-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
以获取最新版本。
在您的项目中启用 Cloud DNS API。
启用集群范围 DNS
在集群范围 DNS 中,只有在 GKE 集群中运行的节点才能解析服务名称,并且服务名称在集群之间不会冲突。此行为与 GKE 集群中的 kube-dns 相同,这意味着您可以将集群从 kube-dns 迁移到 Cloud DNS 集群范围,而无需停机或更改您的应用。
下图展示了 Cloud DNS 如何为 GKE 集群创建专用 DNS 区域。只有在集群节点上运行的进程和 Pod 才能解析集群的 DNS 记录,因为只有节点位于 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_NAME
:集群的名称。COMPUTE_LOCATION
:集群的 Compute Engine 位置。
--cluster-dns-scope=cluster
标志在命令中是可选的,因为 cluster
是默认值。
控制台
转到 Google Cloud 控制台中的 Google Kubernetes Engine 页面。
点击 add_box 创建。
在导航窗格的集群下,点击网络。
在 DNS 提供商部分,点击 Cloud DNS。
选择集群范围。
根据需要配置集群。
点击创建。
在现有集群中启用集群范围 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
更新现有集群:
gcloud container clusters update CLUSTER_NAME \ --cluster-dns=clouddns \ --cluster-dns-scope=cluster \ --location=COMPUTE_LOCATION
替换以下内容:
CLUSTER_NAME
:集群的名称。COMPUTE_LOCATION
:集群的 Compute Engine 位置。
响应类似于以下示例:
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 解析,除非您升级节点池或向集群添加新的节点池。
升级集群中的节点池以使用 Cloud DNS:
gcloud container clusters upgrade CLUSTER_NAME \ --node-pool=POOL_NAME \ --location=COMPUTE_LOCATION
替换以下内容:
CLUSTER_NAME
:集群的名称。POOL_NAME
:要升级的节点池的名称。
如果节点池和控制平面运行相同的版本,请先升级控制平面(如手动升级控制平面中所述),然后执行节点池升级。
确认响应并为集群中的每个节点池重复此命令。如果集群只有一个节点池,请省略
--node-pool
标志。
控制台
转到 Google Cloud 控制台中的 Google Kubernetes Engine 页面。
点击要修改的集群的名称。
在网络下的 DNS 提供商字段中,点击 edit 修改 DNS 提供商。
点击 Cloud DNS。
点击集群范围。
点击保存更改。
启用 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 进行通信。
当通过 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
更新现有集群:
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 解析。
升级集群中的节点池以使用 Cloud DNS:
gcloud container clusters upgrade CLUSTER_NAME \ --node-pool=POOL_NAME
替换以下内容:
CLUSTER_NAME
:集群的名称。POOL_NAME
:要升级的节点池的名称。
如果节点池和控制平面运行相同的版本,请先升级控制平面(如手动升级控制平面中所述),然后执行节点池升级。
确认响应并为集群中的每个节点池重复此命令。如果集群只有一个节点池,请省略
--node-pool
标志。
控制台
转到 Google Cloud 控制台中的 Google Kubernetes Engine 页面。
点击要修改的集群的名称。
在网络下的 DNS 提供商字段中,点击 edit 修改 DNS 提供商。
点击 Cloud DNS。
点击 VPC 范围。
点击保存更改。
验证 Cloud DNS
验证 Cloud DNS for GKE 是否在集群中正常运行:
通过连接到节点上的 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。将示例应用部署到您的集群:
kubectl run dns-test --image us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0
使用 Service 公开示例应用:
kubectl expose pod dns-test --name dns-test-svc --port 8080
验证 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
。验证您的 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
控制台
转到 Google Cloud 控制台中的 Google Kubernetes Engine 页面。
点击要修改的集群的名称。
在网络下的 DNS 提供商字段中,点击 edit 修改 DNS 提供商。
点击 Kube-dns。
点击保存更改。
停用 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 解析。
清理
完成本页面上的练习后,请按照以下步骤移除资源,防止您的账号产生不必要的费用:
删除服务:
kubectl delete service dns-test-svc
删除 Pod:
kubectl delete Pod dns-test
您还可以删除集群。
将 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 范围的集群,则必须按照以下步骤手动迁移它们:
- 将已启用共享 VPC 的现有集群升级到 GKE 版本 1.22.3-gke.700+ 或 1.21.6-gke.1500+。
- 将响应政策从服务项目迁移到宿主项目。您只需为每个共享 VPC 网络执行一次此迁移。
您可以使用 Google Cloud 控制台迁移响应政策。
在服务项目中执行以下步骤:
转到 Cloud DNS 区域页面。
点击响应政策区域标签页。
点击您的 VPC 网络的响应政策。您可以通过说明识别响应政策,这与“网络 NETWORK_NAME 上的 GKE 集群的响应政策”类似。
点击使用者标签页。
在宿主项目的名称旁边,点击 delete 以移除网络绑定。
点击响应政策规则标签页。
选择表中的所有条目。
点击移除响应政策规则。
点击 delete 删除响应政策。
删除响应政策后,DNS 控制器会自动在宿主项目中创建响应政策。其他服务项目中的集群共享此响应政策。
支持自定义桩网域和上游域名服务器
Cloud DNS for GKE 支持使用 kube-dns ConfigMap 配置的自定义存根网域和上游域名服务器。此支持仅适用于 GKE Standard 集群。
Cloud DNS 会将 stubDomains
和 upstreamNameservers
值转换为 Cloud DNS 转发地区。
已知问题
由于 dns_config
更改,Terraform 计划重新创建 Autopilot 集群
如果使用 terraform-provider-google
或 terraform-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-google
或 terraform-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 查询
通过连接到 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.10
或34.118.224.10
的 IP 地址(仅在 1.27 及更高版本的 GKE Autopilot 集群中),则说明 Pod 使用的是 kube-dns。如果输出为169.254.20.10
,则说明 Pod 使用的是 NodeLocal DNSCache。确认该托管地区存在且包含必要的 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
的专用地区。验证 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
启用 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 查询
通过连接到 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.10
或34.118.224.10
的 IP 地址(仅在 1.27 及更高版本的 GKE Autopilot 集群中),则说明 Pod 使用的是 kube-dns。如果输出为169.254.20.10
,则说明 Pod 使用的是 NodeLocal DNSCache。确认该托管地区存在且包含必要的 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
的专用地区。验证 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
的专用地区。对于 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
的专用地区。对于 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.
后续步骤
- 简要了解 GKE 如何提供托管式 DNS。
- 阅读服务和 Pod 的 DNS,大致了解如何在 Kubernetes 集群中使用 DNS。
- 了解 Cloud DNS 中的范围和层次结构。
- 了解如何为专用代管区域启用和停用日志记录功能。