配置出站 NAT 网关

通过 Anthos clusters on VMware (GKE On-Prem),您可以配置来源网络地址转换 (SNAT),以便获得来自用户集群的某些出站流量作为可预测的来源 IP 地址。

本文档介绍如何为用户集群配置出站 NAT 网关。

简介

有时,您的 Pod 在用户集群中运行,需要将数据包发送到在您的组织中运行但在集群外部的组件。您可能希望设计这些外部组件,以便它们根据一组众所周知的源 IP 地址过滤传入的网络流量。

以下是一些使用场景:

  • 数据库前面有一个防火墙,仅允许通过 IP 地址进行访问。管理数据库防火墙的团队与管理用户集群的团队不同。

  • 用户集群中的工作负载必须通过互联网访问第三方 API。出于安全原因,API 提供商使用 IP 地址作为身份来对流量进行身份验证和授权。

借助出站 NAT 网关,您可以精细地控制离开集群的网络流量所用的来源 IP 地址。

价格

在预览版阶段可免费使用此功能。

出站 NAT 网关的工作原理

通常,当 Pod 从集群发出数据包时,数据包将通过运行 Pod 的节点的 IP 地址进行 SNAT 转换。

设置出站 NAT 网关后,您可以指定首先将某些出站数据包发送到专用网关节点。网关节点上的网络接口配置了两个 IP 地址:主要 IP 地址和出站流量来源 IP 地址。

如果数据包已选定为使用出站 NAT 网关,则该数据包会从网关节点离开集群,并使用网络接口上配置的出站源 IP 地址进行 SNAT 转换。

下图演示了数据包流:

上图可以看到从 Pod 发送的数据包流。

  1. 在 IP 地址为 192.168.1.1 的节点上,IP 地址为 10.10.10.1 的 Pod 会生成出站数据包。

  2. 该数据包与出站规则匹配,因此会被转发到网关节点。

  3. 网关节点将来源 IP 地址更改为 192.168.1.100,并将数据包发出集群。

  4. 返回流量返回目标为 192.168.1.100 的网关节点。

  5. 网关节点使用 conntrack 将目标 IP 地址修改为 10.10.10.1。

  6. 该数据包被视为集群内流量,并转发到原始节点并传送回原始 Pod。

角色

本主题涉及两个角色:

  • 集群管理员。 此人会创建一个用户集群,并指定将由 Anthos Network Gateway 使用的浮动 IP 地址。

  • 开发者。此人在用户集群上运行工作负载并创建出站流量政策。

启用出站 NAT 网关

本部分面向集群管理员。

如需配置出站 NAT 网关,请使用用户集群配置文件中的 enableDataplaneV2advancedNetworking 字段,并创建一个或多个 NetworkGatewayGroup 对象。

在集群配置文件中,将这些字段设置为 true

enableDataplaneV2: true
...
advancedNetworking: true

创建用户集群

指定浮动 IP 地址

本部分面向集群管理员。

选择要用作出站来源地址的一组 IP 地址。这些地址称为浮动 IP 地址,因为 Network Gateway Group 会根据需要将地址分配给它选择作为出站流量网关的节点的网络接口。

浮动 IP 地址必须与节点 IP 地址位于同一子网中。

浮动 IP 地址集不得与您为节点指定的 IP 地址集重叠。

例如,假设子网的地址范围为 192.168.1.0/24。并且假设您为节点选择 192.168.1.1 至 192.168.1.99。然后您可以使用 192.168.1.100 至 192.168.1.104 作为浮动 IP 地址。

创建 NetworkGatewayGroup 对象

本部分面向集群管理员。

以下是 NetworkGatewayGroup 对象的清单示例:

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
  - 192.168.1.103
  - 192.168.1.104

floatingIPs 数组替换为浮动 IP 地址,并将清单保存到名为 my-ngg.yaml 的文件中。

创建 NetworkGatewayGroup 对象:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG apply -f my-ngg.yaml

出站 NAT 政策示例

本部分面向开发者。

以下是 EgressNatPolicy 自定义资源的示例:

kind: EgressNATPolicy
apiVersion: networking.gke.io/v1
metadata:
  name: alice-paul
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

在上面清单中,我们看到:

  • Pod 只有在满足以下条件时才能成为出站流量 NAT 的候选对象:

    • Pod 的标签为 role: frontend,Pod 位于具有 user: alice 标签的命名空间中。

    • Pod 的标签为 role: frontend,Pod 位于具有 user: paul 标签的命名空间中。

  • 从候选 Pod 到 8.8.8.0/24 范围内的地址的流量会发送到出站 NAT 网关。

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

创建 EgressNATPolicy 对象

创建您自己的 EgressNATPolicy 清单。将 metadata.name 设置为 "my-policy"。 将清单保存在名为 my-policy.yaml 的文件中。

创建 EgressNatPolicy 对象:

kubectl apply --kubeconfig USER_CLUSTER_KUBECONFIG -f my-policy.yaml

查看关于出站流量 NAT 政策的信息

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get egressnatpolicy my-policy --output yaml

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get networkgatewaygroup --namespace kube-system --output yaml

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG describe egressnatpolicy my-policy

操作顺序

出站 NAT 政策与网络政策 API 兼容。网络政策在出站流量 NAT 政策之前进行评估。如果网络政策要求丢弃数据包,则无论出站 NAT 政策如何,数据包都会被丢弃。

多项出站流量政策

如前所述,每个 EgressNATPolicy 都使用来自 NetworkGatewayGroup 的 floatingIPs 列表中与 gatewayRef.namegatewayRef.namespace 匹配的第一个 IP 地址。如果您创建多项政策并打算使用不同的 IP 地址,则需要创建多个 NetworkGatewayGroup 对象,并分别引用它们。如果您创建多项政策,则每项政策的 gatewayRef 对象必须是唯一的。

此版本的 Anthos clusters on VMware 存在一个限制,即只有 default 名称位于 kube-system 命名空间中的 NetworkGatewayGroup 才会被协调获得浮动 IP 分配。此外,只有默认 NetworkGatewayGroup 会报告所有浮动 IP 地址的分配状态。

因此,创建多个 NetworkGatewayGroup 对象时,您需要确保默认 NetworkGatewayGroup 清单中也指定了非默认对象中的 IP 地址。否则,它们不会分配为浮动 IP 地址,从而无法供 EgressNATPolicies 对象使用。

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

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

    kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get networkgatewaygroup --name default --output 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. 验证默认 NetworkGatewayGroup 的状态后,请在 kube-system 命名空间中创建其他 NetworkGatewayGroup 对象以“跟踪”每个浮动 IP。

    请注意,这些新对象不会报告分配状态,该状态在 default NetworkGatewayGroup 中。

    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. 创建多项政策来引用“辅助”NetworkGatewayGroup 对象,例如在上一步中创建的 gateway1

    kind: EgressNATPolicy
    apiVersion: networking.gke.io/v1
    metadata:
      name: egresspolicy1
    spec:
      ...
      gatewayRef:
        name: gateway1
        namespace: kube-system
    ---
    kind: EgressNATPolicy
    apiVersion: networking.gke.io/v1
    metadata:
      name: egresspolicy2
    spec:
      ...
      gatewayRef:
        name: gateway2
        namespace: kube-system
    ---
    kind: EgressNATPolicy
    apiVersion: networking.gke.io/v1
    metadata:
      name: egresspolicy3
    spec:
      ...
      gatewayRef:
        name: gateway3
        namespace: kube-system