配置出站流量 NAT 网关

本文档介绍了如何为 Google Distributed Cloud 设置出站流量 NAT 网关。此网关为集群的出站流量持续提供确定性 SNAT IP 地址。当您运行具有出站用户流量的工作负载(在集群外部)时,您的客户需要使用一些确定性 IP 地址来识别此流量。这样,他们就可以制定基于 IP 地址的安全措施,如列入许可名单政策。

本页面适用于为组织设计和架构网络以及安装、配置和支持网络设备的网络专家。如需详细了解我们在 Google Cloud 内容中提及的常见角色和示例任务,请参阅常见的 GKE 用户角色和任务

可使用两个自定义资源来启用出站流量 NAT 网关。对于给定的命名空间,NetworkGatewayGroup 自定义资源会指定浮动 IP 地址,可以在选择用作网关的节点的网络接口上配置该地址。借助 EgressNatPolicy 自定义资源,您可以指定出站流量路由政策以控制出站流量网关上的流量。

如果您未设置出站流量 NAT 网关,或者出站流量不符合流量选择规则,则从给定 Pod 到集群外部某个目的地的出站流量会被伪装成运行该 Pod 的节点的 IP 地址。在这种情况下,无法保证来自特定 Pod 的所有出站流量都具有相同的来源 IP 地址或都伪装成同一节点的 IP 地址。

出站流量 NAT 网关是在 Dataplane V2 基础上构建的高级网络产品。

出站流量 NAT 网关的工作原理

出站流量选择逻辑基于命名空间选择器、Pod 选择器和一组目的地 IP 地址范围(采用 CIDR 地址块表示法)。为了说明出站流量 NAT 网关的工作原理,我们来看一个从 Pod 到外部使用方的数据包流及相应的响应情况。假设节点子网具有 192.168.1.0/24 CIDR 地址块中的 IP 地址。

下图展示了通过网关节点的出站流量的网络架构。

Google Distributed Cloud 的出站流量 NAT 网关示意图

通过出站流量 NAT 网关的数据包流可能如下所示:

  1. 出站流量由 IP 地址为 192.168.1.1 的节点中的 IP 地址为 10.10.10.1 的 Pod 生成。

    流量的目标地址是集群外部的端点。

  2. 如果流量与出站流量规则匹配,则 eBPF 程序会将出站流量路由到网关节点,而不是直接伪装成节点 IP 地址。

  3. 网关节点将接收出站流量。

  4. 网关节点将原始流量的来源 IP 地址 10.10.10.1 伪装成 EgressNATPolicy 自定义资源中指定的来源出站流量 IP 地址 192.168.1.100

  5. 返回流量将会返回到目的地为 192.168.1.100 的网关节点。

  6. 网关节点会将返回流量的 conntrack 与原始出站流量的 conntrack 进行匹配,并将目的地 IP 地址重写为 10.10.10.1

  7. 10.10.10.1 被视为集群内流量,将路由到原始节点并传送回原始 Pod。

为节点流量配置浮动 IP 地址

网络网关组自定义资源是 Google Distributed Cloud 的捆绑组件。该资源管理一个或多个浮动 IP 地址的列表,这些地址将用于来自集群中节点的出站流量。参与节点由指定的命名空间决定。网络网关组会始终尽力提供浮动 IP 地址。如果使用浮动 IP 地址的节点发生故障,则高级网络操作器会将分配的 IP 地址移至下一个可用节点。使用该 IP 地址的所有工作负载出站流量也将随之迁移。

在创建新的 1.34.0-gke.566 版集群时,请在集群配置文件中添加网络网关组详细信息(注解和规范)。

创建 NetworkGatewayGroup 自定义资源

创建集群时,请通过在集群配置文件中将 spec.clusterNetwork.advancedNetworking 字段设置为 true 来启用网络网关组,如以下示例所示:

apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
  name: cluster1
  namespace: cluster-cluster1
spec:
  clusterNetwork:
    ...
    advancedNetworking: true
    ...

创建 NetworkGatewayGroup 自定义资源时,请将其命名空间设置为集群命名空间并指定浮动 IP 地址列表,如以下示例所示:

kind: NetworkGatewayGroup
apiVersion: networking.gke.io/v1
metadata:
  namespace: cluster-cluster1
  name: default
spec:
  floatingIPs:
  - 192.168.1.100
  - 192.168.1.101
  - 192.168.1.102

高级网络操作器根据以下条件将浮动 IP 分配给节点:

  • 节点子网:浮动 IP 地址必须与节点子网匹配。
  • 节点角色(控制平面、工作器):在分配浮动 IP 地址时,工作器节点优先于控制平面节点。
  • 节点是否具有浮动 IP 地址:操作器会优先为尚未分配浮动 IP 地址的节点进行分配。

您可以在获取 NetworkGatewayGroup 对象时在 status 部分找到地址与节点的映射。请注意,NetworkGatewayGroup 对象位于 kube-system 命名空间中。如果网关节点关闭,高级网络操作器会将浮动 IP 地址分配给下一个可用节点。

验证网关配置

应用网关配置更改后,您可以使用 kubectl 检查网关的状态,以及检索为网关指定的浮动 IP 地址。

  1. 使用以下命令检查 NetworkGatewayGroup 的状态并查看浮动 IP 地址的分配方式:

    kubectl -n kube-system get networkgatewaygroups.networking.gke.io default -o yaml

    具有两个节点(worker1worker2)的集群的响应可能如下所示:

    kind: NetworkGatewayGroup
    apiVersion: networking.gke.io/v1
    metadata:
      namespace: kube-system
      name: default
    spec:
      floatingIPs:
      - 192.168.1.100
      - 192.168.1.101
      - 192.168.1.102
    status:
      nodes:
        worker1: Up
        worker2: Up // Or Down
      floatingIPs:
        192.168.1.100: worker1
        192.168.1.101: worker2
        192.168.1.102: worker1
    

设置流量选择规则

EgressNATPolicy 自定义资源指定流量选择规则,并为离开集群的出站流量分配确定性 IP 地址。指定自定义资源时,egress(至少具有一条规则)、destinationCIDRsegressSourceIP 全部都需要提供。

使用 kubectl apply 来创建 EgressNATPolicy 自定义资源。以下部分提供了定义规范的详细信息和示例。

指定出站流量路由规则

通过 EgressNatPolicy 自定义资源,您可以为出站流量指定以下规则:

  • 您必须在 egress 部分中指定一个或多个出站流量选择规则。

    • 每个规则均由 podSelectornamespaceSelector 组成。
    • 该选择基于命名空间标签 namespaceSelector.matchLabels.user 和 Pod 标签 podSelector.matchLabels.role
    • 如果 Pod 与任意规则匹配(匹配使用 OR 关系),则会为出站流量选择该 Pod。
  • destinationCIDRs 部分中指定允许的目标地址。

    • destinationCIDRs 使用 CIDR 地址块列表。
    • 如果来自 Pod 的传出流量的目标 IP 地址属于任何指定的 CIDR 地址块范围内,则会为出站流量选择该 Pod。

在以下示例中,如果满足以下条件,则允许来自 Pod 的出站流量:

  • Pod 带有 role: frontend 标签。
  • Pod 位于标记为 user: aliceuser: paul 的命名空间中。
  • Pod 正在与 8.8.8.0/24 CIDR 地址块中的 IP 地址通信。
kind: EgressNATPolicy
apiVersion: networking.gke.io/v1
metadata:
  name: egress
spec:
  sources:
  - namespaceSelector:
      matchLabels:
        user: alice
    podSelector:
      matchLabels:
        role: frontend
  - namespaceSelector:
      matchLabels:
        user: paul
    podSelector:
      matchLabels:
        role: frontend
  action: SNAT
  destinations:
    - cidr: 8.8.8.0/24
  gatewayRef:
    name: default
    namespace: kube-system

如需详细了解如何使用标签,请参阅 Kubernetes 文档中的标签和选择器

获取出站流量的来源 IP 地址

EgressNATPolicy 自定义资源(政策)使用 gatewayRef.namegatewayRef.namespace 值查找 NetworkGatewayGroup 对象(网关)。该政策使用网关的浮动 IP 地址作为出站流量的源 IP 地址。如果匹配网关中有多个浮动 IP 地址,则政策会使用 floatingIPs 列表中的第一个 IP 地址,并忽略任何其他 IP 地址。对于示例网关floatingIPs 列表中的第一个地址为 192.168.1.100gatewayRef 部分中存在无效字段或值会导致应用政策对象失败。

多个出站流量政策和多个网关对象

如上一节中所述,每个 egressNATPolicy 对象(政策)都使用与 gatewayRef.namegatewayRef.namespace 匹配的网关对象的 floatingIPs 列表中的第一个 IP 地址。您可以创建多个政策,并且如果您打算使用不同的 IP 地址,则需要创建多个 NetworkGatewayGroup 对象并分别引用它们。

每个 NetworkGatewayGroup 资源必须包含唯一的浮动 IP 地址。如需将多个 EgressNATPolicy 对象配置为使用同一 IP 地址,请对这些对象使用相同的 gatewayRef.namegatewayRef.namespace

如需设置多个出站流量政策和多个网关对象,请执行以下操作:

  1. kube-system 命名空间中创建网关对象以管理每个浮动 IP 地址。通常,每个出站流量政策都应具有相应的网关对象,以确保分配正确的 IP 地址。

    然后,使用 kubectl 验证每个网关对象,以获取浮动 IP 地址的分配状态:

    kind: NetworkGatewayGroup
    apiVersion: networking.gke.io/v1
    metadata:
      namespace: kube-system
      name: gateway1
    spec:
      floatingIPs:
      - 192.168.1.100
    status:
      ...
      floatingIPs:
        192.168.1.100: worker1
    ---
    kind: NetworkGatewayGroup
    apiVersion: networking.gke.io/v1
    metadata:
      namespace: kube-system
      name: gateway2
    spec:
      floatingIPs:
      - 192.168.1.101
    status:
      ...
      floatingIPs:
        192.168.1.101: worker2
    ---
    kind: NetworkGatewayGroup
    apiVersion: networking.gke.io/v1
    metadata:
      namespace: kube-system
      name: gateway3
    spec:
      floatingIPs:
      - 192.168.1.102
    status:
      ...
      floatingIPs:
        192.168.1.102: worker1
    
  2. 创建多个引用网关对象的政策,例如在上一步中创建的 gateway1

    kind: EgressNATPolicy
    apiVersion: networking.gke.io/v1
    metadata:
      name: egress1
    spec:
      ...
      gatewayRef:
        name: gateway1
        namespace: kube-system
    ---
    kind: EgressNATPolicy
    apiVersion: networking.gke.io/v1
    metadata:
      name: egress2
    spec:
      ...
      gatewayRef:
        name: gateway2
        namespace: kube-system
    ---
    kind: EgressNATPolicy
    apiVersion: networking.gke.io/v1
    metadata:
      name: egress3
    spec:
      ...
      gatewayRef:
        name: gateway3
        namespace: kube-system
    

(可选)指定要放置浮动 IP 地址的节点

NetworkGatewayGroup 资源支持节点选择器。如需指定用于托管浮动 IP 地址的节点子集,您可以将节点选择器添加到 NetworkGatewayGroup 对象,如以下示例所示:

kind: NetworkGatewayGroup
apiVersion: networking.gke.io/v1
metadata:
  namespace: cluster-cluster1
  name: default
spec:
  floatingIPs:
  - 192.168.1.100
  - 192.168.1.101
  - 192.168.1.102
  nodeSelector:
    node-type: "egressNat"

节点选择器会与具有指定标签的节点匹配,并且系统仅会考虑将浮动 IP 地址托管到这些节点。如果您指定了多个选择器,则其逻辑是可叠加的,因此节点必须与每个标签匹配,才能被考虑用于托管浮动 IP 地址。如果没有太多具有匹配标签的节点,节点选择器可能会降低浮动 IP 地址放置的高可用性 (HA) 质量。

高可用性出站 NAT 网关的快速故障切换

对于 1.34 及更高版本的集群,您可以配置具有快速故障切换的出站 NAT 网关。当您有多个浮动 IP 地址并配置快速故障切换时,可实现高可用性出站流量。此功能可更好地分配出站流量,并更快地进行故障切换,从而最大限度地减少停机时间。集群不会一次依赖单个网关节点(主/备),而是将出站流量分配到 NetworkGatewayGroup 资源中的多个网关节点和所有已配置的浮动 IP 地址。

这种主动-主动模型具有以下主要优势:

  • 负载分配:来自不同源端点(例如 Pod)的出站流量会分布在所有可用的网关节点上,从而减少任何单个节点上的负载并增加总可用出站带宽。

  • 快速故障切换:如果出口网关节点发生故障,流量会自动重定向到其余健康状况良好的节点。目标是实现流量快速故障切换。当故障节点上的现有连接断开时,新连接会立即通过其他网关建立,从而最大限度地减少停机时间。

主要区别

配置出站 NAT 网关以实现快速故障切换会改变出站 NAT 网关的运行方式:

能力 主备(默认) 主动/主动(快速故障切换)
浮动 IP 使用情况 EgressNATPolicy 仅使用 NetworkGatewayGroup 中的第一个浮动 IP 地址。 NetworkGatewayGroup 中列出的所有浮动 IP 地址都会主动分配出站流量。
故障切换 如果网关节点发生故障,同一浮动 IP 地址会移至其他节点,这可能会导致流量中断。 如果网关节点发生故障,流量会重定向到另一个节点上的其他正常 IP 地址。新连接会立即通过运行正常的网关路由,而故障节点上的现有有状态连接会终止。
流量 指定政策的所有流量都通过单个网关节点。 流量会根据源端点(例如 Pod)的一致哈希在多个网关节点之间分配。

配置快速故障切换

配置此功能主要涉及两个步骤:

  1. 指定多个浮动 IP 地址。

    使用至少包含两个浮动 IP 地址的池配置 NetworkGatewayGroup,以实现高可用性和负载分配的优势。使用更多浮动 IP 地址可提高出站可靠性和吞吐量。

    以下是一个配置示例:

    apiVersion: networking.gke.io/v1
    kind: NetworkGatewayGroup
    metadata:
      name: egress-gateways
      namespace: cluster-admin
    spec:
      nodeSelector:
        # Selects nodes that are designated as egress gateways
        node-role.kubernetes.io/egress: ""
      floatingIPs:
      - "192.168.1.100"
      - "192.168.1.101"
      - "192.168.1.102"
    
  2. 如需启用快速故障切换,请将 networking.gke.io/egressnat-ha: "enable" 注解添加到 EgressNATPolicy 自定义资源:

    kind: EgressNATPolicy
    apiVersion: networking.gke.io/v1
    metadata:
      name: egress
      annotations:
        networking.gke.io/egressnat-ha: "enable"
    spec:
      ...
    

出站流量选择规则和网络政策

出站流量 NAT 网关与网络政策 API 兼容。网络政策将首先进行评估,并且优先于出站流量 NAT 网关的流量选择规则。例如,如果出站流量触发了一项网络政策,导致数据包被丢弃,则出站流量网关规则将不会检查数据包。仅当网络政策允许数据包出站时,系统才会对出站流量选择规则进行评估,以决定如何处理流量:使用出站流量 NAT 网关,或将其直接伪装为运行 Pod 的节点的 IP 地址。

限制

出站流量 NAT 网关的当前限制包括:

  • 出站流量 NAT 网关仅针对 IPv4 模式启用。

  • 出站流量 IP 地址与节点 IP 地址必须都位于第 2 层网域中。