内部 TCP / UDP ロードバランサをネクストホップとして使用する VM ベースの「ハブ」アプライアンスをデプロイする

このチュートリアルでは、Virtual Private Cloud(VPC)のネットワーク ピアリングを使用してハブアンドスポーク アーキテクチャをデプロイする方法について説明します。

このチュートリアルは、一元管理を行うハブ アプライアンスを複数の Compute Engine 仮想マシンで構成し、Google Cloud 環境にハブアンドスポーク アーキテクチャを実装することを検討しているクラウド ネットワーク エンジニアや運用担当者を対象としています。このチュートリアルでは、各仮想マシンを NAT ゲートウェイとしてデプロイしますが、次世代ファイアウォールなどの他の機能にも同じ手法を使用できます。このチュートリアルは、VPC ネットワークと Compute Engine に精通していることを前提としています。

アーキテクチャ

このアーキテクチャでは、一連のスポーク VPC ネットワークはハブ VPC ネットワークを介して外部と通信を行います。ハブ VPC ネットワークでは、一元管理を行うアプライアンスのプール(ここではネットワーク アドレス変換(NAT)ゲートウェイ)を経由してトラフィックがルーティングされます。関連するルートは、ハブ VPC ネットワークからスポーク VPC ネットワークにエクスポートされます。NAT ゲートウェイは内部ロードバランサのバックエンドとして構成し、Cloud Load Balancing の内部 TCP / UDP ロードバランサをネクストホップとするデフォルト ルートを新たに追加します。

等価コスト マルチパス(ECMP)方式のルーティングで複数のルートを使用しても、内部ロードバランサと同じタイプの負荷分散と高可用性を実現できますが、内部ロードバランサを使用すると、さらに次のような利点が得られます。

  • トラフィックは、ヘルスチェックを使用している場合にのみ、正常なインスタンスに転送されます。ECMP によりルートがポイントするすべてのアクティブ インスタンスにトラフィックが転送され、内部 TCP / UDP 負荷分散を使用することで未使用のルートが生じる可能性が低減されます。インスタンスの終了時や再起動時にルートをクリーンアップする必要もありません。
  • ヘルスチェック タイマーを微調整できるため、フェイルオーバーの処理時間が短縮される可能性があります。マネージド インスタンス グループと自動修復を使用する場合もヘルスチェック タイマーをカスタマイズできますが、対象となるのはトラフィックのルーティングではなくインスタンスの再作成です。

Google では、マネージド サービスとして Cloud NAT も提供しています。これを使用すれば、ユーザーによる管理や操作なしで高可用性を実現できます。ただし、Cloud NAT はこのユースケースではサポートされません。これは、NAT 構成がピアリング ネットワークにインポートされないためです。

次の図は、このチュートリアルで構築するトポロジを表したものです。

1 つのハブ VPC ネットワークと 2 つのスポーク VPC ネットワークで構成されたアーキテクチャ。

このトポロジは、1 つのハブ VPC ネットワークと 2 つのスポーク VPC ネットワークで構成されています。スポーク VPC ネットワークは、VPC ネットワーク ピアリングを使用して、ハブ VPC ネットワークとピアリングされています。ハブ VPC ネットワークには、内部 TCP / UDP ロードバランサの背後に 2 つの NAT ゲートウェイ インスタンスがあります。静的デフォルト ルート(0/0 NAT-GW-ILB)は、ネクストホップとして内部 TCP / UDP ロードバランサをポイントします。この静的デフォルト ルートは、カスタムルートを使用して、VPC ネットワーク ピアリング経由でエクスポートされます。

目標

  • 複数の VPC ネットワークを作成し、ハブアンドスポーク アーキテクチャを使用してピアリングします。
  • ハブ VPC ネットワークで NAT ゲートウェイを作成して構成します。
  • 内部 TCP / UDP ロードバランサをネクストホップとして設定し、構成します。
  • スポーク VPC ネットワークからパブリック インターネットへの接続を確認します。

料金

このチュートリアルでは、課金対象である次の Google Cloud コンポーネントを使用します。

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。新しい Google Cloud ユーザーは無料トライアルをご利用いただけます。

このチュートリアルを終了した後、作成したリソースを削除すると、それ以上の請求は発生しません。詳しくは、クリーンアップをご覧ください。

始める前に

  1. Google アカウントにログインします。

    Google アカウントをまだお持ちでない場合は、新しいアカウントを登録します。

  2. Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。

    [プロジェクトの選択] ページに移動

  3. Cloud プロジェクトに対して課金が有効になっていることを確認します。プロジェクトに対して課金が有効になっていることを確認する方法を学習する

  4. Compute Engine API を有効にします。

    API を有効にする

  5. Cloud Console で、Cloud Shell をアクティブにします。

    Cloud Shell をアクティブにする

    Cloud Console の下部にある Cloud Shell セッションが開始し、コマンドライン プロンプトが表示されます。Cloud Shell はシェル環境です。gcloud コマンドライン ツールなどの Cloud SDK がすでにインストールされており、現在のプロジェクトの値もすでに設定されています。セッションが初期化されるまで数秒かかることがあります。

  6. このチュートリアルでは、すべてのコマンドを Cloud Shell から実行します。

環境設定

  1. Cloud Shell で、自身が作成または選択した Cloud プロジェクトで作業していることを確認します。project-id の部分は、実際の Cloud プロジェクト名に置き換えてください。

    gcloud config set project project-id
    
    export PROJECT_ID=`gcloud config list --format="value(core.project)"`
    
  2. デフォルトのコンピューティング リージョンとゾーンを設定します。

    gcloud config set compute/region us-central1
    gcloud config set compute/zone us-central1-c
    export REGION=us-central1
    export ZONE=us-central1-c
    

    このチュートリアルでは、リージョンは us-central1、ゾーンは us-central1-c です。

VPC ネットワークとサブネットの作成

  1. Cloud Shell で、ハブ VPC ネットワークとサブネットを作成します。

    gcloud compute networks create hub-vpc --subnet-mode custom
    
    gcloud compute networks subnets create hub-subnet1 \
        --network hub-vpc --range 10.0.0.0/24
    
  2. spoke1-vpc および spoke2-vpc という名前のスポーク VPC ネットワークを作成します。次に示すように、それぞれ 1 つのサブネットを指定します。

    gcloud compute networks create spoke1-vpc --subnet-mode custom
    
    gcloud compute networks create spoke2-vpc --subnet-mode custom
    
    gcloud compute networks subnets create spoke1-subnet1 \
        --network spoke1-vpc --range 192.168.1.0/24
    
    gcloud compute networks subnets create spoke2-subnet1 \
        --network spoke2-vpc --range 192.168.2.0/24
    
  3. ハブ VPC ネットワークとスポーク VPC ネットワークにファイアウォール ルールを作成します。これらのルールでは、指定された RFC 1918 範囲からの内部トラフィック(TCP/80 と 443、UDP/53、ICMP)を許可します。

    gcloud compute firewall-rules create hub-vpc-web-ping-dns \
        --network hub-vpc --allow tcp:80,tcp:443,icmp,udp:53 \
        --source-ranges 10.0.0.0/24,192.168.1.0/24,192.168.2.0/24
    
    gcloud compute firewall-rules create spoke1-vpc-web-ping-dns \
        --network spoke1-vpc --allow tcp:80,tcp:443,icmp,udp:53 \
        --source-ranges 10.0.0.0/24,192.168.1.0/24
    
    gcloud compute firewall-rules create spoke2-vpc-web-ping-dns \
        --network spoke2-vpc --allow tcp:80,tcp:443,icmp,udp:53 \
        --source-ranges 10.0.0.0/24,192.168.2.0/24
    
  4. SSH 接続で使用する IAP がすべての仮想マシンにアクセスできるように、ハブ VPC ネットワークとスポーク VPC ネットワークのファイアウォール ルールを作成します。

    gcloud compute firewall-rules create hub-vpc-iap \
        --network hub-vpc --allow tcp:22 \
        --source-ranges 35.235.240.0/20
    
    gcloud compute firewall-rules create spoke1-vpc-iap \
        --network spoke1-vpc --allow tcp:22 \
        --source-ranges 35.235.240.0/20
    
    gcloud compute firewall-rules create spoke2-vpc-iap \
        --network spoke2-vpc --allow tcp:22 \
        --source-ranges 35.235.240.0/20
    

    このチュートリアルでは、SSH 接続に Identity-Aware Proxy(IAP)を使用します。詳細については、外部 IP アドレスを持たないインスタンスへの接続をご覧ください。

  5. ハブ VPC ネットワークで自動修復インスタンス グループのヘルスチェックを許可するファイアウォール ルールを作成します。

    gcloud compute firewall-rules create hub-vpc-health-checks \
        --network hub-vpc --allow tcp:443 --target-tags nat-gw \
        --source-ranges 130.211.0.0/22,35.191.0.0/16
    

インスタンスと必要なルートの作成

  1. Cloud Shell で、NAT ゲートウェイ用のインスタンス テンプレートを作成します。このテンプレートには、NAT ゲートウェイを設定する起動スクリプトが含まれます。

    gcloud compute instance-templates create \
        hub-nat-gw-ilbnhop-template \
        --network hub-vpc \
        --subnet hub-subnet1 \
        --machine-type n1-standard-2 --can-ip-forward \
        --tags nat-gw --scopes default,compute-rw \
        --metadata startup-script='#! /bin/bash
    apt-get update
    apt-get install dnsutils -y
    echo 1 > /proc/sys/net/ipv4/ip_forward
    iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
    eth0_ip="$(curl -H "Metadata-Flavor:Google" \
        http://169.254.169.254/computeMetadata/v1/instance/network-interfaces/0/ip)"
    google_dns1="$(dig +short dns.google | head -n 1)"
    google_dns2="$(dig +short dns.google | tail -n 1)"
    sudo iptables -t nat -A PREROUTING -p tcp -s 35.191.0.0/16 \
        -d $eth0_ip --dport 443 -j DNAT --to $google_dns1
    sudo iptables -t nat -A PREROUTING -p tcp -s 130.211.0.0/22 \
        -d $eth0_ip --dport 443 -j DNAT --to $google_dns2'
    

    ヘルスチェックに使用するソース IP アドレス範囲から受信し、NAT ゲートウェイの内部 IP アドレスに送信するパケットの IP アドレスは、Google の 2 つの Public DNS エニーキャスト IP アドレス(現在は 8.8.8.8 と 8.8.4.4)に変換されます。

    このチュートリアルでは、インスタンス タイプとして n1-standard-2 を使用しますが、それ以外の任意の数やサイズのゲートウェイも使用できます。たとえば、n1-standard-2 インスタンスのネットワーク トラフィックの上限は、インスタンスあたり 4 Gbps ですが、それよりも多くのトラフィックを処理する必要がある場合は、代わりに n1-standard-8 を選択できます。

  2. HTTPS ヘルスチェックを作成します。

    gcloud compute health-checks create https \
        nat-gw-ilbnhop-health-check \
        --check-interval 10 --unhealthy-threshold 3 --port 443 \
        --host dns.google
    
  3. 単一のリージョン内で分散する 2 つのインスタンスを持つリージョン インスタンス グループを作成します。

    gcloud compute instance-groups managed create \
        hub-nat-gw-ilbnhop-mig \
        --region $REGION--size=2 \
        --template=hub-nat-gw-ilbnhop-template \
        --health-check nat-gw-ilbnhop-health-check \
        --initial-delay 15
    

    このチュートリアルでは、初期遅延を 15 秒に設定します。本番環境のデプロイでは、要件に応じてこの設定をカスタマイズしてください。このチュートリアルでは、自動スケーリング ポリシーは使用しません。

  4. バックエンド サービスを作成し、インスタンス グループを追加します。

    gcloud compute backend-services create hub-nat-gw-ilbnhop-backend \
        --load-balancing-scheme=internal \
        --protocol=tcp \
        --health-checks=nat-gw-ilbnhop-health-check
    
    gcloud compute backend-services add-backend \
        hub-nat-gw-ilbnhop-backend \
        --instance-group=hub-nat-gw-ilbnhop-mig \
        --instance-group-region=us-central1
    
  5. 転送ルールを作成します。

    gcloud compute forwarding-rules create \
        hub-nat-gw-ilbnhop \
        --load-balancing-scheme=internal \
        --network=hub-vpc \
        --subnet=hub-subnet1 \
        --address=10.0.0.10 \
        --ip-protocol=TCP \
        --ports=all \
        --backend-service=hub-nat-gw-ilbnhop-backend \
        --backend-service-region=us-central1 \
        --service-label=hub-nat-gw-ilbnhop
    

    転送ルールを TCP でのみ定義した場合でも、内部 TCP / UDP ロードバランサをネクストホップとして使用する場合、その仮想 IP アドレスの背後では TCP と UDP の両方がサポートされます。内部 TCP / UDP ロードバランサはリージョン ロードバランサです。

  6. 新しいルートを作成し、上記で作成した転送ルールをネクストホップに指定します。

    gcloud compute routes create hub-nat-gw-ilbnhop \
        --network=hub-vpc \
        --destination-range=0.0.0.0/0 \
        --next-hop-ilb=hub-nat-gw-ilbnhop \
        --next-hop-ilb-region=us-central1 \
        --priority=800
    

    ネクストホップとして使用するロードバランサには、タグを付けることはできません。

  7. ハブ VPC からデフォルト ルートを削除します。

    export hub_default_route=$(gcloud compute routes list \
        --format="value(name)" --filter="network:hub-vpc AND \
        nextHopGateway:default-internet-gateway" | head -n 1)
    gcloud compute routes delete $hub_default_route -q
    
  8. NAT ゲートウェイからのトラフィックのみを許可する新しいタグ付きルートを作成します。

    gcloud compute routes create hub-default-tagged \
        --network hub-vpc --destination-range 0.0.0.0/0 \
        --next-hop-gateway default-internet-gateway \
        --priority 700 --tags nat-gw
    
  9. 各スポークの VPC からインターネットへのデフォルト ルートを削除します。

    export spoke1_default_route=$(gcloud compute routes list \
        --format="value(name)" --filter="network:spoke1-vpc AND \
        nextHopGateway:default-internet-gateway")
    
    gcloud compute routes delete $spoke1_default_route -q
    
    export spoke2_default_route=$(gcloud compute routes list \
        --format="value(name)" \
        --filter="network:spoke2-vpc AND nextHopGateway:default-internet-gateway")
    
    gcloud compute routes delete $spoke2_default_route -q
    

    ローカルルートとインポートされたルートの間に競合がある場合、常にローカルルートが優先されます。詳細については、ルーティング順序をご覧ください。

  10. 後で NAT ゲートウェイ経由でトラフィックを走らせて接続をテストできるように、hping3 がインストールされたクライアント VM を起動スクリプトを使用して作成します。

    gcloud compute instances create spoke1-client \
        --subnet=spoke1-subnet1 --no-address \
        --metadata startup-script='#! /bin/bash
    apt-get update
    apt-get install hping3 dnsutils -y'
    
    gcloud compute instances create spoke2-client \
        --subnet=spoke2-subnet1 --no-address \
        --metadata startup-script='#! /bin/bash
    apt-get update
    apt-get install hping3 dnsutils -y'
    

VPC ネットワーク ピアリング接続の作成

VPC ネットワーク ピアリングは双方向であるため、両端で定義する必要があります。1 つの VPC ネットワークを複数の VPC ネットワークにピアリングできますが、上限があります。VPC ネットワーク ピアリングを介してデフォルト ルートに到達するには、VPC ネットワーク ピアリングを介してカスタムルートをインポートおよびエクスポートする機能を使用します。

このチュートリアルでは、すべての VPC ネットワークを同じ Cloud プロジェクトで作成します。

  1. Cloud Shell で、カスタムルートのエクスポート フラグを有効にして、ハブ VPC ネットワークからスポーク VPC ネットワークへの VPC ネットワーク ピアリング接続を作成します。

    gcloud compute networks peerings create hub-to-spoke1 \
        --network hub-vpc --peer-network spoke1-vpc \
        --peer-project $PROJECT_ID \
        --export-custom-routes
    
    gcloud compute networks peerings create hub-to-spoke2 \
        --network hub-vpc --peer-network spoke2-vpc \
        --peer-project $PROJECT_ID \
        --export-custom-routes
    
  2. カスタムルートのインポート フラグを有効にして、spoke1 VPC ネットワークからハブ VPC ネットワークへの VPC ネットワーク ピアリング接続を作成します。

    gcloud compute networks peerings create spoke1-to-hub \
        --network spoke1-vpc --peer-network hub-vpc \
        --peer-project $PROJECT_ID \
        --import-custom-routes
    
  3. カスタムルートのインポート フラグを有効にして、spoke2 VPC ネットワークからハブ VPC ネットワークへの VPC ネットワーク ピアリング接続を作成します。

    gcloud compute networks peerings create spoke2-to-hub \
        --network spoke2-vpc --peer-network hub-vpc \
        --peer-project $PROJECT_ID \
        --import-custom-routes
    

ルートの伝播と接続の確認

  1. Cloud Shell で、静的ルートが起動スクリプトの一部として正しく作成されたことを確認します。

    gcloud compute routes list --filter="network:hub-vpc"
    

    出力に hub-default-tagged ルートと hub-nat-gw-ilbanhop ルートが含まれていることを確認します。

    NAME                            NETWORK  DEST_RANGE      NEXT_HOP                  PRIORITY
    default-route-13a4b635b5eab48c  hub-vpc  10.0.0.0/24     hub-vpc                   1000
    hub-default-tagged              hub-vpc  0.0.0.0/0       default-internet-gateway  700
    hub-nat-gw-ilbanhop             hub-vpc  0.0.0.0/0       10.0.0.10                 800
    peering-route-3274f1257a9842a0  hub-vpc  192.168.2.0/24  hub-to-spoke2             1000
    peering-route-798c5777f13094bc  hub-vpc  192.168.1.0/24  hub-to-spoke1             1000
    
  2. spoke1-vpc ルーティング テーブルを確認して、デフォルト ルートが正しくインポートされたことを確認します。

    gcloud compute routes list --filter="network:spoke1-vpc"
    

    peering-route で始まり、DEST_RANGE 値が 0.0.0.0/0 であるルートが出力内にあることを確認します。

    NAME                            NETWORK     DEST_RANGE      NEXT_HOP       PRIORITY
    default-route-75f6ea8f5fc54813  spoke1-vpc  192.168.1.0/24  spoke1-vpc     1000
    peering-route-6c7f130b860bfd39  spoke1-vpc  10.0.0.0/24     spoke1-to-hub  1000
    peering-route-9d44d362f98afbd8  spoke1-vpc  0.0.0.0/0       spoke1-to-hub  800
    
  3. SSH を使用して、IAP 経由でいずれかのクライアントに接続します。

    gcloud compute ssh spoke1-client --tunnel-through-iap
    
  4. NAT ゲートウェイ経由で Google Public DNS をテストし、接続を検証します。

    sudo hping3 -S -p 80 -c 3 dns.google
    

    内部ロードバランサでサポートされているのは TCP と UDP であるため、ICMP ベースの ping を使用してインターネット接続を検証することはできません。そのため、hping3 などのツールを使用する必要があります。

    出力は次のようになります。

    HPING dns.google (eth0 8.8.4.4): S set, 40 headers + 0 data bytes
    len=44 ip=8.8.4.4 ttl=126 DF id=0 sport=80 flags=SA seq=0 win=65535 rtt=4.6 ms
    len=44 ip=8.8.4.4 ttl=126 DF id=0 sport=80 flags=SA seq=1 win=65535 rtt=4.4 ms
    len=44 ip=8.8.4.4 ttl=126 DF id=0 sport=80 flags=SA seq=2 win=65535 rtt=4.3 ms
    
    --- dns.google hping statistic ---
    3 packets transmitted, 3 packets received, 0% packet loss
    round-trip min/avg/max = 4.3/4.4/4.6 ms
    
  5. インターネットとの通信に使用するパブリック IP アドレスを検証します。

    curl ifconfig.co
    

    出力に、いずれかの NAT ゲートウェイ インスタンスのパブリック IP アドレスが表示されます。このコマンドを再度実行すると、出力に異なるパブリック IP アドレスが表示されることがあります。これは、構成した内部負荷分散セッション アフィニティ(デフォルトではクライアント IP、プロトコル、ポート)を使用して接続が分散されるためです。

    VPC ネットワーク ピアリングは推移的ではないため、スポーク VPC ネットワーク同士が VPC ネットワーク ピアリングで接続されることはありません。

本番環境に関する考慮事項

このチュートリアルで作成する構成では、1 つのリージョンに 2 つの NAT ゲートウェイを配置し、それぞれが 2 Gbps に対応します。ただし、ECMP 負荷分散は完璧ではなく、個々のフローが複数のリンクに分散されるわけではありません。このような動作は、次世代のファイアウォールなどのステートフル デバイスを使用するときに必要になります。

この構成を本番環境にデプロイする場合は、次の点を考慮してください。

  • この構成は、一時的または非ステートフルなアウトバウンド リンクに最適です。NAT ゲートウェイ プールのサイズを変更すると、TCP 接続が再バランスされるため、確立済みの接続がリセットされる場合があります。
  • ノードは自動的には更新されないため、デフォルトの Debian インストールにセキュリティ上の脆弱性がある場合は、イメージを手動で更新する必要があります。
  • VM が複数のリージョンにまたがる場合は、各リージョンに NAT ゲートウェイを設定する必要があります。
  • ゲートウェイあたりの帯域幅は、単方向でコアあたり最大 2 Gbps です。あるゲートウェイで障害が発生すると、トラフィックは残りのゲートウェイに分散されます。実行中のフローは再プログラムされないため、ゲートウェイがオンライン状態に戻っても、トラフィックがすぐに安定することはありません。したがって、サイジングの際は必ず十分なオーバーヘッドを確保してください。
  • 予期しない結果に対して通知を受け取るには、Cloud Monitoring を使用してマネージド インスタンス グループとネットワーク トラフィックをモニタリングします。

クリーンアップ

課金を停止する最も簡単な方法は、チュートリアル用に作成した Cloud プロジェクトを削除することです。また、リソースを個別に削除することもできます。

プロジェクトの削除

  1. Cloud Console で [リソースの管理] ページに移動します。

    [リソースの管理] に移動

  2. プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
  3. ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。

個々のリソースの削除

Cloud プロジェクトを残しておく場合は、このチュートリアル用に作成したリソースを削除できます。

  1. VPC ピアリングを削除します。

    gcloud compute networks peerings delete spoke2-to-hub \
        --network spoke2-vpc -q
    
    gcloud compute networks peerings delete spoke1-to-hub \
        --network spoke1-vpc -q
    
    gcloud compute networks peerings delete hub-to-spoke1 \
        --network hub-vpc -q
    
    gcloud compute networks peerings delete hub-to-spoke2 \
        --network hub-vpc -q
    
  2. インスタンス、テンプレート、ルートを削除します。

    gcloud compute instances delete spoke1-client \
        --zone=us-central1-c -q
    
    gcloud compute instances delete spoke2-client \
        --zone=us-central1-c -q
    
    gcloud compute instance-groups managed delete hub-nat-gw-mig \
        --region us-central1 -q
    
    gcloud compute health-checks delete nat-gw-health-check -q
    
    gcloud compute instance-templates delete hub-nat-gw-template -q
    
    gcloud compute routes delete hub-default-tagged -q
    
  3. ファイアウォール ルール、サブネット、VPC を削除します。

    gcloud compute firewall-rules delete spoke2-vpc-iap -q
    
    gcloud compute firewall-rules delete spoke2-vpc-web-ping-dns -q
    
    gcloud compute firewall-rules delete spoke1-vpc-iap -q
    
    gcloud compute firewall-rules delete spoke1-vpc-web-ping-dns -q
    
    gcloud compute firewall-rules delete hub-vpc-iap -q
    
    gcloud compute firewall-rules delete hub-vpc-web-ping-dns -q
    
    gcloud compute firewall-rules delete hub-vpc-health-checks -q
    
    gcloud compute networks subnets delete spoke1-subnet1 \
        --region us-central1 -q
    
    gcloud compute networks subnets delete spoke2-subnet1 \
        --region us-central1 -q
    
    gcloud compute networks subnets delete hub-subnet1 \
        --region us-central1 -q
    
    gcloud compute networks delete spoke1-vpc -q
    
    gcloud compute networks delete spoke2-vpc -q
    
    gcloud compute networks delete hub-vpc -q
    

次のステップ