排查 Ingress 健康检查问题


本页介绍了如何解决与 Google Kubernetes Engine (GKE) 中的 Ingress 健康检查相关的问题。

如果您需要其他帮助,请与 Cloud Customer Care 联系。

了解 Ingress 健康检查的运作方式

在继续执行问题排查步骤之前,了解 GKE 中的健康检查工作原理以及确保成功执行健康检查时需要注意的注意事项可能会有所帮助。

当您使用默认 Ingress 控制器通过 Ingress 公开一个或多个 Service 时,GKE 会创建传统应用负载均衡器内部应用负载均衡器。这两种负载平衡器均支持单个网址映射上的多个后端服务。每个后端服务都对应一个 Kubernetes 服务,并且每个后端服务必须引用 Google Cloud 健康检查。此健康检查与 Kubernetes 活跃性探测或就绪性探测不同,因为健康检查在集群外部实现。

负载均衡器健康检查按后端服务来指定。虽然可以对负载均衡器的所有后端服务使用相同的健康检查,但并非为整个负载均衡器(在 Ingress 对象本身中)指定健康检查引用。

GKE 会根据以下方法之一创建健康检查:

  • BackendConfig CRD:一种自定义资源定义 (CRD),可让您精确控制服务与负载均衡器的互动方式。借助 BackendConfig CRD,您可以为与相应后端服务关联的健康检查指定自定义设置。这些自定义设置让您可以更灵活地控制由 Ingress 创建的传统应用负载平衡器和内部应用负载平衡器的健康检查。
  • 就绪性探测:一种诊断检查,用于确定 Pod 中的容器是否已准备好处理流量。GKE Ingress 控制器会根据该 Service 的服务 Pod 所使用的就绪性探测,为该 Service 的后端服务创建健康检查。您可以从就绪性探测定义派生路径、端口和协议等健康检查参数。
  • 默认值:在您未配置 BackendConfig CRD 或为就绪性探测定义属性时使用的参数。
最佳实践

使用 BackendConfig CRD 可对负载均衡器健康检查设置进行最大限度的控制。

GKE 采用以下过程为与 Kubernetes Service 对应的每个后端服务创建健康检查:

  • 如果该 Service 引用包含 healthCheck 信息的 BackendConfig CRD,则 GKE 会使用该 CRD 来创建健康检查。GKE Enterprise Ingress 控制器和 GKE Ingress 控制器都支持以这种方式创建健康检查。

  • 如果该 Service 不引用 BackendConfig CRD:

    • 如果服务 Pod 使用的 Pod 模板具有其就绪性探测特性可解读为健康检查参数的容器,则 GKE 可推断健康检查的部分或全部参数。如需了解实现详情,请参阅来自就绪性探测的参数;如需查看可用于创建健康检查参数的特性列表,请参阅默认参数和推断的参数。只有 GKE Ingress 控制器支持从就绪性探测推断参数。

    • 如果该 Service 的服务 Pod 的 Pod 模板没有其就绪性探测特性可解读为健康检查参数的容器,则使用默认值来创建健康检查。GKE Enterprise Ingress 控制器和 GKE Ingress 控制器都只能使用默认值来创建健康检查。

注意事项

本部分概述了在配置 BackendConfig CRD 或使用准备情况探测时需要注意的一些注意事项。

BackendConfig CRD

配置 BackendConfig CRD 时,请注意以下事项:

  • 如果您使用的是容器原生负载均衡,请确保 BackendConfig 清单中的健康检查端口与服务 Pod 的 containerPort 匹配。
  • 对于实例组后端,请确保 BackendConfig 清单中的健康检查端口与 Service 公开的 nodePort 相匹配。
  • Ingress 不支持自定义健康检查配置的 gRPCBackendConfig 仅支持使用 HTTP、HTTPS 或 HTTP2 协议来创建健康检查。如需了解如何在 BackendConfig CRD 中使用该协议的示例,请参阅 gke-networking-recipes

如需了解详情,请参阅何时使用 BackendConfig CRD

就绪性探测

将 GKE Ingress 与 HTTP 或 HTTPS 负载均衡搭配使用时,GKE 会发送健康检查探测来确定您的应用是否正常运行。只要满足以下条件,这些健康检查探测就会发送到您在 Pod 的 YAML 配置的 spec.containers[].readinessProbe.httpGet.port 部分中定义的 Pod 上的特定端口:

  • spec.containers[].readinessProbe.httpGet.port 中指定的就绪性探测的端口号必须与应用在容器内监听的实际端口(在 Pod 配置的 containers[].spec.ports.containerPort 字段中定义)一致。
  • 服务 Pod 的 containerPort 必须与 Service 的 targetPort 匹配。这样可确保将流量从服务引导到 Pod 上的正确端口。
  • Ingress 服务后端端口规范必须引用 Service 配置的 spec.ports[] 部分中的有效端口。这可以通过以下两种方法完成:
    • Ingress 中的 spec.rules[].http.paths[].backend.service.port.name 与相应 Service 中定义的 spec.ports[].name 匹配。
    • Ingress 中的 spec.rules[].http.paths[].backend.service.port.number 与相应 Service 中定义的 spec.ports[].port 匹配。

排查常见的健康检查问题

请使用以下问题排查流程图来帮助确定任何健康检查问题:

排查 Ingress 健康检查问题。
图: 排查运行状况检查问题

在此流程图中,以下问题排查指南可帮助确定问题所在:

  1. 调查 Pod 运行状况:如果健康检查失败,请检查服务的服务 Pod 的状态。如果 Pod 未运行且运行状况不佳:

    • 检查 Pod 日志,看看是否存在任何错误或问题导致它们无法运行。
    • 检查就绪性探测和活跃性探测的状态。
  2. 健康检查日志记录:确保您已启用健康检查日志记录。

  3. 验证防火墙配置:确保您的防火墙规则允许健康检查探测到达您的 Pod。如果没有解决:

    • 检查您的防火墙规则,确认它们是否允许来自健康检查探测 IP 地址范围的传入流量。
    • 根据需要调整防火墙规则,以适应这些 IP 地址范围。
  4. 分析数据包捕获内容:如果防火墙配置正确,请执行数据包捕获,以查看您的应用是否响应了健康检查。如果数据包捕获显示成功响应,请与Google Cloud 支持团队联系,寻求进一步帮助。

  5. 排查应用问题:如果数据包捕获未显示成功响应,请调查应用未正确响应健康检查请求的原因。验证健康检查是否以 Pod 上的正确路径和端口为目标,并检查应用日志、配置文件和依赖项。如果您找不到错误,请与 Google Cloud 支持团队联系。

应用对健康检查无响应

在对配置的路径和端口进行运行状况检查期间,应用未以预期的状态代码(HTTP 为 200 OK 或 SYN,TCP 为 ACK)进行响应。

如果您的应用未正确响应健康检查,可能是因为以下某种原因:

  • 网络端点组(NEG)
    • 应用在 Pod 中无法正常运行。
    • 应用未在已配置的端口或路径上监听。
    • 存在网络连接问题,导致健康检查无法到达 Pod。
  • 实例组
    • 实例组中的节点运行状况不佳。
    • 应用未在节点上正常运行。
    • 健康检查请求无法到达节点。

如果您的健康检查失败,请根据您的设置按照以下步骤排查问题:

对于 NEG

  1. 使用 kubectl exec 访问 pod:

    kubectl exec -it pod-name -- command
    

    标志 -it 用于提供交互式终端会话(i 表示交互式,t 表示 TTY)。

    替换以下内容:

    • pod-name:您的 pod 的名称。
    • command:您要在 Pod 中运行的命令。最常见的命令是 bashsh,用于获取交互式 shell。
  2. 运行 curl 命令以测试连接性和应用响应能力:

    • curl localhost:<Port>/<Path>
    • curl -v http://<POD_IP>/[Path configured in HC]
    • curl http://localhost/[Path configured in HC]

对于实例组

  1. 确保节点运行状况良好,并响应默认的健康检查探测。
  2. 如果节点正常运行,但应用 Pod 没有响应,请进一步调查应用。
  3. 如果请求无法到达 Pod,则可能存在 GKE 网络问题。请与 Google Cloud 支持团队联系以寻求帮助。

修改 Pod 上的就绪性探测时出错

当您尝试修改 Pod 上的就绪性探测以更改健康检查参数时,会导致类似于以下内容的错误:

Pod "pod-name" is invalid: spec: Forbidden: pod updates may not change fields

如果您修改与已关联到 Ingress(及其相应负载均衡器)的 Service 关联的 Pod 的就绪性探测,GKE 不会自动更新负载均衡器上的健康检查配置。这会导致 Pod 的就绪性检查与负载均衡器的健康检查不一致,从而导致健康检查失败。

如需解决此问题,请重新部署 Pod 和 Ingress 资源。这会强制 GKE 重新创建负载均衡器及其健康检查,并纳入新的准备情况探测设置。

部署和负载均衡器无法启动

如果您的部署无法启动,并且 Ingress 控制器负载平衡器后面的后端服务被标记为健康状况不佳,则可能是就绪情况探测失败所致。

您可能会看到以下提及就绪探测失败的错误消息:

Readiness probe failed: connection refused

Pod 中的应用无法正确响应 Pod 的 YAML 配置中配置的就绪性探测。这可能有多种原因,例如应用未正常启动、监听错误的端口或在初始化期间遇到错误。

如需解决此问题,请执行以下操作,调查并更正应用配置或行为中的任何差异:

  • 确保应用已正确配置,并在就绪性探测参数中指定的路径和端口上响应。
  • 查看应用日志并排查任何启动问题或错误。
  • 验证 Pod 配置中的 containerPort 是否与 Service 中的 targetPort 和 Ingress 中指定的后端端口匹配。

缺少自动入站流量防火墙规则

您创建了 Ingress 资源,但流量无法到达后端服务。

自动 Ingress 防火墙规则(通常由 GKE 在创建 Ingress 资源时创建)缺失或不小心被删除。

如需恢复与后端服务的连接,请执行以下步骤:

  • 验证 VPC 网络中是否存在自动入站防火墙规则。
  • 如果缺少规则,您可以手动重新创建这些规则,也可以删除并重新创建 Ingress 资源以触发自动创建这些规则。
  • 确保防火墙规则允许在 Ingress 资源中定义的相应端口和协议上传输流量。

BackendConfig 清单中使用的协议不正确

如果您使用 TCP 类型的协议配置 BackendConfig CRD,则会看到以下错误:

Error syncing to GCP: error running backend syncing routine:
error ensuring health check: Protocol "TCP" is not valid, must be one of ["HTTP","HTTPS","HTTP2"]'

BackendConfig 仅支持使用 HTTP、HTTPS 或 HTTP/2 协议来创建健康检查。如需了解详情,请参阅 HTTP、HTTPS 和 HTTP/2 成功标准

后续步骤

如需在单个集群中为 Ingress 设置自定义健康检查,请参阅 GKE 网络配置方案