排查集群的 Cloud NAT 丢包问题

VPC 原生 Google Kubernetes Engine (GKE) 集群中,没有外部 IP 地址的节点可增强安全性。这些节点使用 Cloud NAT 进行出站互联网连接。如果节点虚拟机耗尽其分配的 Cloud NAT 端口和 IP 地址(通常是在出站负载较高的情况下),则可能会发生丢包,从而中断出站流量。

本文档介绍了如何记录和监控丢弃的数据包、调查 Cloud NAT 配置,以及采取措施来减少未来的丢包。

此信息对于负责管理节点不具备互联网访问权限且依靠 Cloud NAT 实现外部连接的 GKE 集群的平台管理员、运维人员和网络管理员非常重要。如需详细了解我们在Google Cloud 内容中提及的常见角色和示例任务,请参阅常见的 GKE 用户角色和任务

诊断丟包问题

以下部分介绍了如何使用 Cloud Logging 记录丢弃的数据包,以及如何使用 Cloud Monitoring 诊断丢弃数据包的原因。

记录丢弃的数据包

您可以使用 Cloud Logging 中的以下查询记录丢弃的数据包:

resource.type="nat_gateway"
resource.labels.region=REGION
resource.labels.gateway_name=GATEWAY_NAME
jsonPayload.allocation_status="DROPPED"

替换以下内容:

  • REGION:集群所在区域的名称。
  • GATEWAY_NAME:Cloud NAT 网关的名称。

此命令会返回 Cloud NAT 网关丢弃的所有数据包的列表,但不会确定原因。

监控丢包的原因

如需确定丢包的原因,请查询 Cloud Monitoring 中的指标观测器。数据包丢失的原因有以下三种:

  • OUT_OF_RESOURCES
  • ENDPOINT_INDEPENDENT_CONFLICT
  • NAT_ALLOCATION_FAILED

如需识别因 OUT_OF_RESOURCESENDPOINT_ALLOCATION_FAILED 错误代码而丢弃的数据包,请使用以下查询:

fetch nat_gateway
  metric 'router.googleapis.com/nat/dropped_sent_packets_count'
  filter (resource.gateway_name == GATEWAY_NAME)
  align rate(1m)
  every 1m
  group_by [metric.reason],
    [value_dropped_sent_packets_count_aggregate:
       aggregate(value.dropped_sent_packets_count)]

如果您发现丢包的原因是上述原因,请参阅丢包的原因是资源不足丢包的原因是端点独立冲突,了解问题排查建议。

如需识别因 NAT_ALLOCATION_FAILED 错误代码而丢弃的数据包,请使用以下查询:

fetch nat_gateway
  metric 'router.googleapis.com/nat/nat_allocation_failed'
  group_by 1m,
    [value_nat_allocation_failed_count_true:
       count_true(value.nat_allocation_failed)]
  every 1m

如果您发现数据包因此原因而丢失,请参阅需要分配更多 IP 地址

调查 Cloud NAT 配置

如果上述查询返回空结果,并且 GKE Pod 无法与外部 IP 地址通信,请使用下表来帮助您排查配置问题:

配置 问题排查
Cloud NAT 配置为仅应用于子网的主要 IP 地址范围。 如果仅针对子网的主 IP 地址范围配置 Cloud NAT,则从集群发送到外部 IP 地址的数据包必须具有来源节点 IP 地址。在此 Cloud NAT 配置中:
  • 如果外部 IP 地址目标受 IP 地址伪装影响,Pod 可以将数据包发送到这些外部 IP 地址。部署 ip-masq-agent 时,请验证 nonMasqueradeCIDRs 列表不包含目标 IP 地址和端口。发送到这些目标位置的数据包首先会转换为来源节点 IP 地址,然后由 Cloud NAT 进行处理。
  • 要允许 Pod 连接到此 Cloud NAT 配置的所有外部 IP 地址,请确保 ip-masq-agent 已部署并且 nonMasqueradeCIDRs 列表仅包含集群的节点和 Pod IP 地址范围。发送到集群外部目标位置的数据包会先转换为来源节点 IP 地址,然后由 Cloud NAT 进行处理。
  • 如要阻止 Pod 向某些外部 IP 地址发送数据包,您需要明确屏蔽这些地址,以免它们被伪装。部署 ip-masq-agent 后,将要屏蔽的外部 IP 地址添加到 nonMasqueradeCIDRs 列表中。发送到这些目标的数据包会带着其原始 Pod IP 地址来源离开节点。Pod IP 地址来自集群子网的次要 IP 地址范围。在此配置中,Cloud NAT 不会对该次要范围进行操作。
Cloud NAT 已配置为仅应用于用于 Pod IP 的子网的次要 IP 地址范围。

如果 Cloud NAT 仅针对集群 Pod IP 使用的子网次要 IP 地址范围进行配置,则从集群发送到外部 IP 地址的数据包必须具有来源 Pod IP 地址。在此 Cloud NAT 配置中:

  • 使用 IP 伪装代理会导致数据包在 Cloud NAT 处理时丢失其来源 Pod IP 地址。如需保留来源 Pod IP 地址,请在 nonMasqueradeCIDRs 列表中指定目标 IP 地址范围。部署 ip-masq-agent 后,发送到 nonMasqueradeCIDRs 列表中目标位置的所有数据包都会保留其来源 Pod IP 地址,然后由 Cloud NAT 进行处理。
  • 如需允许 Pod 连接到此 Cloud NAT 配置的所有外部 IP 地址,请确保 ip-masq-agent 已部署,并且 nonMasqueradeCIDRs 列表尽可能大(0.0.0.0/0 指定所有 IP 地址目的地)。发送到所有目标的数据包在由 Cloud NAT 处理之前会保留来源 Pod IP 地址。

减少丟包

诊断出丢包的原因后,请考虑使用以下建议来降低日后问题再次出现的可能性:

  • 将 Cloud NAT 网关配置为使用动态端口分配,并增加每个虚拟机的端口数上限

  • 如果您使用的是静态端口分配,请增加每个虚拟机的端口数下限

  • 降低应用的出站数据包速率。当应用建立多个与同一目标 IP 地址和端口的出站连接时,它可以使用分配的 NAT 来源地址和来源端口元组的数量快速消耗 Cloud NAT 可以与该目标建立的所有连接。

    如需详细了解 Cloud NAT 如何使用 NAT 来源地址和源端口进行连接,包括对目标的并发连接数限制,请参阅端口和连接

    如需降低应用的出站连接速率,请重复使用打开的连接。重复使用连接的常用方法包括连接池、使用 HTTP/2 等协议进行多路复用连接,或建立用于重复使用多个请求的持久性连接。如需了解详情,请参阅端口和连接

后续步骤