配置出站流量 NAT 网关

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

可使用两个自定义资源来启用出站流量 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 地址。

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

Anthos clusters on Bare Metal 的出站流量 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 地址

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

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

创建 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 地址。指定 CR 时,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 对象并分别引用它们。

在此版本的 Anthos clusters on Bare Metal 中,NetworkGatewayGroup 存在的限制是只有“默认”对象才会进行浮动 IP 分配协调。此外,只有默认网关会报告所有浮动 IP 地址的分配状态。

默认网关由 kube-system 命名空间中具有 default 名称的 NetworkGatewayGroup 定义。因此,创建多个网关对象时,您需要确保默认网关清单中也指定了非默认网关中的 IP 地址。否则,它们不会分配为浮动 IP 地址,从而无法供 EgressNATPolicies 对象使用。

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

  1. 使用 kubectl 验证默认网关对象 (name: default) 以获取浮动 IP 地址的分配状态:

    kubectl -n kube-system get NetworkGatewayGroup.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:
      ...
      floatingIPs:
        192.168.1.100: worker1
        192.168.1.101: worker2
        192.168.1.102: worker1
    
  2. 验证默认网关的状态后,请在 kube-system 命名空间中创建其他网关对象以“跟踪”每个浮动 IP。

    请注意,这些新的网关对象不会报告分配状态,该状态位于 default 网关中。

    kind: NetworkGatewayGroup
    apiVersion: networking.gke.io/v1
    metadata:
      namespace: kube-system
      name: gateway1
    spec:
      floatingIPs:
      - 192.168.1.100
    ---
    kind: NetworkGatewayGroup
    apiVersion: networking.gke.io/v1
    metadata:
      namespace: kube-system
      name: gateway2
    spec:
      floatingIPs:
      - 192.168.1.101
    ---
    kind: NetworkGatewayGroup
    apiVersion: networking.gke.io/v1
    metadata:
      namespace: kube-system
      name: gateway3
    spec:
      floatingIPs:
      - 192.168.1.102
    
  3. 创建多个引用“辅助”网关对象的政策,例如在上一步中创建的 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
    

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

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

限制

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

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

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

  • 已配置为使用预览版出站流量 NAT 网关功能的集群不支持升级。对于 Anthos clusters on Bare Metal 1.12.0 版及更高版本,出站流量 NAT 网关在 Ubuntu 18.04 上仅处于预览版状态。此功能目前为预览版,可免费使用。