本文档介绍了 Google Kubernetes Engine (GKE) 中的服务发现如何简化应用管理,以及如何使用 Cloud DNS 范围、多集群服务 (MCS) 和 Service Directory 将服务发现扩展到单个集群之外。
本文档适用于 GKE 用户、开发者、管理员和架构师。如需详细了解我们在 Google Cloud 内容中提及的常见角色和示例任务,请参阅常见的 GKE Enterprise 用户角色和任务。
在阅读本文档之前,请确保您了解以下概念:
概览
服务发现是一种机制,可让服务和应用动态查找彼此并进行通信,而无需对 IP 地址或端点配置进行硬编码。服务发现有助于确保应用始终可以访问最新的 Pod IP 地址,即使在重新调度 Pod 或添加新 Pod 时也是如此。GKE 提供了多种实现服务发现的方法,包括 kube-dns、自定义 kube-dns 部署和 Cloud DNS。您可以使用 NodeLocal
DNSCache 进一步优化 DNS 性能。
服务发现的优势
服务发现有以下优势:
- 简化应用管理:服务发现功能可让您无需在应用配置中对 IP 地址进行硬编码。应用通过使用逻辑服务名称进行通信,这些名称会自动解析为正确的 Pod IP 地址。这种方法可简化配置,尤其是在 Pod IP 地址可能会因扩缩或重新调度而发生变化的动态环境中。
- 简化了扩缩和弹性机制:服务发现通过将服务使用方与经常更改的 Pod IP 地址分离,简化了扩缩。当您的应用扩缩时,或者当 Pod 发生故障并被替换时,Kubernetes 会自动更新哪些 Pod 可用于接收给定服务的流量。服务发现有助于确保对稳定服务名称的请求仅定向到运行正常的 Pod,从而让您的应用在无需人工干预或重新配置客户端的情况下进行扩缩或从故障中恢复。
- 高可用性:GKE 将负载均衡与服务发现功能结合使用,有助于确保应用的高可用性并提高应用的响应速度,即使在重负载下也是如此。
使用服务发现进行负载均衡
GKE 通过将不同级别的负载均衡与服务发现相结合,有助于确保应用的高可用性。
- 内部服务:对于只能在集群内访问的服务,GKE 的数据平面(
kube-proxy或Cilium)充当负载均衡器。它会在多个运行正常的 Pod 之间均匀分配传入流量,防止过载并有助于确保高可用性。 - 外部服务:对于需要从集群外部访问的服务,GKE 会预配 Google Cloud 负载均衡器。这些负载均衡器包括用于公开互联网访问的外部 Google Cloud 负载均衡器,以及用于在虚拟私有云网络内访问的内部 Google Cloud 负载均衡器。这些负载均衡器会在集群中的节点之间分配流量。然后,每个节点上的数据平面会将流量进一步路由到相应的 Pod。
在内部和外部场景中,服务发现都会持续更新每个服务的可用 Pod 列表。这种持续更新有助于确保数据平面(对于内部服务)和 Google Cloud 负载均衡器(对于外部服务)仅将流量导向健康实例。
服务发现的应用场景
以下是服务发现的常见应用场景:
- 微服务架构:在微服务架构中,应用通常由许多需要相互交互的较小独立服务组成。服务发现功能可让这些应用相互查找并交换信息,即使在集群扩缩时也是如此。
- 实现零停机时间部署并提高弹性:服务发现有助于实现应用零停机时间更新,包括受控发布和 Canary 部署。它会自动发现新服务版本并将流量转移到这些版本,从而有助于减少部署期间的停机时间,并确保用户顺利过渡。服务发现还可以提高弹性。当 GKE 中的 Pod 发生故障时,系统会部署新的 Pod,并且服务发现功能会注册新的 Pod 并将流量重定向到该 Pod,从而有助于最大限度地减少应用停机时间。
服务发现的运作方式
在 GKE 中,应用通常由多个需要相互查找和通信的 Pod 组成。服务发现通过使用域名系统 (DNS) 提供此功能。与您使用 DNS 在互联网上查找网站的方式类似,GKE 集群中的 Pod 使用 DNS 通过服务名称查找服务并与之连接。借助这种方法,无论 Pod 在集群中的哪个位置运行,都可以有效地进行交互,并且应用可以通过使用一致的服务名称(而不是不稳定的 IP 地址)进行通信。
Pod 如何执行 DNS 解析
GKE 集群中的 Pod 通过结合使用自动生成的 DNS 记录及其本地 DNS 配置来解析服务和其他 Pod 的 DNS 名称。
服务 DNS 名称
创建 Kubernetes 服务时,GKE 会自动为其分配 DNS 名称。此名称遵循可预测的格式,集群中的任何 Pod 都可以使用该名称来访问服务:
<service-name>.<namespace>.svc.cluster.local
默认集群网域为 cluster.local,但您可以在创建集群时自定义网域。例如,默认命名空间中名为 my-web-app 的服务将具有 DNS 名称 my-web-app.default.svc.cluster.local。
/etc/resolv.conf 的作用
为了解析这些 DNS 名称,Pod 依赖于其 /etc/resolv.conf 文件。此配置文件会告知 Pod 将其 DNS 查询发送到哪个域名服务器。此文件中列出的域名服务器的 IP 地址取决于您的 GKE 集群上启用的特定 DNS 功能。下表列出了 Pod 根据您的配置使用的域名服务器 IP:
| Cloud DNS for GKE | NodeLocal DNSCache | “/etc/resolv.conf”域名服务器值 |
|---|---|---|
| 已启用 | 已启用 | “169.254.20.10” |
| 已启用 | 已停用 | “169.254.169.254” |
| 已停用 | 已启用 | “kube-dns”服务 IP 地址 |
| 已停用 | 已停用 | “kube-dns”服务 IP 地址 |
此配置有助于确保来自 Pod 的 DNS 查询被定向到正确的组件:
- NodeLocal DNSCache:在节点上提供快速的本地查找。
- 元数据服务器 IP (
169.254.169.254):在启用 Cloud DNS for GKE 但未启用 NodeLocal DNSCache 时使用。DNS 查询会定向到此 IP 地址,Cloud DNS 会使用此地址来拦截和处理 DNS 请求。 kube-dns服务 IP 地址:当 Cloud DNS for GKE 处于停用状态时,用于标准集群内解析。
GKE 中的 DNS 架构
GKE 提供灵活的服务发现架构,主要通过 DNS 实现。以下组件可协同工作,以解析集群中的 DNS 查询:
kube-dns:GKE Standard 集群的默认集群内 DNS 提供商。它以 Pod 的受管部署形式在kube-system命名空间中运行,并监控 Kubernetes API 以发现新服务,从而创建必要的 DNS 记录。- Cloud DNS: Google Cloud的全托管式 DNS 服务。它提供了一种高度可扩缩且可靠的
kube-dns替代方案,并且是 GKE Autopilot 集群的默认 DNS 提供商。 NodeLocal DNSCache:一种可提高 DNS 查找性能的 GKE 插件。它会在集群中的每个节点上运行 DNS 缓存,与kube-dns或 Cloud DNS 搭配使用,以在本地处理 DNS 查询,从而缩短延迟时间并减轻集群中央 DNS 提供商的负载。对于 GKE Autopilot 集群,NodeLocal DNSCache默认处于启用状态,且不能替换。- 自定义
kube-dns部署:一种允许您部署和管理自己的kube-dns实例的部署,可让您更好地控制kube-dns配置和资源。
选择 DNS 提供商
下表总结了 GKE 中可用的 DNS 提供商,包括其特性以及每个提供商适用的场景:
| 提供商 | 特性 | 适用的场景 |
|---|---|---|
| “kube-dns” | 集群内服务和 Pod 的 DNS 解析。 | 所有具有标准网络需求的集群。新版“kube-dns”适用于小型和大型集群。 |
| Cloud DNS | 高级 DNS 功能(专用区域、流量导向、全球负载均衡),以及与其他 Google Cloud 服务的集成。 | 外部公开服务、多集群环境或具有高 DNS 查询速率 (QPS) 的集群。 |
| 自定义“kube-dns”部署 | 可对配置、资源分配进行额外控制,并可使用其他 DNS 提供商。 | 满足大规模集群或需要更积极的扩缩或对资源分配进行精细控制的特定 DNS 需求。 |
单个集群之外的服务发现
您可以使用以下方法将服务发现范围扩展到单个 GKE 集群之外:
Cloud DNS 范围
使用 Cloud DNS 进行集群 DNS 解析的集群可以在以下三种可用范围中运行:
- 集群范围:这是 Cloud DNS 的默认行为。在此模式下,Cloud DNS 的功能等同于
kube-dns,专门为集群内的资源提供 DNS 解析。DNS 记录只能从集群内部解析,并且遵循标准 Kubernetes 服务架构:<svc>.<ns>.svc.cluster.local。 - 附加 VPC 范围:此可选功能可扩展集群范围,从而可从同一 VPC 网络中的其他资源(例如 Compute Engine 虚拟机,或是使用 Cloud VPN 或 Cloud Interconnect 连接的本地客户端)解析无头 Service。
- VPC 范围:采用此配置后,集群服务的 DNS 记录可在整个 VPC 网络内进行解析。这种方法意味着,任何位于同一 VPC 中或连接到该 VPC(通过 Cloud VPN 或 Cloud Interconnect)的客户端都可以直接解析服务名称。
如需详细了解 VPC 范围 DNS,请参阅使用 Cloud DNS for GKE。
多集群 Service
多集群服务 (MCS) 可在多个 GKE 集群中实现服务发现和流量管理。借助 MCS,您可以构建跨集群的应用,同时保持统一的服务体验。
MCS 利用基于 DNS 的服务发现来连接跨集群的服务。创建 MCS 实例时,系统会生成格式为 <svc>.<ns>.svc.clusterset.local 的 DNS 记录。这些记录会解析为每个参与集群中服务端点的 IP 地址。
当一个集群中的客户端访问 MCS 时,请求会路由到任何参与集群中最近的可用端点。此流量分配由每个节点上的 kube-proxy(或 GKE Dataplane V2 中的 Cilium)管理,有助于确保集群之间的高效通信和负载均衡。
Service Directory for GKE
Service Directory for GKE 提供了一个统一的注册表,用于在 Kubernetes 和非 Kubernetes 部署中发现服务。Service Directory 可以在单个注册表中同时注册 GKE 和非 GKE 服务。
在以下情况下,Service Directory 特别有用:
- 您需要 Kubernetes 和非 Kubernetes 应用的单个注册表,用于相互发现。
- 您需要托管式服务发现工具。
- 能够存储有关您服务的元数据,以便其他客户端可以访问。
- 能够按服务级别设置访问权限。 Service Directory 服务可以通过 DNS、HTTP 和 gRPC 进行解析。Service Directory 与 Cloud DNS 集成,可以填充与 Service Directory 中的服务匹配的 Cloud DNS 记录。
如需了解详情,请参阅为 GKE 配置 Service Directory。
优化 DNS 性能和最佳实践
为确保可靠高效的服务发现,尤其是在大规模或高流量集群中,请考虑以下最佳实践和优化策略。
使用 NodeLocal DNSCache 优化性能
对于 Pod 密度较高的集群或生成大量 DNS 查询的应用,您可以通过启用 NodeLocal DNSCache 来提高 DNS 查找速度。NodeLocal DNSCache 是一种 GKE 插件,可在集群中的每个节点上运行 DNS 缓存。当 Pod 发出 DNS 请求时,该请求会转到同一节点上的缓存。这种方法可缩短延迟时间并减少网络流量。
如需详细了解如何启用和配置此功能,请参阅设置 NodeLocal DNSCache。
扩容您的 DNS 提供商
如果您使用 kube-dns 并且遇到间歇性超时,尤其是在流量高峰期,您可能需要扩容 kube-dns 副本的数量。kube-dns-autoscaler 会根据集群中的节点数和核心数调整副本数,并且可以调整其参数以更快地部署更多副本。
如需详细说明,请参阅扩容 kube-dns。
一般最佳实践
- 选择合适的 DNS 提供商:根据集群的需求选择 DNS 提供商。建议将 Cloud DNS 用于高 QPS 工作负载、多集群环境,以及当您需要与更广泛的 VPC 网络集成时。新版
kube-dns适用于各种规模的集群,可满足集群内标准服务发现需求。 - 避免将 Spot 虚拟机或抢占式虚拟机用于
kube-dns:通过不在 Spot 虚拟机或抢占式虚拟机上运行kube-dns等关键系统组件,帮助确保集群 DNS 服务的稳定性。意外的节点终止可能会导致 DNS 解析问题。 - 使用清晰的描述性服务名称:为服务采用一致且有意义的命名惯例,使应用配置更易于阅读和维护。
- 使用命名空间进行整理:使用 Kubernetes 命名空间对相关服务进行分组。这种方法有助于防止命名冲突,并改进集群资源组织。
- 监控和验证 DNS:定期监控 DNS 指标和日志,以便在潜在问题影响应用之前发现它们。定期从 Pod 内部测试 DNS 解析,以确保服务发现功能正常运行。
后续步骤
- 阅读 GKE 中的集群 DNS 概览。
- 阅读服务和 Pod 的 DNS,大致了解如何在 Kubernetes 集群中使用 DNS。
- 了解如何设置 NodeLocal DNSCache。
- 了解如何设置自定义
kube-dns部署。