排查配置问题

本指南可帮助您解决 Cloud NAT 的常见问题。

常见问题

虚拟机无需 Cloud NAT 即可意外访问互联网

如果您的虚拟机 (VM) 实例或容器实例无需 Cloud NAT 即可访问互联网,但您不想让它们访问互联网,请检查以下问题:

  • 确定虚拟机的网络接口是否具有外部 IP 地址。如果网络接口分配有外部 IP 地址,Google Cloud 会自动对来源与该接口的主内部 IP 地址匹配的数据包执行一对一 NAT。如需了解详情,请参阅 Cloud NAT 规范

    如需确定虚拟机是否具有外部 IP 地址,请参阅为现有实例更改或分配外部 IP 地址

  • 确保您的 Google Kubernetes Engine (GKE) 集群是一个专用集群。非专用集群中的每个节点虚拟机都具有外部 IP 地址,因此每个节点都可以使用 Virtual Private Cloud (VPC) 网络中下一个跃点为默认互联网网关而不依赖 Cloud NAT 的路由。如需了解详情,包括非专用集群如何与 Cloud NAT 网关互动,请参阅 Compute Engine 互动

  • 列出您的虚拟私有云网络中的路由,查找可通过不同于默认互联网网关的下一个跃点提供互联网连接的路由。例如:

    • 下一个跃点是虚拟机、内部直通式网络负载平衡器或 Cloud VPN 隧道的静态路由可能会间接提供互联网连接。例如,内部直通式网络负载均衡器的下一个跃点虚拟机或后端虚拟机本身可能有外部 IP 地址,或者 Cloud VPN 隧道可能连接到提供互联网访问的网络。

    • Cloud Router 在您的 VPC 网络中通过本地网络获知的动态路由可能会连接到提供互联网访问权限的网络。

  • 请记住,您的 VPC 网络中的其他自定义路由的优先级可能高于其下一个跃点是默认互联网网关的路由。如需了解 Google Cloud 如何评估路由,请参阅路由适用范围和顺序

不会生成任何日志

某些日志会被排除

  • 验证是否启用了 NAT 日志记录,以及您的日志过滤条件是否未排除要保留的日志。您可以清除日志过滤条件,以免排除任何内容。

  • Cloud NAT 不会记录单个事件。如果出站流量庞大,NAT 日志记录会受限,与虚拟机的机器类型成正比。转换或错误日志可能会被舍弃,并且无法确定在限制期间省略的内容。

丢包的原因是资源不足

如果您看到使用 Cloud NAT 的虚拟机造成的数据包丢失,则可能是因为数据包丢失时没有足够的可用 NAT 源 IP 地址和源端口元组供虚拟机使用(端口耗尽)。5 元组(NAT 来源 IP 地址、来源端口和目标 3 元组)不能在 TCP TIME_WAIT 超时内重用。

如果没有足够的 NAT 元组可用,则 dropped_sent_packets_count 原因OUT_OF_RESOURCES。如需详细了解指标,请参阅使用虚拟机实例指标

如需了解如何减少端口用量,请参阅减少端口用量

如果您使用动态端口分配,请参阅以下部分,了解如何在使用动态端口分配时减少丢包问题。

配置动态端口分配时丢弃的包

动态端口分配用于检测某个虚拟机何时即将用尽端口,并将分配给该虚拟机的端口数加倍。这有助于确保端口不会浪费,但在分配的端口数量增加时可能会导致丢包。

如需减少丢包数,请考虑以下事项:

  • 如果您可以缓慢地增加连接数量,Cloud NAT 就有更多的时间来分配更多的端口。

  • 如果虚拟机正在建立 TCP 连接,您可以为虚拟机配置更大的 tcp_syn_retries 值,以便系统有更多时间建立连接,从而提高连接成功的几率。

    例如,对于 Linux 虚拟机,您可以查看当前设置:

      sysctl net.ipv4.tcp_syn_retries
      

    如果需要,您可以增大该设置的值:

      sudo sysctl -w net.ipv4.tcp_syn_retries=NUM
      

  • 如果您有突发性工作负载,并且需要快速分配更多端口,那么您可能需要调整每个虚拟机的端口数下限。查看端口用量相应地确定每个虚拟机的端口数下限

丢包的原因是端点独立冲突

如果您看到来自使用 Public NAT 的虚拟机的丟包,并且已启用端点独立映射,则丟包可能是由端点独立冲突引起的。如果是,则 dropped_sent_packets_count 原因ENDPOINT_INDEPENDENT_CONFLICT。如需详细了解指标,请参阅使用虚拟机实例指标

您可以使用以下方法降低端点独立冲突的可能性:

  • 停用端点独立映射。 这样,来自给定来源 IP 地址和端口的新连接可以使用不同于之前所用的 NAT 来源 IP 地址和端口。停用或启用端点独立映射不会中断已建立的连接。

  • 提高每个虚拟机实例的 NAT 端口的默认数量下限,以便端口预留过程可以将更多 NAT 来源 IP 地址和端口元组分配给每个客户端虚拟机。这样可以降低为以下两个或更多客户端 IP 地址和临时来源端口元组分配相同的 NAT 来源 IP 地址和来源端口元组的可能性。

  • 检查正在使用的临时来源端口的数量:

    • 对于 Linux 虚拟机:

      netstat -an | egrep 'ESTABLISHED|TIME_WAIT|CLOSE_WAIT' | wc -l
      
    • 对于 Windows 虚拟机:

      netstat -tan | findstr "ESTABLISHED TIME_WAIT CLOSE_WAIT" | find /c /v ""
      
  • 将虚拟机实例配置为使用更多临时来源端口:

    • 对于 Linux 虚拟机:

      • 您可使用以下命令查看已配置的端口范围:

        cat /proc/sys/net/ipv4/ip_local_port_range
        
      • 您可以使用以下命令将 ip_local_port_range 设置为临时来源端口数最大值 (64,512):

        echo 1024 65535 > /proc/sys/net/ipv4/ip_local_port_range
        
    • 对于 Windows 虚拟机:

      • 您可使用以下命令查看已配置的端口范围:

        netsh int ipv4 show dynamicport tcp
        netsh int ipv4 show dynamicport udp
        
      • 您可以使用以下命令将临时来源 TCP 和 UDP 端口的数量设置为可能的最大值 (64,512):

        netsh int ipv4 set dynamicport tcp start=1024 num=64512
        netsh int ipv4 set dynamicport udp start=1024 num=64512
        
      • 在 Google Kubernetes Engine 节点上,您可以使用具有特权的 DaemonSet 自动完成此配置。

  • 对于 GKE 集群,请对发送到相关目标的数据包停用在每个节点上执行的来源 NAT。您可以使用以下两种方式之一来执行此操作:

收到后丢弃的数据包

Cloud NAT 网关会维护一个连接跟踪表,用于存储有效连接详细信息以及 IP 地址和端口映射(即虚拟机 IP 地址和端口如何转换为 NAT IP 地址和端口)。如果连接跟踪表不包含任何连接条目,Cloud NAT 网关会丢弃传入数据包。

表中没有连接条目可能由以下任一原因造成:

  • 由于 TCP 已建立的连接空闲超时因处于不活动状态而过期,因此已建立的 TCP 连接超时。
  • 外部端点在 TCP 临时连接空闲超时到期之前未能建立新连接。例如,Google Cloud 资源发起与 TCP SYN 的连接,但外部端点未能使用 SYN ACK 进行响应。
  • 外部端点(例如探测器)尝试连接到 NAT IP 地址和端口。Cloud NAT 不接受未经请求的入站连接。连接表中不会显示这类连接的条目。因此,所有收到的数据包都会被丢弃。
  • 如果您在 NAT 连接仍处于活动状态时从网关中移除 NAT IP,则 NAT 映射会失效,并且这些连接会立即从连接跟踪表中移除,所有返回流量都会被丢弃。

在解决传入数据包丢失问题之前,请确认丢失是否确实会影响您的应用。为确认,请在丢弃的入站数据包数量出现激增时检查应用是否存在错误。

如果入站数据包丢失确实会影响您的应用,请尝试使用以下方法解决此问题:

  • 在应用中使用保持连接机制,以便长时间运行的连接可以保持更长时间的打开状态。
  • 请提高 TCP 暂时性连接空闲超时值,以便通过 Cloud NAT 网关接收流量(由 Google Cloud 资源发起)的外部端点有更多时间响应和建立连接。
  • 如果您大幅降低了默认值,请提高 TCP 既定连接空闲超时的值。

需要分配更多 IP 地址

有时,您的虚拟机会因为您没有足够的 NAT IP 地址而无法访问互联网。有多重因素可能会导致此问题。有关详情,请参阅下表。

根本原因 症状 解决方案
您已手动分配地址,但根据当前端口使用情况,分配的地址还不足够。
  • Google Cloud 控制台会显示一个错误,指示您需要再分配至少“X”个 IP 地址才能使所有实例都能够访问互联网
  • nat_allocation_failed 指标的值为 true

执行下列其中一项操作:

您已经超过了 NAT IP 地址的硬性限制

如需监控因 IP 地址数量不足而导致的失败操作,请为 nat_allocation_failed 指标创建提醒。如果 Google Cloud 无法为 NAT 网关中的任何虚拟机分配足够的 IP 地址,则此指标设置为 true。如需了解提醒政策,请参阅定义提醒政策

减少端口用量

在无法分配或不需要更多 NAT IP 地址的情况下,您可以尽量减少每个虚拟机使用的端口数量。

如需减少端口用量,请完成以下步骤:

  1. 停用端点独立映射

  2. 启用动态端口分配。如需使用动态端口分配,您需要设置每个虚拟机的端口数下限以及每个虚拟机的端口数上限。Cloud NAT 会自动分配数量介于端口数下限与上限(含边界值)之间的 NAT 来源 IP 地址和来源端口元组。如果使用较小的端口数下限值,那么在虚拟机上的活跃连接较少的情况下,可减少浪费的 NAT 来源 IP 地址和来源端口元组。如果在分配端口时遇到连接超时问题,请参阅减少使用动态端口分配时的丢包问题

  3. 确定能够满足您需求的最小端口下限值。有几种方法可用来确定该值,大多数方法的决策过程都需要首先了解已用端口数 (compute.googleapis.com/nat/port_usage)。如需了解如何获取端口用量信息,请参阅查看端口用量。下面是确定端口数下限的两种示例方法:

    • 考虑一组数量具有代表性的虚拟机在具有代表性的一段时长内的 compute.googleapis.com/nat/port_usage 的平均值。
    • 考虑一组数量具有代表性的虚拟机在具有代表性的一段时长内最常出现的 compute.googleapis.com/nat/port_usage 值。
  4. 确定能够满足您需求的最小端口上限值。在该决策过程中,您也需要首先了解 compute.googleapis.com/nat/port_usage。确定端口数上限时,首先考虑一组数量具有代表性的虚拟机在具有代表性的一段时长内 compute.googleapis.com/nat/port_usage 的最大值。请注意,如果将此上限值设置得过高,可能会导致其他虚拟机无法接收 NAT 来源 IP 地址和来源端口元组。

  5. 若要找到适合的端口数下限和上限值,您需要进行迭代测试。如需了解更改端口数下限和上限值的步骤,请参阅如何在配置了动态端口分配时更改端口数下限或上限值

  6. 查看 NAT 超时,了解其含义及其默认值。如果您需要快速建立与同一目标 3 元组的一系列 TCP 连接,不妨考虑缩短 TCP 等待时长,以便 Cloud NAT 能够更快地重用 NAT 来源 IP 地址和来源端口元组。这样 Cloud NAT 便能更快地重用相同的 5 元组,而无需使用具有唯一性的 5 元组,后面这种情况可能需要为每个发送请求的虚拟机分配额外的 NAT 来源 IP 地址和来源端口元组。如需了解更改 NAT 超时的步骤,请参阅更改 NAT 超时

常见问题解答

Cloud NAT 的地区限制

我可以在多个地区中使用同一个 Cloud NAT 网关吗?

不可以。Cloud NAT 网关不能与多个区域、VPC 网络或 Cloud Router 路由器相关联。

如果您需要为其他区域或 VPC 网络提供连接,请为其创建其他 Cloud NAT 网关。

Cloud NAT 网关使用的外部 NAT IP 地址是全球性还是地区性的?

Cloud NAT 网关使用地区性外部 IP 地址作为 NAT IP 地址。即使是地区性的,它们也可公开路由。如需了解可以分配 NAT IP 地址的不同方式,请参阅 NAT IP 地址

当 Cloud NAT 能够使用和不能使用时

Cloud NAT 是否会应用于 GKE 节点虚拟机等具有外部 IP 地址的实例?

通常不会。如果虚拟机的网络接口具有外部 IP 地址,则 Google Cloud 始终对从网络接口的主要内部 IP 地址发送的数据包执行 1 对 1 NAT,而不使用 Cloud NAT。但是,Cloud NAT 仍然可以为通过同一网络接口的别名 IP 地址范围发送的数据包提供 NAT 服务。如需了解更多详情,请参阅 Cloud NAT 规范Compute Engine 互动

公共 NAT 是否允许其网络接口缺少外部 IP 地址的来源虚拟机向具有外部 IP 地址的目标虚拟机或负载均衡器发送流量,即使来源和目标位于同一个 VPC 网络中?

是。网络路径涉及通过默认互联网网关将流量从 VPC 网络发出,然后在同一网络中接收。

当源虚拟机将数据包发送到目标位置时,Public NAT 会在将数据包传送到第二个实例之前执行源 NAT (SNAT)。 Public NAT 会对从第二个实例到第一个实例的响应执行目标 NAT (DNAT)。如需查看分步示例,请参阅基本 Public NAT 配置和工作流

我可以使用 Private NAT 在同一 VPC 网络中的虚拟机之间通信吗?

不会,Private NAT 不会对同一 VPC 网络中的虚拟机之间的流量执行 NAT。

不支持垃圾传入连接

Cloud NAT 是否允许入站连接(例如 SSH)到没有外部 IP 地址的实例?

否,Cloud NAT 不支持垃圾传入连接。如需了解详情,请参阅 Cloud NAT 规范。不过,如果目标 IP 地址是 Cloud NAT 网关外部 IP 地址,并且具有至少一个虚拟机实例的有效端口映射,Google Cloud 的网络边缘可能会响应 ping。如需查看分配给 Cloud NAT 网关的 IP 地址,请使用 gcloud compute routers get-nat-ip-info 命令。标记为 IN_USE 的外部 IP 地址可能会响应 ping。

如果您需要连接到没有外部 IP 地址的虚拟机,请参阅为内部专用的虚拟机选择连接选项。例如,在 Cloud NAT 示例 Compute Engine 设置过程中,您使用 Identity-Aware Proxy 连接到没有外部 IP 地址的虚拟机。

Cloud NAT 和端口

为什么虚拟机拥有固定数量的端口(默认为 64 个)?

Cloud NAT 网关为虚拟机提供 NAT 时,它会根据端口预留程序预留源地址和源端口元组。

如需了解详情,请参阅端口预留示例

我可以更改为虚拟机预留的端口数下限吗?

可以。您可以在创建新的 Cloud NAT 网关时提高或降低每台虚拟机的端口数下限,也可以稍后通过修改此下限来实现此目的。每个 Cloud NAT 网关都会根据端口预留程序预留源地址和源端口元组。

如需详细了解如何降低端口数下限,请参阅下一个问题

创建 Cloud NAT 网关后,我可以减少每台虚拟机的最小端口数吗?

可以;不过,降低最小端口数可能会导致端口预留程序为每台虚拟机预留更少的端口数。发生这种情况时,现有的 TCP 连接可能会被重置,并且必须重新建立连接。

将 NAT 映射从主要和次要范围切换到仅主要范围时,分配给每个实例的其他端口是否会立即释放?

不会。次要范围使用的其他任何端口会由实例保留,直到每个虚拟机的端口数下限设置值减小。当 Cloud NAT 配置为映射子网的次要(别名)范围时,Cloud NAT 会根据端口预留过程为每个实例至少分配 1024 个端口。

通过切换到仅主要范围,Cloud NAT 会保留已分配这些端口的实例的其他已分配端口。更改 Cloud NAT 仅应用于主要范围的范围后,分配给这些实例的实际端口数不会更改,直到每个虚拟机的端口数下限设置值也减小。

如需减小分配给这些实例的端口数量,请在切换到主要范围后,必须减小每个虚拟机的端口数下限设置值。减小该值之后,Cloud NAT 会自动下调每个实例分配的端口数量,从而减少端口消耗。

Cloud NAT 和其他 Google 服务

能否通过 Cloud NAT 访问 Google API 和服务?

当您为子网的主要 IP 范围启用 Cloud NAT 时,Google Cloud 会自动启用专用 Google 访问通道。如需了解详情,请参阅专用 Google 访问通道互动

后续步骤