IP 伪装代理


本页面介绍 IP 伪装功能在 Google Kubernetes Engine (GKE) 中的运作方式,并针对不同场景提供配置选项。

IP 伪装概览

IP 伪装是一种来源网络地址转换 (SNAT) 形式,用于执行多对一 IP 地址转换。GKE 可以使用 IP 伪装来更改从 Pod 发送的数据包的来源 IP 地址。

如需大致了解任何 Kubernetes 实现中的 IP 伪装,请参阅 IP 伪装代理用户指南

GKE IP 伪装

当 IP 伪装适用于 Pod 发出的数据包时,GKE 会将数据包的来源 IP 地址从 Pod IP 地址更改为底层节点的 IP 地址。如果将收件人配置为仅接收来自集群节点 IP 地址的数据包,则伪装数据包的来源 IP 地址会非常有用。

在 Linux 节点上,GKE 会配置 iptables 规则。 GKE 使用 ip-masq-agent DaemonSet 来配置相应的数据平面。

Windows Server 节点池不支持 IP 伪装。

标准集群的 IP 伪装

在标准集群中,集群的 IP 伪装行为受以下三个因素约束:

下表汇总了标准 GKE 集群的 IP 地址伪装配置:

集群配置 产生的 SNAT 行为

集群中存在 ip-masq-agent DaemonSet,并且 ip-masq-agent ConfigMap 中存在自定义 nonMasqueradeCIDRs 列表。

对于发送到 nonMasqueradeCIDRs 列表中指定目标的数据包,GKE 会保留来源 Pod IP 地址。

对于发送到 nonMasqueradeCIDRs 列表中未指定目标的数据包,GKE 会将来源 Pod IP 地址更改为来源节点 IP 地址。

集群中存在 ip-masq-agent DaemonSet,但是 ip-masq-agent ConfigMap 中不存在自定义 nonMasqueradeCIDRs 列表,或者 ip-masq-agent ConfigMap 根本不存在。

对于发送到一组默认非伪装目标的数据包,GKE 会保留来源 Pod IP 地址。

对于发送到默认非伪装目标以外的目标的数据包,GKE 会将来源 Pod IP 地址更改为来源节点 IP 地址。

集群中存在 ip-masq-agent DaemonSet,并且您创建的集群没有 --disable-default-snat 标志。

对于发送到一组默认非伪装目标的数据包,GKE 会保留来源 Pod IP 地址。

对于发送到默认非伪装目标以外的目标的数据包,GKE 会将来源 Pod IP 地址更改为来源节点 IP 地址。

集群中存在 ip-masq-agent DaemonSet,并且您创建的集群具有 --disable-default-snat 标志。

对于发送到所有目标的数据包,GKE 会保留来源 Pod IP 地址。

当您保留 Pod IPv4 源地址并需要将数据包路由到互联网时,请查看将 Pod IPv4 地址来源保留到互联网目标,了解重要的路由注意事项。

Autopilot 集群的 IP 伪装

在 Autopilot 集群中,GKE 会始终部署 ip-masq-agent DaemonSet。除了 Pod 发送到集群的节点、Pod 或 Service 范围的数据包外,您可以使用 EgressNATPolicy 控制 IP 伪装行为。如需使用 EgressNATPolicy,您的 Autopilot 集群必须同时满足以下两个要求:

  • 集群必须使用 GKE 1.23.4-gke.1600 或更高版本,或者 1.22.7-gke.1500 或更高版本。
  • 创建的集群必须已启用 GKE Dataplane V2

下表汇总了 Autopilot GKE 集群的 IP 伪装配置:

Autopilot 集群配置 产生的 SNAT 行为

集群包含一个自定义 EgressNATPolicy,其 spec.actionNoSNAT,其中包含 spec.destinations[] 中指定的非伪装目标。

对于发送到 EgressNATPolicyspec.destinations[] 中指定的目标的数据包,GKE 会保留来源 Pod IP 地址。 GKE 通过将 spec.destinations[] 转换为 ip-masq-agent configMap 中的 nonMasqueradeCIDRs 列表来实现此目的。

对于发送到 EgressNATPolicyspec.destinations[] 中未指定目标的数据包,GKE 会将来源 Pod IP 地址更改为来源节点 IP 地址。

集群不包含自定义 EgressNATPolicy

默认 EgressNATPolicy由 GKE 管理政策均适用,由此会产生以下行为:

  • 对于发送到一组默认非伪装目标的数据包,GKE 会保留来源 Pod IP 地址。
  • 对于发送到默认非伪装目标以外的目标的数据包,GKE 会将来源 Pod IP 地址更改为来源节点 IP 地址。

配置示例

展开下部分即可基于集群类型查看 IP 伪装和配置示例。

高级配置参考

自动部署 ip-masq-agent

在 Autopilot 模式集群中,GKE 会始终部署 ip-masq-agent DaemonSet。

在标准集群中,当 --disable-default-snat 标志未设置且集群使用以下配置组合之一时,GKE 部署 ip-masq-agent DaemonSet:

  • 集群不使用 GKE Dataplane V2,并且启用了网络政策强制执行

  • 集群使用的 Pod IP 地址范围在 10.0.0.0/8 内不适合。

为使 ip-masq-agent DaemonSet 生效,您还必须在 ip-masq-agent ConfigMap 中指定 nonMasqueradeCIDRs 列表。如需了解详情,请参阅如何配置 IP 伪装代理

当集群中存在 ip-masq-agent DaemonSet 时,GKE 会更新并协调集群每个节点上的服务 Pod。

默认非伪装目标

默认非伪装目标如下:

  • 10.0.0.0/8
  • 172.16.0.0/12
  • 192.168.0.0/16
  • 100.64.0.0/10
  • 192.0.0.0/24
  • 192.0.2.0/24
  • 192.88.99.0/24
  • 198.18.0.0/15
  • 198.51.100.0/24
  • 203.0.113.0/24
  • 240.0.0.0/4

默认非伪装目标适用于具有以下配置的集群:

默认非伪装目标不适用于具有以下配置的集群

--disable-default-snat 标志的作用

--disable-default-snat 标志会更改默认 GKE SNAT 行为,以便保留发送到所有目标的数据包的来源 Pod IP 地址。 GKE 通过不在集群中部署任何 ip-masq-agent DaemonSet 来实现默认 SNAT 行为。

如果集群包含 ip-masq-agent DaemonSet,则 --disable-default-snat 标志无效:

  • 由于 Autopilot 集群始终包含 ip-masq-agent DaemonSet,因此 --disable-default-snat 标志对 Autopilot 集群无效。

如需设置 --disable-default-snat 标志,您可以在创建集群后对其进行更新。如果集群未部署 ip-masq-agent DaemonSet,则停用默认 SNAT 会在集群替换其所有节点后生效(有时需要几小时后才生效)。这是因为 GKE 会在替换集群中的节点时遵循您配置的维护窗口。如果您未配置任何维护窗口,则需要手动循环运行集群中的节点,然后 --disable-default-snat 标志才会生效。

链路本地伪装

169.254.0.0/16 范围用于链路本地 IP 地址。链路本地伪装是指将发送到 169.254.0.0/16 目的地的数据包的来源 Pod IP 地址更改为来源节点 IP 地址。

Autopilot 集群始终保留发送到 169.254.0.0/16 目的地的数据包的来源 Pod IP 地址。

默认情况下,Standard 集群也会保留发送到 169.254.0.0/16 目的地的数据包的来源 Pod IP 地址。

您可以通过执行以下两项操作在标准集群中启用链路本地 IP 伪装:

设置了 hostNetwork: true 的诊断容器和 Pod

除非为数据包指定自定义来源 IP 地址,否则使用 hostNetwork: true 和诊断容器运行的 Pod 会发送来源与节点 IP 地址匹配的数据包。对于使用 hostNetwork: true 运行的 Pod,GKE 会为 Pod 分配节点的 IP 地址。GKE 不会管理诊断容器的 IP 地址,包括使用工具箱调试节点问题的容器。

Autopilot 集群不支持使用 spec.hostNetwork: true 运行 Pod。由于无法使用 SSH 访问 Autopilot 集群的节点,因此无法在其上运行诊断容器。

将 Pod IPv4 地址来源保留到互联网目标

如果您的集群的 IP 伪装配置为以下任一项,则对于发送到所有目标(包括互联网目标)的数据包,GKE 都会保留 Pod IP 地址来源:

  • 在具有 ip-masq-agent DaemonSet 的标准集群中,如果您已在 ip-masq-agent ConfigMap 中将 nonMasqueradeCIDRs 设置为 0.0.0.0
  • 在没有 ip-masq-agent DaemonSet 的标准集群中,如果您设置了 --disable-default-snat 标志。
  • 在 Autopilot 集群中,如果您修改默认 EgressNATPolicy,以使 spec.actionNoSNATspec.destinations 包含 Cidr: 0.0.0.0/0

在公共集群和专用集群中,Pod IPv4 来源都是内部 IPv4 地址,这意味着它们无法在互联网上路由。因此,当您保留发送到互联网的数据包的来源 Pod IPv4 地址时,您需要使用以下技术之一,以便在数据包离开集群节点后路由数据包:

  • 确保您的 VPC 网络的默认路由具有默认的互联网网关的下一个跃点,并配置 Cloud NAT 网关,以至少为集群中 Pod 使用的子网次要 IPv4 地址范围提供公共 NAT 服务。如需了解详情,请参阅 Cloud NAT 概览中的 GKE 互动
  • 将 VPC 网络配置为使用自定义默认路由,该路由的下一个跃点是虚拟机实例或内部直通式网络负载均衡器,其中负载均衡器的虚拟机或后端已配置为代表 Pod 将数据包路由到互联网。

恢复默认的 SNAT 行为

如需在集群中存在 ip-masq-agent DaemonSet 时恢复默认 SNAT 行为,请删除关联的 ip-masq-agent ConfigMap。ip-masq-agent DaemonSet 会在其管理的节点上恢复默认的 IP 伪装行为。

如需在集群中不存在 ip-masq-agent DaemonSet 时恢复默认 SNAT 行为,您需要升级节点池(确保未在集群上设置 --disable-default-snat)。

Autopilot 集群中的出站流量 NAT 政策的作用

借助 GKE 出站流量 NAT 政策,您可以在 Autopilot 集群上配置 IP 伪装。您可以使用 GKE 出站流量 NAT 政策的自定义资源定义 (CRD) 来更改从 Pod 发送的数据包的来源 IP 地址。

出于安全性或 IP 地址耗尽等原因,您可以将来自 Pod 的 IP 地址伪装成节点 IP 地址范围,以便将出站流量传送到本地网络。例如,您可以对 Autopilot 集群使用非 RFC-1918 范围,对节点使用 RFC-1918 范围。 但是,如果 Pod 必须与同时使用非 RFC-1918 范围的本地网络通信,那么 IP 地址就可能会重叠。为避免流量丢失,您可以配置出站流量 NAT 政策,以不将 Pod 的非 RFC-1918 范围通告给本地网络。出站流量 NAT 政策会伪装 Pod 的非 RFC-1918 范围,以改用节点的 RFC-1918 范围。确保节点范围不与任何本地范围重叠,否则可能导致流量循环。

GKE 通过以下流程对 Autopilot 集群强制执行 IP 伪装行为:

  1. GKE 部署出站流量 NAT 控制器和 ip-masq-agent
  2. 创建出站流量 NAT 政策。
  3. GKE 控制器将该政策转换为 ip-masq-agent ConfigMap。
  4. ip-masq-agent DaemonSet 读取 ConfigMap,然后 GKE 强制执行 IP 伪装行为。

自动生成的政策

GKE 支持以下两个自动生成的出站流量 NAT 政策:

  • 默认值:这些政策可修改。
  • 由 GKE 管理:这些政策是固定的,不可修改。

默认政策

GKE 预定义了一组默认 IP 地址范围。将数据包发送到这些目标时,您的集群将不会伪装 IP 地址来源,而是会保留来源 Pod IP 地址。如需更改这些默认 IP 地址范围,请参阅修改和部署出站流量 NAT 政策

以下清单描述了一个默认出站流量 NAT 政策:

    Name:         default
    Namespace:
    Labels:       <none>
    Annotations:  <none>
    API Version:  networking.gke.io/v1
    Kind:         EgressNATPolicy
    Metadata:
      Creation Timestamp:  2022-03-16T21:05:45Z
      Generation:          2
      Managed Fields:
        API Version:  networking.gke.io/v1
        Fields Type:  FieldsV1
        fieldsV1:
          f:spec:
            .:
            f:action:
          f:status:
        Manager:      egress-nat-controller
        Operation:    Update
        Time:         2022-03-16T21:05:45Z
        API Version:  networking.gke.io/v1
        Fields Type:  FieldsV1
        fieldsV1:
          f:spec:
            f:destinations:
        Manager:         kubectl
        Operation:       Update
        Time:            2022-03-17T01:58:13Z
      Resource Version:  189346
      UID:               06acbb5a-23ba-4c2a-bb34-9b6ed8c4a87f
    Spec:
      Action:  NoSNAT
      Destinations:
        Cidr:  10.0.0.0/8
        Cidr:  172.16.0.0/12
        Cidr:  192.168.0.0/16
        Cidr:  240.0.0.0/4
        Cidr:  192.0.2.0/24
        Cidr:  198.51.100.0/24
        Cidr:  203.0.113.0/24
        Cidr:  100.64.0.0/10
        Cidr:  198.18.0.0/15
        Cidr:  192.0.0.0/24
        Cidr:  192.88.99.0/24
    Status:
    Events:  <none>

CIDR 范围与默认非伪装目的地范围相同。

由 GKE 管理的政策

GKE 出站流量 NAT 政策会保留您在保留集群操作时所需的静态 IP 地址范围。此静态范围包含集群的 Pod、Service 和节点 IP 地址范围,并且可能与默认政策中的范围重叠。

您可以通过 GKE 分配的动态 8 字节哈希 (gke-{CLUSTER_SHORT_HASH}) 来标识此政策。您无法修改此政策。

以下清单描述了一个名为 gke-bbfa6c0e-1 的由 GKE 管理的政策:

    Name:         gke-bbfa6c0e-1
    Namespace:
    Labels:       <none>
    Annotations:  <none>
    API Version:  networking.gke.io/v1
    Kind:         EgressNATPolicy
    Metadata:
      Creation Timestamp:  2022-03-16T21:05:46Z
      Generation:          1
      Managed Fields:
        API Version:  networking.gke.io/v1
        Fields Type:  FieldsV1
        fieldsV1:
          f:spec:
            .:
            f:action:
            f:destinations:
          f:status:
        Manager:         egress-nat-controller
        Operation:       Update
        Time:            2022-03-16T21:05:46Z
      Resource Version:  11699
      UID:               0201b5de-a6f6-4926-822b-31ed7cdee2c6
    Spec:
      Action:  NoSNAT
      Destinations:
        Cidr:  10.119.128.0/17
        Cidr:  10.120.0.0/22
        Cidr:  10.128.0.0/20
    Status:
    Events:  <none>

后续步骤