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 からアクセスできます。

セルフペース型の環境設定
- Google Cloud Console にログインして、プロジェクトを新規作成するか、既存のプロジェクトを再利用します。Gmail アカウントも Google Workspace アカウントもまだお持ちでない場合は、アカウントを作成してください。



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

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

この仮想マシンには、必要な開発ツールがすべて用意されています。永続的なホーム ディレクトリが 5 GB 用意されており、Google Cloud で稼働します。そのため、ネットワークのパフォーマンスと認証機能が大幅に向上しています。このラボでの作業はすべて、ブラウザから実行できます。
3. ラボの設定
このラボでは、プロジェクトを使用して、それぞれにサブネットを含む 2 つの VPC を作成します。外部 IP アドレスを予約し、Cloud NAT ゲートウェイ(Cloud Router を使用)、2 つのプロデューサー インスタンス、2 つのコンシューマー インスタンスを作成して構成します。デフォルトの Cloud NAT の動作を検証したら、動的ポート割り当てを有効にして、その動作を検証します。最後に、NAT ルールを構成し、DPA と NAT ルールの間の相互作用を確認します。
ネットワーキング アーキテクチャの概要:

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 の動作を確認する方法。
次のステップ
- 動的ポート割り当てのドキュメント ページを参照する
- アプリケーションで NAT タイムアウトとポート割り当て値を調整してテストします。
- Google Cloud Platform のネットワーキングについて学習する
©Google, Inc. or its affiliates. All rights reserved. Do not distribute.