虚拟机实例的特殊配置

本页面介绍了 Compute Engine 虚拟机 (VM) 实例的特殊网络配置,示例如下:

  • 建立到实例的外部 HTTP 连接
  • 将实例配置为网络代理
  • 将实例配置为 VPN 网关
  • 将实例配置为 NAT 网关
  • 构建高可用性和高带宽 NAT 网关

建立到实例的外部 HTTP 连接

默认防火墙规则不允许通过 HTTP 或 HTTPS 连接访问您的实例。但是,添加允许这些连接的规则相当简单。请注意,实例必须具有外部 IP 地址,才能接收来自 VPC 网络外部的流量。

您可使用 gcloud 命令行工具或 Google Cloud Platform Console 添加防火墙规则,以允许建立 HTTP 或 HTTPS 连接。您也可以通过 API 添加防火墙规则。

Console

您可以使用 GCP Console 为 VPC 网络上的所有实例创建整体防火墙规则,也可以在创建该实例时选择相应的选项,从而允许个别实例使用 HTTP 和 HTTPS 连接。我们要首先介绍后面这种选项,因为它提供了对个别实例的更多控制。

  1. 在 GCP Console 中,转到虚拟机实例页面。

    转到“虚拟机实例”页面

  2. 点击创建实例
  3. 防火墙部分中,选择允许 HTTP 流量允许 HTTPS 流量
  4. 点击创建以创建实例。

选择这些复选框后,VPC 网络会自动创建一条 default-httpdefault-https 规则,此规则将应用于使用 http-serverhttps-server 标记的所有实例。您的新实例也会根据您选择的复选框,使用适当的标记。

如果您已有 default-httpdefault-https 防火墙规则,则可以通过在实例的详情页面上启用允许 HTTP允许 HTTPS 选项,将相应防火墙规则应用于现有实例。

  1. 转到“虚拟机实例”页面
  2. 点击所需实例的名称。
  3. 点击页面顶部的编辑按钮。
  4. 向下滚动到防火墙部分。
  5. 选中所需 VPC 网络下的允许 HTTP允许 HTTPS 选项。
  6. 点击保存

通过类似的方式,您也可以取消选中一个或两个复选框,禁用一个实例的外部 HTTP 或 HTTPS 访问。

通过允许为 HTTP 和 HTTPS 流量标记特定实例,而非创建一条适用于所有实例的整体防火墙规则,GCP 即限制了允许外部流量传输到一个项目内所有虚拟机的安全隐患。但是,如果您想创建一条防火墙规则,允许传送到所有虚拟机实例的 HTTP 或 HTTPS 流量,则可以创建自己的防火墙规则:

  1. 转到“VPC 网络”页面
  2. 选择要应用该防火墙规则的 VPC 网络。
  3. 防火墙规则部分下,点击添加防火墙规则
  4. 为您的防火墙规则命名,并在协议和端口 (Protocols & Ports) 框中添加 tcp:80tcp:443 以允许 HTTPS 流量。
  5. 点击创建
gcloud 命令行工具

如果您希望允许传送到一个项目中所有虚拟机的 HTTP 和 HTTPS 流量,以下命令会创建一个防火墙,允许来自任意位置的传入 HTTP 和 HTTPS 请求传送到连接到此 VPC 网络的任意实例。

gcloud compute firewall-rules create FIREWALL_RULE --allow tcp:80,tcp:443

**示例**

gcloud compute firewall-rules create sample-http \
 --description "Incoming http and https allowed." \
 --allow tcp:80,tcp:443
gcloud compute firewall-rules describe sample-http
allowed:
- IPProtocol: tcp
  ports:
  - '80'
  - '443'
creationTimestamp: '2014-06-13T13:27:12.206-07:00'
id: '5057780722612413546'
kind: compute#firewall
name: sample-http
network: https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/global/networks/default
selfLink: https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/global/firewalls/samplehttp
sourceRanges:
- 0.0.0.0/0

将实例配置为网络代理

您可以对 VPC 网络进行设计,保证仅有一个实例具有外部访问权限,并且 VPC 网络中的其他所有实例均使用该实例作为连接到外部环境的代理服务器。如果您需要控制进出 VPC 网络的访问权限,或者需要降低使用多个外部 IP 地址的费用,那么这种做法会非常有用。

这个具体示例讨论了如何在使用 Debian 映像的虚拟机实例上设置网络代理。它使用网关实例作为 Squid 代理服务器,但这仅仅是设置代理服务器的方法之一。

要设置 Squid 代理服务器,请执行以下操作:

  1. 使用外部(静态或临时)IP 地址设置一个实例。在本示例中,将您的实例命名为 gateway-instance
  2. 通过指定 gcloud compute instances create ... --no-address,设置一个或多个无外部 IP 地址的实例。在本示例中,将此实例命名为 hidden-instance
  3. 了解如何从一个实例连接到另一个实例,因为您无法直接连接到仅在内部使用的实例。
  4. 添加防火墙以允许端口 3128 上的 TCP 流量:

    gcloud compute firewall-rules create [FIREWALL_RULE] --network [NETWORK] --allow tcp:3128
    
  5. gateway-instance 上安装 Squid,并将其配置为允许通过 VPC 网络(RFC 1918RFC 4193RFC 4291 IP 空间)上的任何机器进行访问。这假设 gateway-instancehidden-instance 均连接到同一 VPC 网络,这使得它们可以彼此连接。

    user@gateway-instance:~$ sudo apt-get install squid3
    

    允许本地网络上的任何计算机使用 Squid3 服务器。以下 sed 命令在 Squid 配置文件中为本地网络和计算机取消注释并启用 acl localnet src 条目。

    user@gateway-instance:~$ sudo sed -i 's:#\(http_access allow localnet\):\1:' /etc/squid/squid.conf
    
    user@gateway-instance:~$ sudo sed -i 's:#\(http_access deny to_localhost\):\1:' /etc/squid/squid.conf
    
    user@gateway-instance:~$ sudo sed -i 's:#\(acl localnet src 10.0.0.0/8.*\):\1:' /etc/squid/squid.conf
    
    user@gateway-instance:~$ sudo sed -i 's:#\(acl localnet src 172.16.0.0/12.*\):\1:' /etc/squid/squid.conf
    
    user@gateway-instance:~$ sudo sed -i 's:#\(acl localnet src 192.168.0.0/16.*\):\1:' /etc/squid/squid.conf
    
    user@gateway-instance:~$ sudo sed -i 's:#\(acl localnet src fc00\:\:/7.*\):\1:' /etc/squid/squid.conf
    
    user@gateway-instance:~$ sudo sed -i 's:#\(acl localnet src fe80\:\:/10.*\):\1:' /etc/squid/squid.conf
    
    # Prevent proxy access to metadata server
    user@gateway-instance:~$ sudo cat <<EOF >>/etc/squid/squid.conf
    acl to_metadata dst 169.254.169.254
    http_access deny to_metadata
    EOF
    
    # Start Squid
    user@gateway:~$ sudo service squid3 start
    
  6. 配置 hidden-instance 以将 gateway-instance 用作其代理。使用 ssh 连接到 hidden-instance,并将其代理网址地址定义为指向端口 3128(默认的 Squid 配置)上的 gateway-instance,如下所示:

    user@gateway-instance:~$ ssh hidden-instance
    
    user@hidden-instance:~$ sudo -s
    
    root@hidden-instance:~# echo "export http_proxy=\"http://gateway-instance.$(dnsdomainname):3128\"" >> /etc/profile.d/proxy.sh
    
    root@hidden-instance:~# echo "export https_proxy=\"http://gateway-instance.$(dnsdomainname):3128\"" >> /etc/profile.d/proxy.sh
    
    root@hidden-instance:~# echo "export ftp_proxy=\"http://gateway-instance.$(dnsdomainname):3128\"" >> /etc/profile.d/proxy.sh
    
    root@hidden-instance:~# echo "export no_proxy=169.254.169.254,metadata,metadata.google.internal" >> /etc/profile.d/proxy.sh
    

    更新 sudoers 来传递这些环境变量。

    root@hidden-instance:~# cp /etc/sudoers /tmp/sudoers.new
    
    root@hidden-instance:~# chmod 640 /tmp/sudoers.new
    
    root@hidden-instance:~# echo "Defaults env_keep += \"ftp_proxy http_proxy https_proxy no_proxy"\" >>/tmp/sudoers.new
    
    root@hidden-instance:~# chmod 440 /tmp/sudoers.new
    
    root@hidden-instance:~# visudo -c -f /tmp/sudoers.new && cp /tmp/sudoers.new /etc/sudoers
    
  7. 退出 sudo,加载变量,然后对 hidden-instance 运行 apt-get。它现在应该会将网关用作代理。如果网关未用作代理,apt-get 就无法正常工作,因为 hidden-instance 未直接连接到互联网。

    root@hidden-instance:~# exit
    
    user@hidden-instance:~$ source ~/.profile
    
    user@hidden-instance:~$ sudo apt-get update
    

将实例配置为 VPN 网关

您可以使用 Strongswan VPN 软件,在您的某个实例上设置 VPN 网关。对于大多数用户来说,Google 建议使用 Cloud VPN 而非 Strongswan。使用 Cloud VPN 时,您不需要创建和配置实例即可运行 VPN 软件。如果 Cloud VPN 未提供您需要的功能,则可以使用 Strongswan。

  1. 创建将作为您的本地网络连接目标的 VPC 网络。

    gcloud compute networks create vpn-network --subnet-mode custom
    
  2. 创建一个 IP 范围与您的本地子网无重叠的子网。

    gcloud compute networks subnets create vpn-subnet \
        --network vpn-network \
        --region us-central1 \
        --range 10.0.0.0/24 \
    
  3. vpn-subnet 子网中创建一个实例。这个实例将作为您的 VPN 网关。

    gcloud compute instances create vpn-gateway --can-ip-forward \
        --subnet vpn-subnet \
        --zone us-central1-a \
        --tags vpn-gateway
    
  4. 查找并记录您的 VPN 网关的内部和外部 IP 地址。

    gcloud compute instances describe --zone us-central1-a vpn-gateway
    

    外部 IP 地址是 natIP 字段的值。内部 IP 地址是 networkIP 字段的值,例如 10.0.0.2。

  5. 创建一个实例,通过 VPN 网关与本地网络中的客户端进行通信。

    gcloud compute instances create test-vpn \
        --subnet vpn-subnet \
        --tags vpn \
        --zone us-central1-a
    
  6. vpn-network 网络中创建路由,以便在流量以本地网络为目的地时,通过 vpn-gateway 路由流量。

    gcloud compute routes create vpnnetwork-to-gateway \
        --destination-range [ON_PREM_IP_RANGE] \
        --next-hop-address [VPN_GATEWAY_INTERNAL_IP] \
        --network vpn-network \
        --tags vpn
    

    [VPN_GATEWAY_INTERNAL_IP] 值是您的 VPN 网关的内部 IP 地址(networkIP 字段的值)。

  7. 将以下防火墙规则添加到您的 VPC 网络,以接受传入流量。

    gcloud compute firewall-rules create ssh --source-ranges 0.0.0.0/0 \
        --allow tcp:22 \
        --network vpn-network
    
    gcloud compute firewall-rules create  allow-internal \
        --source-ranges 10.0.0.0/24 \
        --allow tcp:1-65535,udp:1-65535,icmp \
        --network vpn-network \
        --allow all
    
    gcloud compute firewall-rules create allow-ipsec-nat \
        --source-ranges [ON_PREM_VPN_GATEWAY_EXTERNAL_IP]/32 \
        --allow udp:4500,udp:500 \
        --network vpn-network \
        --target-tags vpn-gateway
    
    gcloud compute firewall-rules create from-onprem \
        --source-ranges [ON_PREM_NETWORK_ADDRESS_SPACE] \
        --allow tcp:1-65535,udp:1-65535,icmp \
        --network vpn-network \
        --target-tags vpn
    

    在您的本地网络中创建防火墙规则,以接受来自 VPC 网络的传入流量。

  8. 连接到您的 VPN 网关实例。

  9. 安装并配置 VPN 软件 Strongswan。

    在主目录中,创建一个名为 ipsec.conf 的文件。在此文件中填入以下内容,用对应于您的环境的值替换其中的占位符:

    conn myconn
      authby=psk
      auto=start
      dpdaction=hold
      esp=aes128-sha1-modp2048!
      forceencaps=yes
      ike=aes128-sha1-modp2048!
      keyexchange=ikev2
      mobike=no
      type=tunnel
      left=%any
      leftid=[VPN_GATEWAY_EXTERNAL_IP_ADDRESS]
      leftsubnet=10.0.0.0/24
      leftauth=psk
      leftikeport=4500
      right=[ON_PREM_EXTERNAL_IP_ADDRESS]
      rightsubnet=[ON_PREM_ADDRESS_SPACE]
      rightauth=psk
      rightikeport=4500
    

    然后,运行以下命令,用密钥(一个字符串值)替换 [secret-key]

    $ sudo apt-get update
    
    $ sudo apt-get install strongswan -y
    
    $ echo "%any : PSK \"[secret-key]\"" | sudo tee /etc/ipsec.secrets > /dev/null
    
    $ sudo sysctl -w net.ipv4.ip_forward=1
    
    $ sudo sed -i 's/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/g' /etc/sysctl.conf
    
    $ sudo cp ipsec.conf /etc
    
    $ sudo ipsec restart
    

    您还必须配置本地部署 VPN 网关,以便成功建立 VPN 隧道。

    如果您的本地部署网关计算机正在运行基于 Debian 的操作系统,则可以使用相同的步骤来安装和配置 Strongswan。例如,复制 ipsec.conf 文件并切换左侧和右侧的 ID 和子网。

  10. 通过从 test-vpn 实例对本地计算机进行 ping 操作来测试您的 VPN 隧道:

    gcloud compute ssh test-vpn --command 'ping -c 3 [ON_PREM_INTERNAL_ADDRESS]'
    

问题排查

如果您根据上述说明操作时遇到了 VPN 设置问题,请尝试按照以下提示来对您的设置进行问题排查:

  1. 检查连接的状态:

    $ sudo ipsec status
    

    如果未列出 myconn,请启动连接:

    $ sudo ipsec up myconn
    
  2. 确定两个 VPN 端点是否能够通信。

    使用 netcat 发送类似于 VPN 的流量(UDP,端口 4500)。在本地 VPN 端点上运行以下命令:

    $ echo | nc -u [vpn-vm-gateway-external-address] 4500
    

    在接收端运行 tcpdump,以确定您的虚拟机实例可以在端口 4500 上接收数据包:

    $ tcpdump -nn -n host [public-ip-of-local-VPN-gateway-machine] -i any
    
  3. 您可以将以下几行代码添加到您的 ipsec.conf 文件中,从而启用更详细的日志记录:

    config setup
      charondebug="ike 3, mgr 3, chd 3, net 3"
    
    conn myconn
      authby=psk
      auto=start
      ...
    

    接下来,重试连接。虽然连接仍然会失败,但您可以在日志中检查错误。该日志文件应位于您的虚拟机实例上的 /var/log/charon.log 处。

将实例配置为 NAT 网关

您可以通过更改路由集合来创建更复杂的网络情景。本节介绍如何设置内部地址转换 (NAT) 网关实例,并且使得该实例可将流量从仅限内部的虚拟机实例路由到互联网。这允许您使用一个外部 IP 地址发送来自多个虚拟机实例的流量,但仅向互联网公开单独一台虚拟机。

  1. 首先,为此情景创建一个 VPC 网络来托管虚拟机实例。

    gcloud compute networks create custom-network1 \
        --subnet-mode custom
    
  2. us-central1 区域创建子网。

    gcloud compute networks subnets create subnet-us-central \
        --network custom-network1 \
        --region us-central1 \
        --range 192.168.1.0/24
    
  3. 创建防火墙规则,以便在您刚刚创建的新网络中允许 ssh 连接。

    gcloud compute firewall-rules create custom-network1-allow-ssh \
        --allow tcp:22 \
        --network custom-network1
    
    gcloud compute firewall-rules create custom-network1-allow-internal \
        --allow tcp:1-65535,udp:1-65535,icmp \
        --source-ranges 192.168.1.0/24 \
        --network custom-network1
    
  4. 创建一个虚拟机,将其用作 custom-network1 上的 NAT 网关。

    gcloud compute instances create nat-gateway --network custom-network1 \
        --subnet subnet-us-central \
        --can-ip-forward \
        --zone us-central1-a \
        --image-family debian-9 \
        --image-project debian-cloud \
        --tags nat
    
  5. 对于没有外部 IP 地址且将使用网关实例的任何虚拟机实例,都请使用 no-ip 标记进行标记,或者新建一个无外部 IP 地址的虚拟机,并使用标记 no-ip 来标记该实例。

    • 为现有实例添加标记。
    gcloud compute instances add-tags existing-instance --tags no-ip
    
    • 或者创建一个没有外部 IP 地址的新虚拟机。
    gcloud compute instances create example-instance --network custom-network1 \
        --subnet subnet-us-central \
        --no-address \
        --zone us-central1-a \
        --image-family debian-9 \
        --image-project debian-cloud \
        --tags no-ip
    
  6. 创建路由,以便通过网关实例发送以互联网为目的地的流量。

    gcloud compute routes create no-ip-internet-route \
        --network custom-network1 \
        --destination-range 0.0.0.0/0 \
        --next-hop-instance nat-gateway \
        --next-hop-instance-zone us-central1-a \
        --tags no-ip --priority 800
    

    如果有其他任何存在冲突的路由,则设置此路由的优先级可确保优先采用此路由。默认优先级为 1000,低于 1000 的值均会得到优先采用。

  7. 接下来,登录您的网关实例,并为流向互联网的 NAT 内部流量配置 iptables。

    gcloud compute ssh nat-gateway --zone us-central1-a
    

    在您的实例上,配置 iptables:

    $ sudo sysctl -w net.ipv4.ip_forward=1
    
    $ sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
    

    第一条 sudo 命令告诉内核,您希望允许 IP 转发。第二条 sudo 命令伪装从内部实例接收到的数据包,就像这些数据包是从 NAT 网关实例发送的一样。

    要检查您的 iptables NAT 规则,请使用列出选项:

    $ sudo iptables -v -L -t nat
    

    检查输出是否类似于以下示例:

    Chain PREROUTING (policy ACCEPT 5 packets, 3924 bytes)
     pkts bytes target     prot opt in     out     source               destination
    
    Chain INPUT (policy ACCEPT 5 packets, 3924 bytes)
     pkts bytes target     prot opt in     out     source               destination
    
    Chain OUTPUT (policy ACCEPT 64 packets, 4164 bytes)
     pkts bytes target     prot opt in     out     source               destination
    
    Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination
    64  4164 MASQUERADE  all  --  any    eth0    anywhere             anywhere"
    
  8. (可选)如果您希望在将来重新启动后仍然保留这些设置,请运行如下命令:

    $ sudo echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/20-natgw.conf
    
    $ sudo apt-get install iptables-persistent
    

构建高可用性和高带宽 NAT 网关

本部分介绍了如何启用等成本多路径 (ECMP) 路由和自动修复来设置多个 NAT 网关,以实现更具弹性的高带宽部署。

GCP 为虚拟机使用 RFC 1918 专用 IP 地址。如果这些虚拟机需要访问公共互联网上的资源,则需要使用 NAT。对于简单的情景,单个 NAT 网关架构便已足够。但是,若要提高吞吐量或可用性,则需要更富有弹性的架构。

配置网关

在多条路由具有相同优先级的实例中,GCP 使用 ECMP 路由分配流量。在这种情况下,您将创建多个 NAT 网关,以便通过 ECMP 接收部分流量。随后,NAT 网关会将流量转发到使用其公开 IP 地址的外部主机。

下图展示了此配置。

多网关配置

为了提高弹性,您要将各网关置于大小为 1 的单独受管实例组中,然后附加简单的运行状况检查,以确保网关在发生故障时会自动重启。网关位于彼此分隔的实例组中,因此将具有附加到实例模板的静态外部 IP。您在本示例中预配了三个 n1-standard-2 NAT 网关,不过,根据您的实际需要,您可以设置其他任何数量或大小的网关。例如,n1-standard-2 实例的网络流量上限为 4 Gbps;如果您需要处理更多流量,则可以选择 n1-standard-8

  1. 创建 VPC 网络(如果需要)。如果您未将这些网关添加到现有 VPC,请为它们创建 VPC 网络和子网。如果要将其添加到现有 VPC,请跳至第二步并根据您的环境适当地修改区域。

    1. 使用 Cloud Shell,创建与您的 GCP 项目关联的自定义 VPC。此 VPC 允许您使用非默认 IP 地址,但不包含任何默认防火墙规则:

      gcloud compute networks create example-vpc --subnet-mode custom
      
    2. 在此 VPC 中创建一个子网,并指定一个区域和 IP 范围。在本教程中,使用 10.0.1.0/24us-east1 区域:

      gcloud compute networks subnets create example-east \
          --network example-vpc --range 10.0.1.0/24 --region us-east1
      
  2. 预留并存储三个静态 IP 地址。

    1. us-east1 地区预留并存储名为 nat-1 的地址:

      gcloud compute addresses create nat-1 --region us-east1
      
      nat_1_ip=$(gcloud compute addresses describe nat-1 \
          --region us-east1 --format='value(address)')
      
    2. us-east1 中预留并存储一个名为 nat-2 的地址:

      gcloud compute addresses create nat-2 --region us-east1
      
      nat_2_ip=$(gcloud compute addresses describe nat-2 \
          --region us-east1 --format='value(address)')
      
    3. us-east1 中预留并存储一个名为 nat-3 的地址:

      gcloud compute addresses create nat-3 --region us-east1
      nat_3_ip=$(gcloud compute addresses describe nat-3 \
          --region us-east1 --format='value(address)')
      
  3. 使用预留的 IP 创建三个实例模板。

    1. 复制启动配置:

      gsutil cp gs://nat-gw-template/startup.sh .
      

      如果无法访问启动脚本,请复制“启动脚本”部分中的脚本。

    2. 创建一个 nat-1 实例模板:

      gcloud compute instance-templates create nat-1 \
          --machine-type n1-standard-2 --can-ip-forward --tags natgw \
          --metadata-from-file=startup-script=startup.sh --address $nat_1_ip
      
    3. 创建一个 nat-2 实例模板:

      gcloud compute instance-templates create nat-2 \
          --machine-type n1-standard-2 --can-ip-forward --tags natgw \
          --metadata-from-file=startup-script=startup.sh  --address $nat_2_ip
      
    4. 创建一个 nat-3 实例模板:

      gcloud compute instance-templates create nat-3 \
          --machine-type n1-standard-2 --can-ip-forward --tags natgw \
          --metadata-from-file=startup-script=startup.sh --address $nat_3_ip
      

      n1-standard-2 机器类型有两个 vCPU,可以使用最高 4 Gbps 的网络带宽。如果您需要更多带宽,则可能需要选择其他主机。每个 vCPU 的带宽可以达到 2 Gbps,在 8vCPU 主机上最高可达到 16 Gbps。

  4. 创建运行状况检查以监控响应能力:

    gcloud compute health-checks create http nat-health-check --check-interval 30 \
        --healthy-threshold 1 --unhealthy-threshold 5 --request-path /health-check
    
    gcloud compute firewall-rules create "natfirewall" \
        --allow tcp:80 --target-tags natgw \
        --source-ranges "130.211.0.0/22","35.191.0.0/16"
    

    如果系统发生故障并且无法响应 HTTP 通信,则系统会重启。在这种情况下,由于您需要一个项目,因此可以使用现有项目,也可以新建一个项目。

  5. 为每个 NAT 网关创建一个实例组:

    gcloud compute instance-groups managed create nat-1 --size=1 --template=nat-1 --zone=us-east1-b
    gcloud compute instance-groups managed create nat-2 --size=1 --template=nat-2 --zone=us-east1-c
    gcloud compute instance-groups managed create nat-3 --size=1 --template=nat-3 --zone=us-east1-d
    
  6. 设置自动修复以重启无响应的 NAT 网关:

    gcloud beta compute instance-groups managed set-autohealing nat-1 \
        --health-check nat-health-check --initial-delay 120 --zone us-east1-b
    nat_1_instance=$(gcloud compute instances list |awk '$1 ~ /^nat-1/ { print $1 }')
    gcloud beta compute instance-groups managed set-autohealing nat-2 \
        --health-check nat-health-check --initial-delay 120 --zone us-east1-c
    nat_2_instance=$(gcloud compute instances list |awk '$1 ~ /^nat-2/ { print $1 }')
    gcloud beta compute instance-groups managed set-autohealing nat-3 \
        --health-check nat-health-check --initial-delay 120 --zone us-east1-d
    nat_3_instance=$(gcloud compute instances list |awk '$1 ~ /^nat-3/ { print $1 }')
    
  7. 将默认路由添加到您的实例:

    gcloud compute routes create natroute1 --destination-range 0.0.0.0/0 \
        --tags no-ip --priority 800 --next-hop-instance-zone us-east1-b \
        --next-hop-instance $nat_1_instance
    gcloud compute routes create natroute2 --destination-range 0.0.0.0/0 \
        --tags no-ip --priority 800 --next-hop-instance-zone us-east1-c \
        --next-hop-instance $nat_2_instance
    gcloud compute routes create natroute3 --destination-range 0.0.0.0/0 \
        --tags no-ip --priority 800 --next-hop-instance-zone us-east1-d \
        --next-hop-instance $nat_3_instance
    
  8. 标记您想要使用 NAT 的实例:

    gcloud compute instances add-tags natted-servers --tags no-ip
    
  9. 测试 NAT 功能。配置好网关并标记好访客虚拟机之后,在不为虚拟机提供外部 IP 的情况下,对外部主机进行 ping 操作,如下面的示例所示:

    ping 8.8.8.8

    输出示例:

    PING 8.8.8.8 (8.8.8.8): 56 data bytes
    64 bytes from 8.8.8.8: icmp_seq=0 ttl=52 time=0.618 ms
    64 bytes from 8.8.8.8: icmp_seq=1 ttl=52 time=0.325 ms
    64 bytes from 8.8.8.8: icmp_seq=2 ttl=52 time=0.443 ms
    64 bytes from 8.8.8.8: icmp_seq=3 ttl=52 time=0.314 ms
    64 bytes from 8.8.8.8: icmp_seq=4 ttl=52 time=0.386 ms
    

要考虑的问题

此配置在 us-east1 区域提供了三个 NAT 网关,每个网关的容量均为 2 Gbps。但是,ECMP 负载平衡并不完美,单个流不会跨多条链路进行传播。

  • 此配置的 Terraform 模块也可用于自动部署。
  • 此配置最适合临时或无状态的出站链路。如果 NAT 网关池的大小发生更改,则 TCP 连接可能会重新平衡,这可能导致已建立的连接重置。
  • 节点不会自动更新,因此如果 Debian 默认安装造成了威胁,就需要手动更新。
  • 这些实例均位于 us-east1 区域。如果您的虚拟机位于其他地区,则可以通过将网关移到更靠近这些地区的位置来提高性能。
  • 每个网关的带宽最高可达到每个核心 2 Gbps(单向)。在网关故障期间,流量将分配到其他网关,但由于正在运行的流未重新编程,因此在网关重新恢复在线后,流量不会立即重新复位。因此,应在确定大小时确保留出足够的开销。
  • 如果希望在出现意外结果时收到提醒,请使用 Stackdriver 监控托管实例组和网络流量。

启动脚本:startup.sh

在步骤 3a 中提及的启动脚本如下:

#!/bin/bash
echo 1 > /proc/sys/net/ipv4/ip_forward
echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/20-natgw.conf
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

cat <<EOF > /usr/local/sbin/health-check-server.py
#!/usr/bin/python
from BaseHTTPServer import BaseHTTPRequestHandler,HTTPServer
import subprocess

PORT_NUMBER = 80
PING_HOST = "www.google.com"

def connectivityCheck():
  try:
    subprocess.check_call(["ping", "-c", "1", PING_HOST])
    return True
  except subprocess.CalledProcessError as e:
    return False

#This class handles any incoming request
class myHandler(BaseHTTPRequestHandler):
  def do_GET(self):
    if self.path == '/health-check':
      if connectivityCheck():
        self.send_response(200)
      else:
        self.send_response(503)
    else:
      self.send_response(404)

try:
  server = HTTPServer(("", PORT_NUMBER), myHandler)
  print "Started httpserver on port " , PORT_NUMBER
  #Wait forever for incoming http requests
  server.serve_forever()

except KeyboardInterrupt:
  print "^C received, shutting down the web server"
  server.socket.close()
EOF

nohup python /usr/local/sbin/health-check-server.py >/dev/null 2>&1 &

将基于实例的 NAT 网关迁移到 Cloud NAT

如果您有基于实例的 NAT 网关并想要将其迁移到 Cloud NAT,请执行以下操作:

  1. 在基于实例的网关所在的那个区域内配置 Cloud NAT
  2. 删除静态路由或向基于实例的 NAT 网关发送数据包的路由。请注意,网络的默认网关路由应该仍然存在。
  3. 流量应开始流经 Cloud NAT。
  4. 确认一切正常运行后,删除基于实例的 NAT 网关。

后续步骤

  • 请参阅 VPC 概览,了解 VPC 网络。
  • 请参阅使用 VPC,了解如何创建和修改 VPC 网络。
此页内容是否有用?请给出您的反馈和评价:

发送以下问题的反馈:

此网页