在 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. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

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

  3. 启用 Compute Engine API。

    启用 API

  4. In the Google Cloud console, activate Cloud Shell.

    Activate 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. 删除测试虚拟机

后续步骤