排查配置问题

本指南可帮助您解决 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 映射就会失效 从连接跟踪表中移除 - 所有返回流量都会被舍弃。

在解决入站流量数据包丢弃问题之前,请确认丢弃是否确实影响了 部署应用要进行确认,请在用户数量激增时检查您的应用是否存在错误 被丢弃的入站流量

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

  • 在应用中使用 keepalive 机制,以便设置长时间运行的连接 可以保持营业更长时间
  • 提高 TCP 临时连接空闲超时值 接收流量(由 Google Cloud 资源启动)的外部端点 从而有更多时间进行响应并建立 连接。
  • 如果有 显著降低了默认值。

需要分配更多 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 互动

如果源虚拟机网络接口缺少外部 IP 地址,那么启用公共 NAT 是否可以将流量发送到具有外部 IP 地址的目标虚拟机或负载均衡器,即使来源和目标位于同一 VPC 网络中也是如此?

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

当来源虚拟机将数据包发送到目标时,Public NAT 都会发生 在将数据包传送到第二个实例之前执行来源 NAT (SNAT)。 Public NAT 针对来自第二个 IP 地址的响应执行目标 NAT (DNAT) 复制到第一个实例如需了解分步示例,请参阅 基本 Public NAT 配置和工作流

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

否,专用 NAT 不会对同一虚拟机内虚拟机之间的流量执行 NAT VPC 网络。

不支持垃圾传入连接

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

否,Cloud NAT 不支持垃圾传入连接。如需了解详情,请参阅 Cloud NAT 规范。 但是,如果存在以下情况,Google Cloud 的网络边缘可能会响应 ping: 目标 IP 地址是一个 Cloud NAT 网关外部 IP 地址, 具有活跃端口映射到至少一个虚拟机实例。查看 IP 地址 分配给 Cloud NAT 网关时,请使用 gcloud compute Routerrs 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 访问通道互动

后续步骤