在 Google Cloud 和 AWS 之间创建高可用性 VPN 连接

本教程演示如何在 Google Cloud 和 Amazon Web Services (AWS) 之间创建高可用性 VPN 连接,以便在跨这两个云平台的 VPC 网络之间进行直接通信。

本教程假定您熟悉虚拟私有云 (VPC) 网络、边界网关协议 (BGP)、虚拟专用网 (VPN) 和 IPsec 隧道的基本概念。

Google Cloud 提供高可用性 (HA) VPN 服务,以将您的 VPC 网络连接到在 Google Cloud 外部(例如在本地或 AWS 上通过 IPsec VPN 连接)运行的环境。如果根据 Google 最佳做法进行配置,高可用性 VPN 可提供服务可用性达 99.99% 的 SLA

架构概览

本文档中介绍的架构包括以下组件:

  • Cloud Router 路由器:完全分布式和全代管式 Google Cloud 服务,通过 BGP 为您的 VPC 网络提供动态路由。
  • 高可用性 VPN 网关:在 Google Cloud 上运行的 Google 管理的 VPN 网关。每个高可用性 VPN 网关都是具有两个接口的区域级资源,每个接口都有自己的外部 IP 地址:接口 0 和 1。
  • VPN 隧道:将高可用性 VPN 网关连接到对等 VPN 网关,并充当用于传输加密流量的虚拟隧道。
  • 对等 VPN 网关:两个 AWS 站点到站点 VPN 端点,可能来自 AWS 虚拟专用网关或 AWS 传输网关。

每个对等 VPN 网关连接都有两个隧道,它们预配置为指向单个客户网关(在本例中为 Google Cloud 高可用性 VPN 接口)。使用此配置时,要达到 99.99% 服务可用性的 SLA,最少需要 4 个隧道。

VPN 隧道上的路由选项和组合带宽会因在 AWS 端使用的站点到站点 VPN 选项而异:

下图展示了此架构。

架构概览。

目标

  • 在 Google Cloud 上创建 VPC 网络。
  • 在 Google Cloud 上创建高可用性 VPN 网关和 Cloud Router 路由器。
  • 在 AWS 上创建客户网关。
  • 在 AWS 上通过动态路由创建 VPN 连接。
  • 在 Google Cloud 上创建外部 VPN 网关和 VPN 隧道。
  • 验证并测试 Google Cloud 和 AWS 上的 VPC 网络之间的 VPN 连接。

Terraform 模块示例

您可以使用 gcp-to-aws-ha-vpn-terraform-module 模块在 Google Cloud 和 AWS 之间预配高可用性 VPN。

费用

本教程使用 Google Cloud 的收费组件,包括以下组件:

如需估算 Google Cloud 组件的费用,请使用 Google Cloud 价格计算器

本教程使用 Amazon Web Services 的收费组件,包括以下组件:

  • AWS 传输网关
  • AWS 站点到站点 VPN

如需估算 AWS 组件的费用,请使用 AWS 价格计算器

准备工作

  1. 在 Google Cloud Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目

    转到“项目选择器”

  2. 确保您的 Google Cloud 项目已启用结算功能

  3. 启用 Compute Engine API。

    启用 API

  4. 在 Google Cloud 控制台中,激活 Cloud Shell。

    激活 Cloud Shell

  5. 确保您拥有必需的管理角色来配置网络组件:

    • Network Admin:compute.networkAdmin
    • Security Admin:compute.securityAdmin
    • Compute Admin:compute.admin

    如需详细了解这些角色的用途,请参阅负有网络相关工作职责的 IAM 角色

在 Google Cloud 上创建高可用性 VPN 网关和 Cloud Router 路由器

在本部分中,您将在 Google Cloud 上创建一个 VPC 网络、一个高可用性 VPN 网关和一个 Cloud Router 路由器。

  1. 在 Cloud Shell 中,确保您使用的是您创建或选择的 Google Cloud 项目:

    gcloud config set project YOUR_PROJECT_ID
    
    export PROJECT_ID=`gcloud config list --format="value(core.project)"`
    

    YOUR_PROJECT_ID 替换为您的 Google Cloud 项目 ID。

  2. 创建具有单个子网的自定义 VPC 网络:

    gcloud compute networks create NETWORK \
        --subnet-mode SUBNET_MODE \
        --bgp-routing-mode BGP_ROUTING_MODE
    

    请替换以下内容:

    该命令应类似于以下示例:

    gcloud compute networks create gc-vpc \
        --subnet-mode custom \
        --bgp-routing-mode global
    
  3. 创建一个子网来托管测试虚拟机:

    gcloud compute networks subnets create SUBNET_NAME \
        --network NETWORK \
        --region SUBNET_REGION \
        --range IP_ADDRESS_RANGE
    

    请替换以下内容:

    这些命令应类似于以下示例:

    gcloud compute networks subnets create subnet-east4  \
        --network gc-vpc \
        --region us-east4 \
        --range 10.1.1.0/24
    
  4. 创建高可用性 VPN 网关:

    gcloud compute vpn-gateways create HA_VPN_GATEWAY_NAME \
        --network NETWORK \
        --region REGION
    

    HA_VPN_GATEWAY_NAME 替换为高可用性 VPN 网关的名称。

  5. 创建 Cloud Router 路由器:

    gcloud compute routers create ROUTER_NAME \
        --region REGION \
        --network NETWORK \
        --asn GOOGLE_ASN \
        --advertisement-mode custom \
        --set-advertisement-groups all_subnets
    

    请替换以下内容:

    • ROUTER_NAME:Cloud Router 路由器的名称
    • GOOGLE_ASN:您要创建的 Cloud Router 路由器的专用 ASN(自治系统编号)。它可以是 64512-65534 或 4200000000-4294967294 范围内您尚未用作同一区域和网络中的对等 ASN 的任何专用 ASN。

    该命令应类似于以下示例:

    gcloud compute routers create cloud-router \
        --region us-east4 \
        --network gc-vpc \
        --asn 65534 \
        --advertisement-mode custom \
        --set-advertisement-groups all_subnets
    

此过程会创建一个具有两个接口的 VPN 网关。记下外部地址,以便当在 AWS 端设置环境时使用这些地址。

在 AWS 上创建网关和 VPN 连接

在本部分中,您将创建客户网关、目标网关和采用动态路由的 VPN 连接。

您可以使用 AWS 命令行界面来运行 AWS 命令。

  1. 使用以下 AWS 命令创建两个客户网关:

    aws ec2 create-customer-gateway --type ipsec.1 --public-ip INTERFACE_0_IP_ADDRESS --bgp-asn GOOGLE_ASN
    
    aws ec2 create-customer-gateway --type ipsec.1 --public-ip INTERFACE_1_IP_ADDRESS --bgp-asn GOOGLE_ASN
    

    INTERFACE_0_IP_ADDRESSINTERFACE_1_IP_ADDRESS 替换为在上一部分的最后一步中获得的公共 IP 地址。

  2. 创建目标网关并将其挂接到您的 VPC 网络。

    目标网关可以是虚拟专用网关或传输网关。如需了解详情,请参阅创建目标网关

    按照虚拟专用网关或传输网关的说明操作:

    • 虚拟专用网关:

      1. 创建具有特定 AWS 端 ASN 的虚拟专用网关:

        aws ec2 create-vpn-gateway --type ipsec.1 --amazon-side-asn AWS_SIDE_ASN
        

        AWS_SIDE_ASN 替换为 AWS 端的 ASN。

        该命令应类似于以下示例:

        aws ec2 create-vpn-gateway --type ipsec.1 --amazon-side-asn 65001
        
      2. 将虚拟专用网关挂接到 VPC 网络:

        aws ec2 attach-vpn-gateway --vpn-gateway-id VPN_GATEWAY_ID --vpc-id VPC_ID
        
    • 传输网关:

      1. 创建传输网关:

        aws ec2 create-transit-gateway --description TRANSIT_GATEWAY_DESCRIPTION \
            --options=AmazonSideAsn=65001,AutoAcceptSharedAttachments=enable,DefaultRouteTableAssociation=enable,DefaultRouteTablePropagation=enable,VpnEcmpSupport=enable,DnsSupport=enable
        

        TRANSIT_GATEWAY_DESCRIPTION 替换为传输网关的说明。

      2. 将 VPC 网络挂接到传输网关:

        aws ec2 create-transit-gateway-vpc-attachment \
            --transit-gateway-id TRANSIT_GATEWAY_ID \
            --vpc-id VPC_ID \
            --subnet-id SUBNET_ID
        
  3. 创建采用动态路由的 VPN 连接。

    创建采用动态路由的 VPN 连接的方法各不相同,具体取决于您的目标网关是虚拟专用网关还是传输网关。如需了解详情,请参阅创建站点到站点 VPN 连接

    按照虚拟专用网关或传输网关的说明操作:

    • 虚拟专用网关:

      在虚拟专用网关和客户网关之间创建采用动态路由的 VPN 连接,并将标记应用于 VPN 连接:

          aws ec2 create-vpn-connection \
              --type ipsec.1 \
              --customer-gateway-id CUSTOMER_GATEWAY_1 \
              --vpn-gateway-id VPN_GATEWAY_ID \
              --options TunnelOptions='[{TunnelInsideCidr=AWS_T1_IP,PreSharedKey=SHARED_SECRET_1},{TunnelInsideCidr=AWS_T2_IP,PreSharedKey=SHARED_SECRET_2}]'
      
          aws ec2 create-vpn-connection \
              --type ipsec.1 \
              --customer-gateway-id CUSTOMER_GATEWAY_2 \
              --vpn-gateway-id VPN_GATEWAY_ID \
              --options TunnelOptions='[{TunnelInsideCidr=AWS_T3_IP,PreSharedKey=SHARED_SECRET_3},{TunnelInsideCidr=AWS_T4_IP,PreSharedKey=SHARED_SECRET_4}]'
      
    • 传输网关:

      在传输网关和客户网关之间创建采用动态路由的 VPN 连接:

      aws ec2 create-vpn-connection \
          --type ipsec.1 \
          --customer-gateway-id CUSTOMER_GATEWAY_1 \
          --transit-gateway-id TRANSIT_GATEWAY_ID \
          --options TunnelOptions='[{TunnelInsideCidr=AWS_T1_IP,PreSharedKey=SHARED_SECRET_1},{TunnelInsideCidr=AWS_T2_IP,PreSharedKey=SHARED_SECRET_2}]'
      
      aws ec2 create-vpn-connection \
          --type ipsec.1 \
          --customer-gateway-id CUSTOMER_GATEWAY_2 \
          --transit-gateway-id TRANSIT_GATEWAY_ID \
          --options TunnelOptions='[{TunnelInsideCidr=AWS_T3_IP,PreSharedKey=SHARED_SECRET_3},{TunnelInsideCidr=AWS_T4_IP,PreSharedKey=SHARED_SECRET_4}]'
      

      请替换以下内容:

      • CUSTOMER_GATEWAY_1:Google Cloud VPN 网关,接口 0
      • CUSTOMER_GATEWAY_2:Google Cloud VPN 网关,接口 1
      • AWS_T1_IP:用于连接 1、隧道 1 的虚拟专用网关的内部 IP 地址
      • AWS_T2_IP:用于连接 1、隧道 2 的虚拟专用网关的内部 IP 地址
      • AWS_T3_IP:用于连接 2、隧道 1 的虚拟专用网关的内部 IP 地址
      • AWS_T4_IP:用于连接 2、隧道 2 的虚拟专用网关的内部 IP 地址
      • SHARED_SECRET_1:连接 1、隧道 1 的预共享密钥
      • SHARED_SECRET_2:连接 1、隧道 2 的预共享密钥
      • SHARED_SECRET_3:连接 2、隧道 1 的预共享密钥
      • SHARED_SECRET_4:连接 2、隧道 2 的预共享密钥

      AWS 预留了一些 CIDR 范围,因此您不能将这些范围中的值用作 IP 地址(AWS_T1_IPAWS_T2_IPAWS_T3_IPAWS_T4_IP)。如需了解 AWS 预留的 CIDR 块,请参阅隧道 IPv4 CIDR 内

      这些命令将创建四个连接到 Google Cloud 的隧道。

  4. 下载配置文件以用于两个 VPN 连接。

    在后续步骤中,您将使用配置文件中的值在 Google Cloud 端创建和配置资源。

在 Google Cloud 上创建 VPN 隧道和 Cloud Router 路由器接口

在本部分中,您将使用您在上一部分中创建的 AWS VPN 连接的信息,在 Google Cloud 上创建和配置组件。

在配置连接到 AWS 的 VPN 隧道时,请使用 IKEv2 加密协议并选择 AWS 端较少的转换集。例如,选择一个第 1 阶段加密算法和一个第 2 阶段加密算法、完整性算法以及 Diffie-Hellman (DH) 组编号的组合。否则,由于默认 AWS 转换集的较大安全关联 (SA) 载荷大小,Cloud VPN 隧道可能无法进行密钥更新。这种较大的载荷大小会导致 AWS 端的 IKE 数据包的 IP 碎片化,而这不受 Cloud VPN 的支持。如需了解详情,请参阅站点到站点 VPN 连接的隧道选项

  1. 在 Cloud Shell 中,为 AWS 外部 IP 地址创建一个具有四个接口的外部 VPN 网关:

    gcloud compute external-vpn-gateways create PEER_GATEWAY_NAME --interfaces \
      0=AWS_GW_IP_1,1=AWS_GW_IP_2,2=AWS_GW_IP_3,3=AWS_GW_IP_4
    

    请替换以下内容:

    • AWS_GW_IP_1:用于连接 1、隧道 1 的虚拟专用网关的外部 IP 地址
    • AWS_GW_IP_2:用于连接 1、隧道 2 的虚拟专用网关的外部 IP 地址
    • AWS_GW_IP_3:用于连接 2、隧道 1 的虚拟专用网关的外部 IP 地址
    • AWS_GW_IP_4:用于连接 2、隧道 2 的虚拟专用网关的外部 IP 地址
  2. 创建四个 VPN 隧道:

    • 隧道 1:

      gcloud compute vpn-tunnels create tunnel-1 \
          --peer-external-gateway PEER_GATEWAY_NAME \
          --peer-external-gateway-interface 0 \
          --region REGION \
          --ike-version IKE_VERSION \
          --shared-secret SHARED_SECRET_1 \
          --router ROUTER_NAME \
          --vpn-gateway HA_VPN_GATEWAY_NAME \
          --interface 0
      
    • 隧道 2:

      gcloud compute vpn-tunnels create tunnel-2 \
          --peer-external-gateway PEER_GATEWAY_NAME \
          --peer-external-gateway-interface 1 \
          --region REGION \
          --ike-version IKE_VERSION \
          --shared-secret SHARED_SECRET_2 \
          --router ROUTER_NAME \
          --vpn-gateway HA_VPN_GATEWAY_NAME \
          --interface 0
      
    • 隧道 3:

      gcloud compute vpn-tunnels create tunnel-3 \
          --peer-external-gateway PEER_GATEWAY_NAME \
          --peer-external-gateway-interface 2 \
          --region REGION \
          --ike-version IKE_VERSION \
          --shared-secret SHARED_SECRET_3 \
          --router ROUTER_NAME \
          --vpn-gateway HA_VPN_GATEWAY_NAME \
          --interface 1
      
    • 隧道 4:

      gcloud compute vpn-tunnels create tunnel-4 \
          --peer-external-gateway PEER_GATEWAY_NAME \
          --peer-external-gateway-interface 3 \
          --region REGION \
          --ike-version IKE_VERSION \
          --shared-secret SHARED_SECRET_4 \
          --router ROUTER_NAME \
          --vpn-gateway HA_VPN_GATEWAY_NAME \
          --interface 1
      
  3. 创建四个 Cloud Router 路由器接口:

    在以下命令中,将每个 GOOGLE_BGP_IP_TUNNEL 占位符替换为 Google Cloud 端隧道的内部 IP 地址。您可以发现 AWS VPN 配置文件中的值是每个隧道的客户网关地址。每个地址都必须在 169.254.0.0/16 网络范围的 /30 CIDR 范围内。

    • Cloud Router 路由器接口 1:

      gcloud compute routers add-interface ROUTER_NAME \
          --interface-name int-1 \
          --vpn-tunnel tunnel-1 \
          --ip-address GOOGLE_BGP_IP_TUNNEL_1 \
          --mask-length 30 \
          --region REGION
      
    • Cloud Router 路由器接口 2:

      gcloud compute routers add-interface ROUTER_NAME \
          --interface-name int-2 \
          --vpn-tunnel tunnel-2 \
          --ip-address GOOGLE_BGP_IP_TUNNEL_2 \
          --mask-length 30 \
          --region REGION
      
    • Cloud Router 路由器接口 3:

      gcloud compute routers add-interface ROUTER_NAME \
          --interface-name int-3 \
          --vpn-tunnel tunnel-3 \
          --ip-address GOOGLE_BGP_IP_TUNNEL_3 \
          --mask-length 30 \
          --region REGION
      
    • Cloud Router 路由器接口 4:

      gcloud compute routers add-interface ROUTER_NAME \
          --interface-name int-4 \
          --vpn-tunnel tunnel-4 \
          --ip-address GOOGLE_BGP_IP_TUNNEL_4 \
          --mask-length 30 \
          --region REGION
      
  4. 添加 BGP 对等节点。

    在以下命令中,将 PEER_ASN 替换为 BGP 会话的 AWS 端的 ASN。

    • AWS 连接 1、隧道 1

      gcloud compute routers add-bgp-peer ROUTER_NAME \
          --peer-name aws-conn1-tunn1 \
          --peer-asn PEER_ASN \
          --interface int-1 \
          --peer-ip-address AWS_T1_IP \
          --region REGION
      
    • AWS 连接 1、隧道 2

      gcloud compute routers add-bgp-peer ROUTER_NAME \
          --peer-name aws-conn1-tunn2 \
          --peer-asn PEER_ASN \
          --interface int-2 \
          --peer-ip-address AWS_T2_IP \
          --region REGION
      
    • AWS 连接 2、隧道 1

      gcloud compute routers add-bgp-peer ROUTER_NAME \
          --peer-name aws-conn2-tunn1 \
          --peer-asn PEER_ASN \
          --interface int-3 \
          --peer-ip-address AWS_T3_IP \
          --region REGION
      
    • AWS 连接 2、隧道 2

      gcloud compute routers add-bgp-peer ROUTER_NAME \
          --peer-name aws-conn2-tunn2 \
          --peer-asn PEER_ASN \
          --interface int-4 \
          --peer-ip-address AWS_T4_IP \
          --region REGION
      

验证配置

  1. 在 Cloud Shell 中,验证 Cloud Router 路由器状态:

    gcloud compute routers get-status ROUTER_NAME \
        --region REGION \
        --format='flattened(result.bgpPeerStatus[].name, result.bgpPeerStatus[].ipAddress, result.bgpPeerStatus[].peerIpAddress)'
    

    输出内容类似如下:

    result.bgpPeerStatus[].peerIpAddress)'
    result.bgpPeerStatus[0].ipAddress:     169.254.171.18
    result.bgpPeerStatus[0].name:          aws-conn1-tunn1
    result.bgpPeerStatus[0].peerIpAddress: 169.254.171.17
    result.bgpPeerStatus[1].ipAddress:     169.254.156.154
    result.bgpPeerStatus[1].name:          aws-conn1-tunn2
    result.bgpPeerStatus[1].peerIpAddress: 169.254.156.153
    result.bgpPeerStatus[2].ipAddress:     169.254.123.38
    result.bgpPeerStatus[2].name:          aws-conn2-tunn1
    result.bgpPeerStatus[2].peerIpAddress: 169.254.123.37
    result.bgpPeerStatus[3].ipAddress:     169.254.48.186
    result.bgpPeerStatus[3].name:          aws-conn2-tunn2
    result.bgpPeerStatus[3].peerIpAddress: 169.254.48.185
    
  2. 列出所有隧道:

    gcloud compute vpn-tunnels list
    

    输出内容类似如下:

    NAME      REGION    GATEWAY    PEER_ADDRESS
    tunnel-1  us-east4  ha-vpn-gw  34.205.x.x
    tunnel-2  us-east4  ha-vpn-gw  52.203.x.x
    tunnel-3  us-east4  ha-vpn-gw  3.208.x.x
    tunnel-4  us-east4  ha-vpn-gw  52.204.x.x
    
  3. 检查隧道状态:

    gcloud compute vpn-tunnels describe tunnel-1 \
         --region REGION \
         --format='flattened(status,detailedStatus)'
    

    输出内容类似如下:

    detailed_status: Tunnel is up and running.
    status:          ESTABLISHED
    
  4. 列出 Cloud Router 路由器知悉的动态路由:

    gcloud compute routers get-status ROUTER_NAME \
        --region REGION \
        --format="flattened(result.bestRoutes)"
    

    输出内容类似如下:

    result.bestRoutes[0].creationTimestamp: 2021-01-19T20:42:07.366-08:00
    result.bestRoutes[0].destRange:         10.2.2.0/24
    result.bestRoutes[0].kind:              compute#route
    result.bestRoutes[0].nextHopIp:         169.254.171.17
    result.bestRoutes[0].priority:          100
    result.bestRoutes[1].creationTimestamp: 2021-01-19T20:42:07.366-08:00
    result.bestRoutes[1].destRange:         10.2.2.0/24
    result.bestRoutes[1].kind:              compute#route
    result.bestRoutes[1].nextHopIp:         169.254.156.153
    result.bestRoutes[1].priority:          100
    result.bestRoutes[2].creationTimestamp: 2021-01-19T20:56:26.588-08:00
    result.bestRoutes[2].destRange:         10.2.2.0/24
    result.bestRoutes[2].kind:              compute#route
    result.bestRoutes[2].nextHopIp:         169.254.123.37
    result.bestRoutes[2].priority:          100
    result.bestRoutes[3].creationTimestamp: 2021-01-19T20:56:26.588-08:00
    result.bestRoutes[3].destRange:         10.2.2.0/24
    result.bestRoutes[3].kind:              compute#route
    result.bestRoutes[3].nextHopIp:         169.254.48.185
    result.bestRoutes[3].priority:          100
    

测试连接性

  1. 在隧道的每端创建测试虚拟机以测试 ping 请求。

    确保您已部署允许 ICMP 流量的防火墙规则

    • 如需了解如何在 Compute Engine 中创建虚拟机,请参阅入门指南

    • 如需了解如何在 AWS 上创建虚拟机,请参阅启动虚拟机

  2. 使用 ping 命令测试连接。

  3. 使用 iperf 测量测试机器之间的带宽。

    • 服务器端:

      iperf3 -s
      
    • 客户端:

      iperf3 -c SERVER_IP_ADDRESS -P NUMBER_OF_PARALLEL_SESSIONS
      

清理

删除您在本教程中创建的 Google Cloud 和 AWS 资源。

删除 Google Cloud 项目

为避免系统因本教程中使用的资源向您的 Google Cloud 账号收取费用,您可以删除您的项目:

  1. 在 Google Cloud 控制台中,进入管理资源页面。

    转到“管理资源”

  2. 在项目列表中,选择要删除的项目,然后点击删除
  3. 在对话框中输入项目 ID,然后点击关闭以删除项目。

删除 AWS 资源

  1. 删除 VPN 连接
  2. 删除传输网关
  3. 删除测试虚拟机

后续步骤