借助 Google Distributed Cloud,您可以配置来源网络地址转换 (SNAT),以便获得来自用户集群的某些出站流量作为可预测的来源 IP 地址。
本文档介绍如何为用户集群配置出站 NAT 网关。
简介
有时,您的 Pod 在用户集群中运行,需要将数据包发送到在您的组织中运行但在集群外部的组件。您可能希望设计这些外部组件,以便它们根据一组众所周知的源 IP 地址过滤传入的网络流量。
以下是一些使用场景:
- 数据库前面有一个防火墙,仅允许通过 IP 地址进行访问。管理数据库防火墙的团队与管理用户集群的团队不同。 
- 用户集群中的工作负载必须通过互联网访问第三方 API。出于安全原因,API 提供商使用 IP 地址作为身份来对流量进行身份验证和授权。 
借助出站 NAT 网关,您可以精细地控制离开集群的网络流量所用的来源 IP 地址。
价格
在预览版阶段可免费使用此功能。
出站 NAT 网关的工作原理
通常,当 Pod 从集群发出数据包时,数据包将通过运行 Pod 的节点的 IP 地址进行 SNAT 转换。
设置出站 NAT 网关后,您可以指定首先将某些出站数据包发送到专用网关节点。网关节点上的网络接口配置了两个 IP 地址:主要 IP 地址和出站流量来源 IP 地址。
如果数据包已选定为使用出站 NAT 网关,则该数据包会从网关节点离开集群,并使用网络接口上配置的出站源 IP 地址进行 SNAT 转换。
下图演示了数据包流:
上图可以看到从 Pod 发送的数据包流。
- 在 IP 地址为 192.168.1.1 的节点上,IP 地址为 10.10.10.1 的 Pod 会生成出站数据包。 
- 该数据包与出站规则匹配,因此会被转发到网关节点。 
- 网关节点将来源 IP 地址更改为 192.168.1.100,并将数据包发出集群。 
- 返回流量返回目标为 192.168.1.100 的网关节点。 
- 网关节点使用 conntrack 将目标 IP 地址修改为 10.10.10.1。 
- 该数据包被视为集群内流量,并转发到原始节点并传送回原始 Pod。 
角色
本主题涉及两个角色:
- 集群管理员。 此人会创建一个用户集群,并指定将由 Anthos Network Gateway 使用的浮动 IP 地址。 
- 开发者。此人在用户集群上运行工作负载并创建出站流量政策。 
启用出站 NAT 网关
本部分面向集群管理员。
如需配置出站 NAT 网关,请使用用户集群配置文件中的 enableDataplaneV2 和 advancedNetworking 字段,并创建一个或多个 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.name和- gatewayRef.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.name 和 gatewayRef.namespace 匹配的第一个 IP 地址。如果您创建多项政策并打算使用不同的 IP 地址,则需要创建多个 NetworkGatewayGroup 对象,并分别引用它们。如果您创建多项政策,则每项政策的 gatewayRef 对象必须是唯一的。
每个 NetworkGatewayGroup 资源必须包含唯一的浮动 IP 地址。如需将多个 EgressNATPolicy 对象配置为使用同一 IP 地址,请对这些对象使用相同的 gatewayRef.name 和 gatewayRef.namespace。
如需设置多个出站流量政策和多个网关对象,请执行以下操作:
- 在 - 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
- 创建多个引用网关对象的政策,例如在上一步中创建的 - 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
(可选)指定要放置浮动 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) 质量。