配置用于外部通信的出站流量 NAT 网关

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

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

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

出站流量 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 Network Gateway 控制器是 Anthos clusters on Bare Metal 上的一个捆绑组件。该控制器管理一个或多个浮动 IP 地址的列表,这些地址将用于来自集群中节点的出站流量。参与节点由指定的命名空间决定。Anthos Network Gateway 会始终尽力提供浮动 IP 地址。如果使用浮动 IP 地址的节点发生故障,则 Anthos Network Gateway 会将分配的 IP 地址移至下一个可用节点。使用该 IP 地址的所有工作负载出站流量也将随之迁移。

创建新的 1.8.0 集群时,请在集群配置文件中添加 Anthos Network Gateway 的详细信息(注释和规范)。

创建 AnthosNetworkGateway 自定义资源

您可以在创建集群时在集群配置文件中使用 baremetal.cluster.gke.io/enable-anthos-network-gateway 注释来启用 Anthos Network Gateway。将注释设置为 true,如以下示例所示:

apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
  annotations:
    baremetal.cluster.gke.io/enable-anthos-network-gateway: "true"
  name: cluster1
  namespace: cluster-cluster1

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

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

您指定的浮动 IP 地址的数量会影响集群的可靠性。例如,出站流量 NAT 网关只能使用一个指定的浮动 IP 地址,但节点故障可能会导致流量中断。如果添加更多浮动 IP 地址,AnthosNetworkGateway 会根据需要分配并移动这些地址。我们建议您为集群中使用的每个 L2 网域提供至少两个浮动 IP 地址。

控制器将根据以下条件为节点分配浮动 IP 地址:

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

您可以在获取 AnthosNetworkGateway 对象时在 status 部分找到地址/节点映射。请注意,AnthosNetworkGateway 对象位于 kube-system 命名空间中。如果某个网关节点发生故障,AnthosNetworkGateway 的控制器会将浮动 IP 地址分配给下一个可用节点。

验证网关配置

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

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

    kubectl -n kube-system get anthosnetworkgateway.networking.gke.io default -oyaml

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

    kind: AnthosNetworkGateway
    apiVersion: networking.gke.io/v1alpha1
    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
    
  2. 使用以下命令检索特定节点的 AnthosNetworkGateway 状态和地址分配。

    kubectl -n kube-system get anthosnetworkgatewaynode.networking.gke.io NODE_NAME -oyaml

    NODE_NAME 替换为您要检查的特定节点/机器的名称。

设置流量选择规则

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 范围内的 IP 地址通信。
kind: EgressNATPolicy
apiVersion: networking.gke.io/v1alpha1
metadata:
  name: egress
spec:
  egress:
  - namespaceSelector:
      matchLabels:
        user: alice
    podSelector:
      matchLabels:
        role: frontend
  - namespaceSelector:
      matchLabels:
        user: paul
    podSelector:
      matchLabels:
        role: frontend
  destinationCIDRs:
  - 8.8.8.0/24
  egressSourceIP: 192.168.1.100

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

为出站流量指定来源 IP 地址

egressSourceIP 字段中指定要使用的来源 IP 地址。来源 IP 地址必须与 AnthosNetworkGateway 自定义资源中指定的其中一个浮动 IP 地址匹配。

继续使用上一部分中的 EgressNATPolicy 示例,如果满足 Pod 选择和目标 IP 地址条件,则系统将使用 SNAT 将来自 Pod 的出站流量转换为 192.168.1.100

为了接受路由,egressSourceIP 地址必须与网关节点 IP 位于同一子网中。如果网关节点的 egressSourceIP 地址未知(未分配),则无法满足路由请求。在这种情况下,您将会在 Kubernetes 事件中收到 UnknownEgressIP 错误。

使用以下 kubectl 命令输出 EgressNATPolicy 对象的事件:

kubectl describe EgressNATPolicy egress

如果有多个 EgressNATPolicy CR,则每个 CR 都必须具有不同的 egressSourceIP 地址。为防止冲突,请与开发团队协调。

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

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

限制

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

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

  • 在此预览版阶段,出站流量 IP 地址必须与节点 IP 地址位于同一 L2 网域中。

  • 已配置为使用预览版出站流量 NAT 网关功能的集群不支持升级。