配置 GKE pod 与外部端点的连接

本文档介绍了如何配置从 GKE 中的 Pod 到外部端点(包括本地网络中的资源和公共互联网服务)的连接。如需控制 GKE Pod 流量的来源 IP 地址,您可以同时使用 ip-masq-agent(节点级转换)和 Cloud NAT(VPC 级出站流量)。

概览

当 VPC 原生 GKE 集群中的 Pod 将数据包发送到集群外部的目标时,数据包的来源 IP 地址会根据节点级 IP 伪装代理 (ip-masq-agent) 和 Cloud NAT 的配置方式而变化。

  1. 节点级转换 (ip-masq-agent): 根据配置的 nonMasqueradeCIDRs 列表,将数据包的来源 IP 地址从 Pod IP 地址(次要子网范围)转换为内部 节点 IP 地址(主要子网范围)。
  2. VPC 级网关 (Cloud NAT): 将内部 VPC IP 地址(节点 IP 地址或 Pod IP 地址)转换为静态公共 IP 地址,以允许出站互联网访问。

根据目标是否由节点伪装,数据包离开节点时会使用节点的 IP 地址或 Pod 的 IP 地址。此来源 IP 地址决定了您如何配置您的 Cloud Router 或本地路由器。


IP 伪装和 Cloud NAT 如何协同工作

对于面向互联网的流量,来自 Pod 的数据包会遍历节点网络堆栈和 Cloud NAT 网关。

如果目标 IP 地址与 nonMasqueradeCIDRs 列表中的任何范围都不匹配,则:

  • ip-masq-agent 对 GKE 节点执行来源 NAT (SNAT)。来源 IP 地址从 Pod IP 地址 重写为 节点 IP 地址
  • 数据包进入 VPC 网络,并以节点 IP 地址作为来源。
  • Cloud NAT 网关拦截数据包。
  • Cloud NAT 将节点 IP 地址转换为公共 IP 地址,并将其路由到互联网。

场景 B:保留 Pod IP 地址(无伪装)

如果目标 IP 地址与 nonMasqueradeCIDRs 列表中的某个范围匹配(或者如果默认 SNAT 已停用),则:

  • ip-masq-agent 不会修改数据包。来源 IP 地址仍为 Pod IP 地址
  • 数据包进入 VPC 网络,并以 Pod IP 地址作为来源。
  • Cloud NAT 网关拦截数据包。
  • Cloud NAT 将 Pod IP 地址转换为公共 IP 地址,但前提是 Cloud NAT 明确配置为转换用于 GKE Pod 的子网的次要 IP 地址范围。

IP 伪装检查器

您可以使用此检查器验证目标 IP 地址是否会根据您的 ip-masq-agent 配置进行伪装。


流量流示例

如需了解转换路径,请考虑以下配置示例:

  • Pod IP 地址范围10.4.0.0/14(Pod IP 地址:10.4.0.5
  • 节点 IP 地址范围10.128.0.0/20(节点 IP 地址:10.128.0.10
  • 目标 IP 地址8.8.8.8(公共 DNS 服务器,不在 nonMasqueradeCIDRs 列表中)

当 Pod 发送数据包时,会发生以下情况:

  1. 数据包从 Pod 开始: 数据包源自 Pod 的网络接口(IP 地址:10.4.0.5),目标 IP 地址为 8.8.8.8
  2. 节点级伪装: 由于 8.8.8.8 目标 IP 地址不在 nonMasqueradeCIDRs 列表中,因此主机节点上的 ip-masq-agent 会在数据包离开时拦截该数据包并执行 SNAT。来源 IP 地址从 10.4.0.5 Pod IP 地址重写为主机节点 IP 地址,即 10.128.0.10
  3. VPC 出站流量: 数据包使用 10.128.0.10 主机节点 IP 地址作为来源 IP 地址到达 VPC 网络。
  4. Cloud NAT 网关: 由于目标是公共互联网,因此 Cloud NAT 会处理数据包,将来源 IP 地址从 10.128.0.10 转换为公共 NAT IP 地址(例如 203.0.113.1),并将其转发到互联网。
  5. 响应处理: 响应返回到公共 Cloud NAT IP 地址,Cloud NAT 会将其反向转换为 10.128.0.10 主机节点 IP 地址。然后,节点会将主机节点 IP 地址反向转换为 Pod IP 地址(即 10.4.0.5),并将其传送给 Pod 容器。

使用 Cloud Service Mesh (CSM) 的流量流

如果您的工作负载使用 Cloud Service Mesh,则流量路由行为如下所示:

  • 边车代理或无 Sidecar 的 CNI 重定向:来自应用容器的出站数据包在到达节点的网络命名空间之前,会被网格拦截(通过使用边车代理(如 Envoy)或通过基于 ebpf 的重定向或 CNI 重定向)。
  • 政策应用: 网状网根据其授权和出站流量政策确定是否允许连接。
  • 出站流量路由
    • 如果流量是使用 Cloud Service Mesh 出站流量网关定向的,则离开节点的数据包的来源 IP 地址对应于出站流量网关的节点或 Pod 的 IP 地址,而不是原始 Pod。
    • 如果流量直接路由到外部端点,则数据包会退出代理,并通过标准主机节点网络堆栈进行路由。在这种情况下,本文档前面介绍的 ip-masq-agent 政策和 Cloud NAT 配置仍然适用于出站流量。
  • 如需详细了解如何在 Cloud Service Mesh 中配置路由、网关和管理外部流量,请参阅Cloud Service Mesh 文档

问题排查和隔离连接问题

如果 Pod 无法连接到外部端点,并且您使用的是服务网格,则必须隔离问题是出在服务网格配置还是底层 GKE 路由中。如需隔离问题,请使用以下方法:

  1. 绕过服务网格:在停用 Sidecar 注入的命名空间中部署临时客户端 Pod,或在 Pod 规范中使用 sidecar.istio.io/inject: "false" 注解,以防止为测试工作负载注入。
  2. 测试连接: 尝试从非网格 Pod 连接到外部目标(例如,使用 curlpingnc)。
  3. 分析结果
    • 如果连接成功: 底层 GKE 网络路由、ip-masq-agent 规则和 Cloud NAT 网关配置正确。连接被阻止的原因是 Cloud Service Mesh 政策、缺少出站流量规则或 mTLS 规则。如需详细了解问题排查,请参阅 Cloud Service Mesh 文档中的排查使用 Envoy 的部署的问题
    • 如果连接失败: 问题属于底层网络基础架构(例如 IP 伪装、Cloud Router、Cloud NAT、VPC 防火墙规则或本地防火墙)。请按照此页面中的步骤验证您的路由配置。

使用检查器确定来源 IP 地址范围

在配置路由器或防火墙之前,请使用本文档中的 IP 伪装检查器,并执行以下操作:

  1. ip-masq-agent ConfigMap 的 YAML 内容粘贴到配置字段中。
  2. 输入目标端点(例如本地数据库或外部互联网服务)的目标 IP 地址。
  3. 点击检查伪装
  4. 请注意输出:
    • 已伪装:数据包使用 节点 IP 地址范围 作为来源。
    • 未伪装:数据包使用 Pod IP 地址范围 作为来源。

配置与端点的连接

根据 IP 伪装检查器的结果,按照目标类型配置网络路径和网关。

本地端点(VPN 或互连)

Cloud NAT 不用于本地连接,但您必须根据使用 IP 伪装检查器确定的来源 IP 地址范围配置路由器和防火墙。

如果流量已伪装(来源是节点 IP 地址):

  1. Cloud Router: 确保 Cloud Router 通告包含 GKE 集群子网的 主要 IP 地址范围
  2. 本地路由器或防火墙: 配置本地路由器和防火墙,以允许和处理来自 GKE 节点 IP 地址范围 的入站流量。

如果流量未伪装(来源是 Pod IP 地址):

  1. Cloud Router: 在 Cloud Router 上配置自定义路由通告,以将 GKE Pod 次要 IP 地址范围 通告到本地网络。
  2. 本地路由器或防火墙: 配置本地路由表和防火墙,以允许源自 GKE Pod IP 地址范围 的流量,并确保将返回路由通告回 VPC。

互联网端点 (Cloud NAT)

将流量路由到公共互联网端点时,您必须在 VPC 内配置 Cloud NAT 网关。

  1. 在 Google Cloud 控制台中,前往 Cloud NAT 页面。
  2. 选择或创建 Cloud NAT 网关。
  3. Cloud NAT 来源 下,选择网关处理 GKE 子网范围的方式:
    • 如果流量已伪装(来源是节点 IP 地址): 选择子网的主要 IP 地址范围 。商业 GKE 部署通常默认使用此选项。
    • 如果流量未伪装(来源是 Pod IP 地址): 必须选择主要和次要 IP 地址范围 (或明确指定 GKE Pod 次要范围)。如果您仅选择主要范围,则 GKE Pod 互联网流量将被阻止。