Cloud NAT の動的ポート割り当ての使用

1. 概要

動的ポート割り当て(DPA)は、Cloud NAT の新機能です。DPA を有効にすると、Cloud NAT はインスタンスのニーズに応じてポート割り当てを動的にスケールアップ/スケールダウンします。DPA は最小ポート数と最大ポート数の制限で構成されているため、ポートが最小値を下回ることはなく、最大値を超えることもありません。これにより、NAT ゲートウェイの背後にある一部のインスタンスは、Cloud NAT の背後にあるすべてのインスタンスに追加のポートを割り当てることなく、接続数を動的にスケールアップできます。

DPA がない場合、Cloud NAT の背後にあるすべてのインスタンスには、minPortsPerVm パラメータで定義されているように、使用状況に関係なく同じ数のポートが割り当てられます。

詳細については、NAT DPA に関するドキュメント セクション をご覧ください。

学習内容

  • DPA の準備として Cloud NAT ゲートウェイを設定する方法。
  • DPA を使用せずにポート割り当てを検査する方法。
  • NAT ゲートウェイの DPA を有効にして構成する方法。
  • 並行下り(外向き)接続を実行して、DPA の効果を確認する方法。
  • DPA が有効になっている NAT ゲートウェイに NAT ルールを追加する方法。
  • 複数の宛先に下り(外向き)接続を実行して、ルールによる DPA の動作を確認する方法。

必要なもの

  • Google Compute Engine に関する基本的な知識
  • ネットワークと TCP/IP に関する基本的な知識
  • Unix / Linux コマンドラインに関する基本的な知識
  • Google Cloud のネットワーキング ラボなど、Google Cloud のネットワーキング ツアーを完了していると、手順を進める上で役立ちます。
  • 「アルファ版アクセス」が有効になっている Google Cloud プロジェクト。
  • Cloud NAT の基本を理解している。

2. Google Cloud コンソールと Cloud Shell を使用する

このラボでは、GCP を操作するために、Google Cloud Console と Cloud Shell の両方を使用します。

Google Cloud Console

Cloud コンソールには、https://console.cloud.google.com からアクセスできます。

75eef5f6fd6d7e41.png

セルフペース型の環境設定

  1. Google Cloud Console にログインして、プロジェクトを新規作成するか、既存のプロジェクトを再利用します。Gmail アカウントも Google Workspace アカウントもまだお持ちでない場合は、アカウントを作成してください。

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

  • プロジェクト名は、このプロジェクトの参加者に表示される名称です。Google API では使用されない文字列で、いつでも更新できます。
  • プロジェクト ID は、すべての Google Cloud プロジェクトにおいて一意でなければならず、不変です(設定後は変更できません)。Cloud Console により一意の文字列が自動生成されます(通常は内容を意識する必要はありません)。ほとんどの Codelab では、プロジェクト ID を参照する必要があります(通常、プロジェクト ID は「PROJECT_ID」の形式です)。好みの文字列でない場合は、別のランダムな ID を生成するか、独自の ID を試用して利用可能であるかどうかを確認することができます。プロジェクトの作成後、ID は「フリーズ」されます。
  • 3 つ目の値として、一部の API が使用するプロジェクト番号があります。これら 3 つの値について詳しくは、こちらのドキュメントをご覧ください。
  1. 次に、Cloud のリソースや API を使用するために、Cloud Console で課金を有効にする必要があります。この Codelab の操作をすべて行って、費用が生じたとしても、少額です。このチュートリアルを終了した後に課金が発生しないようにリソースをシャットダウンするには、Codelab の最後にある「クリーンアップ」の手順を行います。Google Cloud の新規ユーザーは、300 米ドル分の無料トライアル プログラムをご利用いただけます。

Cloud Shell の起動

Google Cloud はノートパソコンからリモートで操作できますが、この Codelab では、Google Cloud Shell(Cloud 上で動作するコマンドライン環境)を使用します。

GCP Console で右上のツールバーにある Cloud Shell アイコンをクリックします。

bce75f34b2c53987.png

プロビジョニングと環境への接続にはそれほど時間はかかりません。完了すると、次のように表示されます。

f6ef2b5f13479f3a.png

この仮想マシンには、必要な開発ツールがすべて用意されています。永続的なホーム ディレクトリが 5 GB 用意されており、Google Cloud で稼働します。そのため、ネットワークのパフォーマンスと認証機能が大幅に向上しています。このラボでの作業はすべて、ブラウザから実行できます。

3. ラボの設定

このラボでは、プロジェクトを使用して、それぞれにサブネットを含む 2 つの VPC を作成します。外部 IP アドレスを予約し、Cloud NAT ゲートウェイ(Cloud Router を使用)、2 つのプロデューサー インスタンス、2 つのコンシューマー インスタンスを作成して構成します。デフォルトの Cloud NAT の動作を検証したら、動的ポート割り当てを有効にして、その動作を検証します。最後に、NAT ルールを構成し、DPA と NAT ルールの間の相互作用を確認します。

ネットワーキング アーキテクチャの概要:

a21caa6c333909d8.png

4. 外部 IP アドレスを予約する

このラボで使用するすべての外部 IP アドレスを予約しましょう。これにより、コンシューマー VPC とプロデューサー VPC の両方に関連する NAT ルールとファイアウォール ルールをすべて記述できます。

Cloud Shell から:

gcloud compute addresses  create nat-address-1 nat-address-2 \
 producer-address-1 producer-address-2 --region us-east4

出力:

Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/nat-address-1].
Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/nat-address-2].
Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/producer-address-1].
Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/producer-address-2].

予約した IP アドレスを環境変数として入力します。

export natip1=`gcloud compute addresses list --filter name:nat-address-1 --format="get(address)"`
export natip2=`gcloud compute addresses list --filter name:nat-address-2 --format="get(address)"`
export producerip1=`gcloud compute addresses list --filter name:producer-address-1 --format="get(address)"`
export producerip2=`gcloud compute addresses list --filter name:producer-address-2 --format="get(address)"`

出力は想定されていませんが、アドレスが正しく入力されたことを確認します。すべての環境変数の値を出力してみましょう。

env | egrep '^(nat|producer)ip[1-3]'

出力:

producerip1=<Actual Producer IP 1>
producerip2=<Actual Producer IP 2>
natip1=<NAT IP 1>
natip2=<NAT IP 2>

5. プロデューサー VPC とインスタンスの設定。

次に、プロデューサー リソースのリソースを作成します。プロデューサー VPC で実行されているインスタンスは、2 つのパブリック IP(producer-address-1 と producer-address-2)を使用してインターネットに接続するサービスを提供します。

まず、VPC を作成します。Cloud Shell から:

gcloud compute networks create producer-vpc --subnet-mode custom

出力:

Created [https://www.googleapis.com/compute/v1/projects/<Project-ID>/global/networks/producer-vpc].
NAME      SUBNET_MODE  BGP_ROUTING_MODE  IPV4_RANGE  GATEWAY_IPV4
producer-vpc  CUSTOM       REGIONAL

Instances on this network will not be reachable until firewall rules
are created. As an example, you can allow all internal traffic between
instances as well as SSH, RDP, and ICMP by running:

$ gcloud compute firewall-rules create <FIREWALL_NAME> --network producer-vpc --allow tcp,udp,icmp --source-ranges <IP_RANGE>
$ gcloud compute firewall-rules create <FIREWALL_NAME> --network producer-vpc --allow tcp:22,tcp:3389,icmp

次に、us-east4 にサブネットを作成します。Cloud Shell から:

gcloud compute networks subnets create prod-net-e4 \
   --network producer-vpc --range 10.0.0.0/24 --region us-east4

出力:

Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/subnetworks/prod-net-e4].
NAME         REGION    NETWORK       RANGE        STACK_TYPE  IPV6_ACCESS_TYPE  IPV6_CIDR_RANGE  EXTERNAL_IPV6_CIDR_RANGE
prod-net-e4  us-east4  producer-vpc  10.0.0.0/24  IPV4_ONLY

次に、NAT IP アドレスがポート 8080 のプロデューサー インスタンスに到達できるようにする VPC ファイアウォール ルールを作成します。

最初のルールの場合、Cloud Shell から次の操作を行います。

gcloud compute firewall-rules create producer-allow-80 \
  --network producer-vpc --allow tcp:80 \
  --source-ranges $natip1,$natip2

出力:

Creating firewall...⠹Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/global/firewalls/producer-allow-80].
Creating firewall...done.
NAME                 NETWORK       DIRECTION  PRIORITY  ALLOW     DENY  DISABLED
producer-allow-80    producer-vpc  INGRESS    1000      tcp:80          False

次のステップでは、2 つのプロデューサー インスタンスを作成します。

プロデューサー インスタンスは、シンプルな nginx プロキシ デプロイを実行します。

必要なすべてのソフトウェアを含むインスタンスを迅速にプロビジョニングするために、Debian APT パッケージ マネージャーを使用して nginx をインストールする起動スクリプトを使用してインスタンスを作成します。

NAT ルールを作成できるように、各インスタンスに異なる予約済み IP アドレスをプロビジョニングします。

最初のインスタンスを作成します。Cloud Shell から:

gcloud compute instances create producer-instance-1 \
--zone=us-east4-a --machine-type=e2-medium \
--network-interface=address=producer-address-1,network-tier=PREMIUM,subnet=prod-net-e4 \
--metadata startup-script="#! /bin/bash
sudo apt update
sudo apt install -y nginx
mkdir /var/www/html/nginx/
cat <<EOF > /var/www/html/nginx/index.html
<html><body><h1>This is producer instance 1</h1>
</body></html>
EOF"

出力:

Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/zones/us-east4-a/instances/producer-instance-1].
NAME                 ZONE        MACHINE_TYPE  PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP    STATUS
producer-instance-1  us-east4-a  e2-medium                  10.0.0.2     <Producer IP1>  RUNNING

次に、2 つ目のインスタンスを作成します。Cloud Shell から:

gcloud compute instances create producer-instance-2 \
--zone=us-east4-a --machine-type=e2-medium \
--network-interface=address=producer-address-2,network-tier=PREMIUM,subnet=prod-net-e4 \
--metadata startup-script="#! /bin/bash
sudo apt update
sudo apt install -y nginx
mkdir /var/www/html/nginx/
cat <<EOF > /var/www/html/nginx/index.html
<html><body><h1>This is producer instance 2</h1>
</body></html>
EOF"

出力:

Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/zones/us-east4-a/instances/producer-instance-2].
NAME                 ZONE        MACHINE_TYPE  PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP    STATUS
producer-instance-2  us-east4-a  e2-medium                  10.0.0.3     <Producer IP2>  RUNNING

6. コンシューマー VPC、Cloud NAT、インスタンスを設定する

プロデューサー サービスを作成したので、次はコンシューマー VPC とその Cloud NAT ゲートウェイを作成します。

VPC とサブネットを作成したら、TCP 送信元 IP 範囲の IAP を許可する簡単な上り(内向き)ファイアウォール ルールを追加します。これにより、gcloud を使用してコンシューマー インスタンスに直接 SSH 接続できるようになります。

次に、手動割り振りモードで単純な Cloud NAT ゲートウェイを作成し、それに関連付けられた予約済みアドレス「nat-address-1」を作成します。Codelab の以降のパートでは、ゲートウェイの構成を更新して動的ポート割り当てを有効にし、後でカスタムルールを追加します。

まず、VPC を作成します。Cloud Shell から:

gcloud compute networks create consumer-vpc --subnet-mode custom

出力:

Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/global/networks/consumer-vpc].
NAME          SUBNET_MODE  BGP_ROUTING_MODE  IPV4_RANGE  GATEWAY_IPV4
consumer-vpc  CUSTOM       REGIONAL

Instances on this network will not be reachable until firewall rules
are created. As an example, you can allow all internal traffic between
instances as well as SSH, RDP, and ICMP by running:

$ gcloud compute firewall-rules create <FIREWALL_NAME> --network consumer-vpc --allow tcp,udp,icmp --source-ranges <IP_RANGE>
$ gcloud compute firewall-rules create <FIREWALL_NAME> --network consumer-vpc --allow tcp:22,tcp:3389,icmp

次に、us-east4 にサブネットを作成します。Cloud Shell から:

gcloud compute networks subnets create cons-net-e4 \
   --network consumer-vpc --range 10.0.0.0/24 --region us-east4

出力:

Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/subnetworks/cons-net-e4].
NAME         REGION    NETWORK       RANGE        STACK_TYPE  IPV6_ACCESS_TYPE  IPV6_CIDR_RANGE  EXTERNAL_IPV6_CIDR_RANGE
cons-net-e4  us-east4  consumer-vpc  10.0.0.0/24  IPV4_ONLY

次に、IAP 範囲のアドレスがポート 22 のコンシューマー インスタンスに到達できるようにする VPC ファイアウォール ルールを作成します。

最初のファイアウォール ルールについては、Cloud Shell から次のコマンドを実行します。

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

出力:

Creating firewall...⠹Created [https://www.googleapis.com/compute/v1/projects/<Project-ID>/global/firewalls/consumer-allow-iap].
Creating firewall...done.
NAME                 NETWORK       DIRECTION  PRIORITY  ALLOW     DENY  DISABLED
consumer-allow-iap  consumer-vpc  INGRESS    1000      tcp:22        False

NAT ゲートウェイを作成する前に、まず Cloud Router インスタンスを作成する必要があります(プライベート ASN 番号を使用しますが、このラボのアクティビティには関係ありません)。Cloud Shell から:

gcloud compute routers create consumer-cr \
--region=us-east4 --network=consumer-vpc \
 --asn=65501

出力:

Creating router [consumer-cr]...done.
NAME         REGION       NETWORK
consumer-cr  us-east4  consumer-vpc

次に、NAT ゲートウェイ インスタンスを作成します。Cloud Shell から:

gcloud compute routers nats create consumer-nat-gw \
    --router=consumer-cr \
    --router-region=us-east4 \
    --nat-all-subnet-ip-ranges \
    --nat-external-ip-pool=nat-address-1

出力:

Creating NAT [consumer-nat-gw] in router [consumer-cr]...done.

デフォルトでは、Cloud NAT ゲートウェイは minPortsPerVm が 64 に設定されて作成されます。

コンシューマー テスト インスタンスを作成します。ここで予約済みのプロデューサー IP を入力して、後でインスタンス内で参照できるようにします。Cloud Shell から:

gcloud compute instances create consumer-instance-1 --zone=us-east4-a \
--machine-type=e2-medium --network-interface=subnet=cons-net-e4,no-address \
--metadata=producer-service-ip1=$producerip1,producer-service-ip2=$producerip2

gcloud compute instances create consumer-instance-2 --zone=us-east4-a \
--machine-type=e2-medium --network-interface=subnet=cons-net-e4,no-address \
--metadata=producer-service-ip1=$producerip1,producer-service-ip2=$producerip2

出力:

Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/zones/us-east4-a/instances/consumer-instance-1].
NAME                ZONE        MACHINE_TYPE  PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP  STATUS
consumer-instance-1  us-east4-a  e2-medium                  10.0.0.2                  RUNNING

Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/zones/us-east4-a/instances/consumer-instance-2].
NAME                ZONE        MACHINE_TYPE  PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP  STATUS
consumer-instance-2  us-east4-a  e2-medium                  10.0.0.3                  RUNNING

7. デフォルトの Cloud NAT の動作を確認する

この時点で、コンシューマー インスタンスはデフォルトの Cloud NAT の動作を使用します。この動作では、すべての外部アドレスとの通信に同じ予約済み IP「nat-address-1」が使用されます。Cloud NAT でも DPA はまだ有効になっていません。

次のコマンドを実行して、Cloud NAT がコンシューマー インスタンスに割り当てたポートを確認します。

gcloud  compute routers get-nat-mapping-info consumer-cr --region=us-east4

出力例

---
instanceName: consumer-instance-1
interfaceNatMappings:
- natIpPortRanges:
  - <NAT Consumer IP1>:1024-1055
  numTotalDrainNatPorts: 0
  numTotalNatPorts: 32
  sourceAliasIpRange: ''
  sourceVirtualIp: 10.0.0.2
- natIpPortRanges:
  - <NAT Consumer IP1>:32768-32799
  numTotalDrainNatPorts: 0
  numTotalNatPorts: 32
  sourceAliasIpRange: ''
  sourceVirtualIp: 10.0.0.2
---
instanceName: consumer-instance-2
interfaceNatMappings:
- natIpPortRanges:
  - <NAT Address IP1>:1056-1087
  numTotalDrainNatPorts: 0
  numTotalNatPorts: 32
  sourceAliasIpRange: ''
  sourceVirtualIp: 10.0.0.3
- natIpPortRanges:
  - <NAT Address IP1>:32800-32831
  numTotalDrainNatPorts: 0
  numTotalNatPorts: 32
  sourceAliasIpRange: ''
  sourceVirtualIp: 10.0.0.3

上記の出力からわかるように、Cloud NAT は同じ外部 IP nat-address-1 からインスタンスごとに 64 個のポートを割り当てています。

DPA を有効にする前に、並行して開くことができる接続の数を検証しましょう。

最初のコンシューマー インスタンスに SSH 接続します。Cloud Shell から:

gcloud compute ssh consumer-instance-1 --zone=us-east4-a

これでインスタンス シェルが表示されます。

出力例(簡潔にするため、完全な出力は切り捨てられています)

External IP address was not found; defaulting to using IAP tunneling.
...
...
<username>@consumer-instance-1:~$

コンシューマー インスタンス内で、まず両方のプロデューサー IP を取得し、環境変数として設定します。

export producerip1=`curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/producer-service-ip1" -H "Metadata-Flavor: Google"`

export producerip2=`curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/producer-service-ip2" -H "Metadata-Flavor: Google"`

次に、両方のプロデューサー インスタンスに curl を実行して、正常に到達できることを確認します。

<username>@consumer-instance-1:~$ curl http://$producerip1/nginx/
<html><body><h1>This is producer instance 1</h1>
</body></html>
<username>@consumer-instance-1:~$ curl http://$producerip2/nginx/
<html><body><h1>This is producer instance 2</h1>
</body></html>

次に、ループで curl を実行して、プロデューサー インスタンスの 1 つに並列接続を多数作成してみましょう。Cloud NAT では、クローズされたソケットを 2 分間再利用できないことに注意してください。したがって、2 分以内にすべての接続試行をループ処理できる限り、この方法で並列接続をシミュレートできます。

インスタンスの SSH セッションで次のコマンドを実行します。

while true; do for i in {1..64}; do curl -s -o /dev/null --connect-timeout 5 http://$producerip1/nginx/; if [ $? -ne 0 ] ; then echo -e "\nConnection # $i failed" ; else echo -en "\rConnection # $i successful"; fi; done; echo -e "\nLoop Done, Sleeping for 150s"; sleep 150; done

64 個の並列接続を正常に開くことができ、スクリプトは次の内容を出力します。

Connection # 64 successful

Loop Done, Sleeping for 150s
Connection # 64 successful

Loop Done, Sleeping for 150s

64 個を超える並列接続ができないことを確認するには、まず 2 分間待って、古いソケットがすべてクリアされるようにします。次に、同じ 1 行のコマンドを次のように調整して、再度実行します。

while true; do for i in {1..70}; do curl -s -o /dev/null --connect-timeout 5 http://$producerip1/nginx/; if [ $? -ne 0 ] ; then echo -e "\nConnection # $i failed" ; else echo -en "\rConnection # $i successful"; fi; done; echo -e "\nLoop Done, Sleeping for 150s"; sleep 150; done

次の出力が想定されます。

Connection # 64 successful
Connection # 65 failed
Connection # 66 failed
Connection # 67 failed
Connection # 68 failed
Connection # 69 failed
Connection # 70 failed

Loop Done, Sleeping for 150s

これは、最初の 64 個の接続は成功しましたが、残りの 6 個の接続はポートが使用できないため失敗したことを示します。

それでは、SSH シェルを終了して、次のセクションで DPA を有効にしましょう。

8. DPA を有効にして動作を検証する

次の gcloud コマンドを実行します。これにより、DPA が有効になり、VM あたりの最小ポート割り当てが 64 に、最大ポート割り当てが 1,024 に設定されます。

gcloud alpha compute routers nats update consumer-nat-gw --router=consumer-cr \
--region=us-east4 --min-ports-per-vm=64 --max-ports-per-vm=1024 \
--enable-dynamic-port-allocation

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

Updating nat [consumer-nat-gw] in router [consumer-cr]...done.

get-nat-mapping-info を再度実行して、両方のインスタンスに割り当てられているポートが 64 個のみであることを確認します。

gcloud  compute routers get-nat-mapping-info consumer-cr --region=us-east4

出力例(簡潔にするため一部を省略)

---
instanceName: consumer-instance-1
...
  - <NAT Consumer IP1>:1024-1055
  numTotalNatPorts: 32
...
- natIpPortRanges:
  - <NAT Consumer IP1>:32768-32799
  numTotalNatPorts: 32
...
---
instanceName: consumer-instance-2
...
  - <NAT Address IP1>:1056-1087
  numTotalNatPorts: 32
...
  - <NAT Address IP1>:32800-32831
  numTotalNatPorts: 32
...

インスタンスはまだポートをアクティブに使用していないため、ポート割り当てはほとんど変更されていません。

インスタンスに SSH で接続します。

gcloud compute ssh consumer-instance-1 --zone=us-east4-a

プロデューサー IP 環境変数を再エクスポートします。

export producerip1=`curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/producer-service-ip1" -H "Metadata-Flavor: Google"`

export producerip2=`curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/producer-service-ip2" -H "Metadata-Flavor: Google"`

前のループを再実行して、並列接続をシミュレートします。

while true; do for i in {1..70}; do curl -s -o /dev/null --connect-timeout 5 http://$producerip1/nginx/; if [ $? -ne 0 ] ; then echo -e "\nConnection # $i failed" ; else echo -en "\rConnection # $i successful"; fi; done; echo -e "\nLoop Done, Sleeping for 150s"; sleep 150; done

次の出力が表示されます。

Connection # 64 successful
Connection # 65 failed

Connection # 66 failed
Connection # 70 successful
Loop Done, Sleeping for 150s

何が起こったのでしょうか。Cloud NAT はポート使用量の増加に応じてポート割り当てを増やしますが、ネットワーキング レイヤ全体でプログラミングされるまでに時間がかかります。そのため、残りの接続試行が正常に完了するまでに、1 ~ 3 回の接続タイムアウトが発生します。

curl のタイムアウトは 5 秒と短く設定されていますが、タイムアウトが長いアプリケーションは、DPA がポート割り当てを増やしている間も接続を正常に完了できるはずです。

このランプアップ動作は、次のように 1024 回の接続試行のループを実行すると、より明確に確認できます。

while true; do for i in {1..1024}; do curl -s -o /dev/null --connect-timeout 5 http://$producerip1/nginx/; if [ $? -ne 0 ] ; then echo -e "\nConnection # $i failed" ; else echo -en "\rConnection # $i successful"; fi; done; echo -e "\nLoop Done, Sleeping for 150s"; sleep 150; done

次の出力が表示されるはずです。

Connection # 64 successful
Connection # 65 failed

Connection # 66 failed
Connection # 129 successful
Connection # 130 failed

Connection # 131 failed
Connection # 258 successful
Connection # 259 failed

Connection # 260 failed
Connection # 515 successful
Connection # 516 failed

Connection # 1024 successful
Loop Done, Sleeping for 150s

Cloud NAT はポートを 2 の累乗で割り振るため、各ステップで割り振りが実質的に 2 倍になります。このため、64 ~ 1024 の間の 2 の累乗の周辺で接続タイムアウトがハイライト表示されます。

maxPortsPerVM を 1024 に設定したため、1024 を超える接続は想定していません。これをテストするには、1024 より大きいカウントで curl ループを再実行します(古いポートをリセットするために 2 分間待機します)。

while true; do for i in {1..1035}; do curl -s -o /dev/null --connect-timeout 5 http://$producerip1/nginx/; if [ $? -ne 0 ] ; then echo -e "\nConnection # $i failed" ; else echo -en "\rConnection # $i successful"; fi; done; echo -e "\nLoop Done, Sleeping for 150s"; sleep 150; done

予想どおり、出力には 1, 024 を超える接続が失敗し始めることが示されています。

<truncated output>
...
Connection # 1028 successful
Connection # 1029 failed
Connection # 1030 failed
Connection # 1031 failed
Connection # 1032 failed
Connection # 1033 failed
Connection # 1034 failed
Connection # 1035 failed
...
Loop Done, Sleeping for 150s

maxPortsPerVM を 1024 に設定することで、Cloud NAT に VM あたりのポート割り当てを 1024 を超えてスケーリングしないように指示しました。

SSH セッションを終了して get-nat-mapping-info をすばやく再実行すると、割り当てられた追加のポートを確認できます。

gcloud  compute routers get-nat-mapping-info consumer-cr --region=us-east4

次の出力を確認します。

---
instanceName: consumer-instance-1
interfaceNatMappings:
- natIpPortRanges:
  - <NAT Address IP1>:1024-1055
  - <NAT Address IP1>1088-1119
  -<NAT Address IP1>:1152-1215
  - <NAT Address IP1>:1280-1407
  - <NAT Address IP1>:1536-1791
  numTotalDrainNatPorts: 0
  numTotalNatPorts: 512
  sourceAliasIpRange: ''
  sourceVirtualIp: 10.0.0.2
- natIpPortRanges:
  - <NAT Address IP1>:32768-32799
  - <NAT Address IP1>:32832-32863
  - <NAT Address IP1>:32896-32959
  - <NAT Address IP1>:33024-33151
  - <NAT Address IP1>:33536-33791
  numTotalDrainNatPorts: 0
  numTotalNatPorts: 512
  sourceAliasIpRange: ''
  sourceVirtualIp: 10.0.0.2
---
instanceName: consumer-instance-2
interfaceNatMappings:
- natIpPortRanges:
  - <NAT Address IP1>:1056-1087
  numTotalDrainNatPorts: 0
  numTotalNatPorts: 32
  sourceAliasIpRange: ''
  sourceVirtualIp: 10.0.0.3
- natIpPortRanges:
  - <NAT Address IP1>:32800-32831
  numTotalDrainNatPorts: 0
  numTotalNatPorts: 32
  sourceAliasIpRange: ''
  sourceVirtualIp: 10.0.0.3

consumer-instance-1 には 1, 024 個のポートが割り当てられていますが、consumer-instance-2 には 64 個のポートしか割り当てられていません。これは DPA 以前には容易に実現できなかったものであり、Cloud NAT における DPA の威力をまさに示すものです。

2 分待ってから get-nat-mapping-info コマンドを再実行すると、consumer-instance-1 が最小値の 64 ポートに戻っていることがわかります。DPA がポート割り当てを増やすだけでなく、使用されていないときにポートを解放して、同じ NAT ゲートウェイの背後にある他のインスタンスで使用できるようにする機能も示しています。

9. DPA で Cloud NAT ルールをテストする

また、Cloud NAT の NAT ルール機能も最近リリースされました。これにより、特定の外部宛先に特定の NAT IP を使用するルールを作成できます。詳細については、NAT ルールのドキュメント ページをご覧ください。

この演習では、DPA と NAT ルールの間のやり取りを観察します。まず、producer-address-2 にアクセスするときに nat-address-2 を使用する NAT ルールを定義します。

次の gcloud コマンドを実行します。このコマンドは、

gcloud alpha compute routers nats rules create 100 \
 --match='destination.ip == "'$producerip2'"' \
 --source-nat-active-ips=nat-address-2 --nat=consumer-nat-gw \
 --router=consumer-cr --router-region=us-east4

次の出力が表示されます。

Updating nat [consumer-nat-gw] in router [consumer-cr]...done.

次に、get-nat-mapping-info を再実行して、新しい NAT ルールの効果を確認します。

gcloud alpha compute routers get-nat-mapping-info consumer-cr --region=us-east4

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

---
instanceName: consumer-instance-1
interfaceNatMappings:
- natIpPortRanges:
  - <NAT Address IP1>:1024-1055
  numTotalDrainNatPorts: 0
  numTotalNatPorts: 32
  ruleMappings:
  - natIpPortRanges:
    - <NAT Address IP2>:1024-1055
    numTotalDrainNatPorts: 0
    numTotalNatPorts: 32
    ruleNumber: 100
  sourceAliasIpRange: ''
  sourceVirtualIp: 10.0.0.2
- natIpPortRanges:
  - <NAT Address IP1>:32768-32799
  numTotalDrainNatPorts: 0
  numTotalNatPorts: 32
  ruleMappings:
  - natIpPortRanges:
    - <NAT Address IP2>:32768-32799
    numTotalDrainNatPorts: 0
    numTotalNatPorts: 32
    ruleNumber: 100
  sourceAliasIpRange: ''
  sourceVirtualIp: 10.0.0.2

ruleMappings 階層の nat-address-2 用に、指定された最小値である 64 個の追加ポートが割り当てられています。

インスタンスが NAT ルールで指定された宛先に多数の接続を開いた場合はどうなるでしょうか。Let's find out.(HONEY の節約額を確認してみましょう。)

インスタンスに SSH で接続します。

gcloud compute ssh consumer-instance-1 --zone=us-east4-a

プロデューサー IP 環境変数を再エクスポートします。

export producerip1=`curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/producer-service-ip1" -H "Metadata-Flavor: Google"`

export producerip2=`curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/producer-service-ip2" -H "Metadata-Flavor: Google"`

次に、今度は producerip2 に対して curl ループを再実行します。

while true; do for i in {1..1024}; do curl -s -o /dev/null --connect-timeout 5 http://$producerip2/nginx/; if [ $? -ne 0 ] ; then echo -e "\nConnection # $i failed" ; else echo -en "\rConnection # $i successful"; fi; done; echo -e "\nLoop Done, Sleeping for 150s"; sleep 150; done

次のような出力が返されるはずです。

Connection # 64 successful
Connection # 65 failed

Connection # 66 failed
Connection # 129 successful
Connection # 130 failed

Connection # 131 failed
Connection # 258 successful
Connection # 259 failed

Connection # 260 failed
Connection # 515 successful
Connection # 516 failed

Connection # 1024 successful
Loop Done, Sleeping for 150s

基本的には、前のテストをミラーリングします。インスタンスの SSH セッションを終了して、NAT マッピングをもう一度見てみましょう。

gcloud alpha compute routers get-nat-mapping-info consumer-cr --region=us-east4

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

---
instanceName: consumer-instance-1
interfaceNatMappings:
- natIpPortRanges:
  - <NAT Address IP1>:1024-1055
  numTotalDrainNatPorts: 0
  numTotalNatPorts: 32
  ruleMappings:
  - natIpPortRanges:
    - <NAT Address IP2>:1024-1055
    - <NAT Address IP2>:1088-1119
    - <NAT Address IP2>:1152-1215
    - <NAT Address IP2>:1280-1407
    - <NAT Address IP2>:1536-1791
    numTotalDrainNatPorts: 0
    numTotalNatPorts: 512
    ruleNumber: 100
  sourceAliasIpRange: ''
  sourceVirtualIp: 10.0.0.2
- natIpPortRanges:
  - <NAT Address IP1>:32768-32799
  numTotalDrainNatPorts: 0
  numTotalNatPorts: 32
  ruleMappings:
  - natIpPortRanges:
    - <NAT Address IP2>:32768-32799
    - <NAT Address IP2>:32832-32863
    - <NAT Address IP2>:32896-32959
    - <NAT Address IP2>:33024-33151
    - <NAT Address IP2>:33280-33535
    numTotalDrainNatPorts: 0
    numTotalNatPorts: 512
    ruleNumber: 100
  sourceAliasIpRange: ''
  sourceVirtualIp: 10.0.0.2
---
instanceName: consumer-instance-2
interfaceNatMappings:
- natIpPortRanges:
  - <NAT Address IP1>:1056-1087
  numTotalDrainNatPorts: 0
  numTotalNatPorts: 32
  ruleMappings:
  - natIpPortRanges:
    - <NAT Address IP2>:1056-1087
    numTotalDrainNatPorts: 0
    numTotalNatPorts: 32
    ruleNumber: 100
  sourceAliasIpRange: ''
  sourceVirtualIp: 10.0.0.3
- natIpPortRanges:
  - <NAT Address IP1>:32800-32831
  numTotalDrainNatPorts: 0
  numTotalNatPorts: 32
  ruleMappings:
  - natIpPortRanges:
    - <NAT Address IP2>:32800-32831
    numTotalDrainNatPorts: 0
    numTotalNatPorts: 32
    ruleNumber: 100
  sourceAliasIpRange: ''
  sourceVirtualIp: 10.0.0.3

---
instanceName: consumer-instance-1
interfaceNatMappings:
- natIpPortRanges:
  - <NAT Address IP1>:1024-1055
  numTotalDrainNatPorts: 0
  numTotalNatPorts: 32
  ruleMappings:
  - natIpPortRanges:
    - <NAT Address IP2>:1024-1055
    numTotalDrainNatPorts: 0
    numTotalNatPorts: 32
    ruleNumber: 100
  sourceAliasIpRange: ''
  sourceVirtualIp: 10.0.0.2
- natIpPortRanges:
  - <NAT Address IP1>:32768-32799
  numTotalDrainNatPorts: 0
  numTotalNatPorts: 32
  ruleMappings:
  - natIpPortRanges:
    - <NAT Address IP2>:32768-32799
    numTotalDrainNatPorts: 0
    numTotalNatPorts: 32
    ruleNumber: 100
  sourceAliasIpRange: ''
  sourceVirtualIp: 10.0.0.2

上記のように、consumer-instance-1 のデフォルトの NAT IP(nat-address-1 の IP)には 64 個のポートしか割り当てられていませんが、NAT ルールの IP(nat-address-2 の IP)には 1,024 個のポートが割り当てられています。その間、consumer-instance-2 はすべての NAT IP に 64 個のポートのデフォルト割り当てを維持していました。

演習として、逆のケースをテストできます。Cloud NAT にすべての追加ポートの割り当てを解除させ、producerip1 に対して curl ループを実行して、get-nat-mapping-info の出力に対する影響を確認します。

10. クリーンアップの手順

繰り返し費用が発生しないようにするには、この Codelab に関連するすべてのリソースを削除します。

まず、すべてのインスタンスを削除します。

Cloud Shell から:

gcloud compute instances delete consumer-instance-1 consumer-instance-2 \
 producer-instance-1 producer-instance-2 \
 --zone us-east4-a --quiet

予想される出力 :

Deleted [https://www.googleapis.com/compute/v1/projects/<Project Id>/zones/us-east4-a/instances/consumer-instance-1].
Deleted [https://www.googleapis.com/compute/v1/projects/<Project Id>/zones/us-east4-a/instances/consumer-instance-2].
Deleted [https://www.googleapis.com/compute/v1/projects/<Project Id>/zones/us-east4-a/instances/producer-instance-1].
Deleted [https://www.googleapis.com/compute/v1/projects/<Project Id>/zones/us-east4-a/instances/producer-instance-2].

次に、Cloud Router を削除します。Cloud Shell から:

gcloud compute routers delete consumer-cr \
 --region us-east4 --quiet

次の出力が表示されます。

Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/routers/consumer-cr].

すべての外部 IP アドレスを解放します。Cloud Shell から:

gcloud compute addresses delete nat-address-1 \
 nat-address-2 producer-address-1 \
 producer-address-2 --region us-east4 --quiet

次の出力が表示されます。

Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/nat-address-1].
Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/nat-address-2].
Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/nat-address-3].
Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/producer-address-1].
Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/producer-address-2].

VPC ファイアウォール ルールを削除します。Cloud Shell から:

gcloud compute firewall-rules delete consumer-allow-iap \
 producer-allow-80 --quiet

次の出力が表示されます。

Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/global/firewalls/consumer-allow-iap].
Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/global/firewalls/producer-allow-80].

サブネットを削除します。Cloud Shell から:

gcloud compute networks subnets delete cons-net-e4 \
 prod-net-e4 --region=us-east4 --quiet

次の出力が表示されます。

Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/subnetworks/cons-net-e4].
Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/subnetworks/prod-net-e4].

最後に、VPC を削除します。Cloud Shell から:

gcloud compute networks delete consumer-vpc \
 producer-vpc --quiet

次の出力が表示されます。

Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/global/networks/consumer-vpc].
Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/global/networks/producer-vpc].

11. 完了

これで、Cloud NAT DPA ラボは完了です。

学習した内容

  • DPA の準備として Cloud NAT ゲートウェイを設定する方法。
  • DPA を使用せずにポート割り当てを検査する方法。
  • NAT ゲートウェイの DPA を有効にして構成する方法。
  • 並行下り(外向き)接続を実行して、DPA の効果を確認する方法。
  • DPA が有効になっている NAT ゲートウェイに NAT ルールを追加する方法。
  • 複数の宛先に下り(外向き)接続を実行して、ルールによる DPA の動作を確認する方法。

次のステップ

©Google, Inc. or its affiliates. All rights reserved. Do not distribute.