با استفاده از Cloud NAT Dynamic Port Allocation

1. بررسی اجمالی

تخصیص پورت پویا (DPA) یک ویژگی جدید در Cloud NAT است. با فعال بودن DPA، Cloud NAT به صورت پویا تخصیص پورت‌ها را برای نمونه‌ها بسته به نیاز آنها، مقیاس می‌دهد. DPA با حداقل و حداکثر محدودیت پورت پیکربندی شده است به گونه ای که هرگز پورت ها را کمتر از حداقل کاهش نمی دهد یا از حداکثر بزرگتر نمی کند. این به برخی از نمونه‌های پشت دروازه‌های NAT اجازه می‌دهد تا به صورت پویا تعداد اتصالات خود را بدون نیاز به تخصیص پورت‌های بیشتر به همه نمونه‌های پشت Cloud NAT افزایش دهند.

بدون DPA، همه نمونه‌های پشت Cloud NAT به همان تعداد پورت بدون توجه به استفاده اختصاص داده می‌شوند، همانطور که توسط پارامتر minPortsPerVm تعریف شده است.

برای اطلاعات بیشتر لطفاً بخش مستندات در مورد NAT DPA را مرور کنید.

چیزی که یاد خواهید گرفت

  • نحوه راه اندازی یک دروازه NAT Cloud در آماده سازی برای DPA.
  • نحوه بازرسی تخصیص پورت بدون DPA
  • چگونه DPA را برای دروازه NAT فعال و پیکربندی کنیم.
  • نحوه مشاهده اثرات DPA با اجرای اتصالات خروجی موازی
  • چگونه قوانین NAT را با فعال بودن DPA به دروازه NAT اضافه کنیم.
  • نحوه مشاهده رفتار DPA با قوانین با اجرای اتصالات خروجی به مقصدهای متعدد.

آنچه شما نیاز دارید

  • دانش اولیه موتور محاسباتی گوگل
  • دانش پایه شبکه و TCP/IP
  • دانش اولیه خط فرمان یونیکس/لینوکس
  • انجام یک تور شبکه در Google Cloud مانند آزمایشگاه شبکه در Google Cloud مفید است.
  • پروژه Google Cloud با «Alpha Access» فعال است.
  • آشنایی با اصول Cloud NAT

2. استفاده از Google Cloud Console و Cloud Shell

برای تعامل با GCP، از Google Cloud Console و Cloud Shell در سراسر این آزمایشگاه استفاده خواهیم کرد.

Google Cloud Console

در https://console.cloud.google.com می‌توانید به کنسول Cloud دسترسی پیدا کنید.

75eef5f6fd6d7e41.png

تنظیم محیط خود به خود

  1. به Google Cloud Console وارد شوید و یک پروژه جدید ایجاد کنید یا از یک موجود استفاده مجدد کنید. اگر قبلاً یک حساب Gmail یا Google Workspace ندارید، باید یک حساب ایجاد کنید .

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

  • نام پروژه نام نمایشی برای شرکت کنندگان این پروژه است. این یک رشته کاراکتری است که توسط API های Google استفاده نمی شود و می توانید هر زمان که بخواهید آن را به روز کنید.
  • شناسه پروژه باید در تمام پروژه‌های Google Cloud منحصربه‌فرد باشد و تغییرناپذیر باشد (پس از تنظیم نمی‌توان آن را تغییر داد). Cloud Console به طور خودکار یک رشته منحصر به فرد تولید می کند. معمولاً برای شما مهم نیست که چیست. در اکثر کدها، باید به شناسه پروژه ارجاع دهید (و معمولاً به عنوان PROJECT_ID شناخته می‌شود)، بنابراین اگر آن را دوست ندارید، یک نمونه تصادفی دیگر ایجاد کنید، یا می‌توانید شناسه پروژه را امتحان کنید و ببینید در دسترس است. سپس پس از ایجاد پروژه "یخ زده" می شود.
  • یک مقدار سوم وجود دارد، یک شماره پروژه که برخی از API ها از آن استفاده می کنند. در مورد هر سه این مقادیر در مستندات بیشتر بیاموزید.
  1. در مرحله بعد، برای استفاده از منابع Cloud/APIها، باید صورتحساب را در کنسول Cloud فعال کنید . اجرا کردن از طریق این کد لبه نباید هزینه زیادی داشته باشد، اگر اصلاً باشد. برای اینکه منابع را خاموش کنید تا بیش از این آموزش متحمل صورتحساب نشوید، دستورالعمل‌های «پاک‌سازی» را که در انتهای Codelab یافت می‌شود دنبال کنید. کاربران جدید Google Cloud واجد شرایط برنامه آزمایشی رایگان 300 دلاری هستند.

Cloud Shell را راه اندازی کنید

در حالی که Google Cloud را می توان از راه دور از لپ تاپ شما کار کرد، در این کد لبه از Google Cloud Shell استفاده خواهید کرد، یک محیط خط فرمان که در Cloud اجرا می شود.

از کنسول GCP روی نماد Cloud Shell در نوار ابزار بالا سمت راست کلیک کنید:

bce75f34b2c53987.png

تهیه و اتصال به محیط فقط چند لحظه طول می کشد. وقتی تمام شد، باید چیزی شبیه به این را ببینید:

f6ef2b5f13479f3a.png

این ماشین مجازی با تمام ابزارهای توسعه که شما نیاز دارید بارگذاری شده است. این یک فهرست اصلی 5 گیگابایتی دائمی را ارائه می دهد و در Google Cloud اجرا می شود و عملکرد و احراز هویت شبکه را تا حد زیادی افزایش می دهد. تمام کارهای شما در این آزمایشگاه به سادگی با یک مرورگر قابل انجام است.

3. راه اندازی آزمایشگاه

برای این آزمایشگاه، شما از یک پروژه استفاده خواهید کرد و دو VPC با یک زیر شبکه در هر کدام ایجاد خواهید کرد. شما آدرس های IP خارجی را رزرو می کنید و سپس یک دروازه NAT Cloud (با یک Cloud Router)، دو نمونه تولید کننده و همچنین دو نمونه مصرف کننده ایجاد و پیکربندی می کنید. پس از تأیید رفتار پیش‌فرض Cloud NAT، Dynamic Port Allocation را فعال کرده و رفتار آن را تأیید می‌کنید. در نهایت، قوانین NAT را نیز پیکربندی کرده و تعامل بین قوانین DPA و NAT را مشاهده خواهید کرد.

نمای کلی معماری شبکه:

a21caa6c333909d8.png

4. آدرس های IP خارجی را رزرو کنید

بیایید تمام آدرس های IP خارجی را برای استفاده در این آزمایشگاه رزرو کنیم. این به شما کمک می کند تا همه قوانین NAT و فایروال مرتبط را در VPC مصرف کننده و تولید کننده بنویسید.

از 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 تولیدکننده اجرا می‌شوند، سرویس اینترنت رو با استفاده از دو 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

در مرحله بعد، بیایید قوانین فایروال VPC را ایجاد کنیم تا آدرس های IP NAT به نمونه های تولید کننده در پورت 8080 برسند.

برای قانون اول، از 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

مرحله بعدی ایجاد دو نمونه تولید کننده است.

نمونه های تولید کننده یک پروکسی ساده nginx را اجرا می کنند.

برای تهیه سریع نمونه ها با تمام نرم افزارهای مورد نیاز، نمونه ها را با یک اسکریپت راه اندازی ایجاد می کنیم که nginx را با استفاده از مدیر بسته Debian APT نصب می کند.

برای اینکه بتوانیم قوانین 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

سپس نمونه دوم را ایجاد کنید. از 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. Consumer VPC، Cloud NAT و Instances را راه اندازی کنید

اکنون که سرویس تولید کننده را ایجاد کرده اید، اکنون زمان ایجاد VPC مصرف کننده و دروازه NAT Cloud آن است.

پس از ایجاد VPC و زیرشبکه، یک قانون فایروال ورودی ساده اضافه می کنیم تا به IAP برای محدوده IP منبع TCP اجازه دهیم. این به ما امکان می دهد مستقیماً با استفاده از gcloud به نمونه های مصرف کننده SSH کنیم.

سپس یک دروازه ساده Cloud NAT در حالت تخصیص دستی و آدرس رزرو شده "nat-address-1" مرتبط با آن ایجاد می کنیم. در بخش‌های بعدی کد لبه، پیکربندی دروازه را برای فعال کردن تخصیص پورت پویا به‌روزرسانی می‌کنیم و بعداً قوانین سفارشی را اضافه می‌کنیم.

ابتدا اجازه دهید 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

در مرحله بعد، بیایید یک قوانین فایروال VPC ایجاد کنیم تا به آدرس های محدوده IAP اجازه دسترسی به نمونه های مصرف کننده در پورت 22 را بدهد.

برای اولین قانون فایروال، موارد زیر را از 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.

توجه داشته باشید که به طور پیش فرض، دروازه NAT Cloud با تنظیم 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 64 پورت را برای هر نمونه از همان IP خارجی nat-address-1 اختصاص داده است.

بیایید قبل از فعال کردن 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"`

سپس سعی کنید به هر دو نمونه تولیدکننده بپیچید تا مطمئن شوید که می توانیم با موفقیت به آنها دسترسی پیدا کنیم.

<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 از طریق یک حلقه، بسیاری از اتصالات موازی را به یکی از نمونه های سازنده ایجاد کنیم. به یاد داشته باشید که Cloud NAT اجازه استفاده مجدد از سوکت های بسته را به مدت 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 دقیقه صبر کنید تا تمام سوکت های قدیمی پاک شوند. سپس همان تک لاینر را به شکل زیر تغییر دهید و دوباره اجرا کنید

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 و حداکثر تخصیص پورت را 1024 تنظیم می کند.

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 وقفه زمانی اتصال را می‌بینیم.

ما یک بازه زمانی تهاجمی برای کرل (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 برجسته شده است.

از آنجایی که ما maxPortsPerVM روی 1024 تنظیم کردیم، انتظار نداریم که بتوانیم بیش از 1024 اتصال داشته باشیم. می‌توانیم آن را با اجرای مجدد حلقه کرل با تعداد بالاتر از 1024 (پس از 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

و همانطور که انتظار می رفت، خروجی نشان می دهد که اتصالات فراتر از 1024 شروع به شکست می کنند

<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 دستور داده‌ایم که هرگز تخصیص پورت‌ها را بیش از 1024 در هر VM مقیاس ندهد.

اگر از جلسه 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 دارای 1024 پورت اختصاص داده شده است، اما consumer-instance-2 تنها 64 پورت اختصاص داده شده است. این قبل از DPA به راحتی امکان پذیر نبود و دقیقاً قدرت DPA را برای Cloud NAT برجسته می کند.

اگر قبل از اجرای مجدد دستور get-nat-mapping-info 2 دقیقه صبر کنید، متوجه خواهید شد که consumer-instance-1 به حداقل مقدار خود یعنی فقط 64 پورت اختصاص داده شده بازگشته است. نشان‌دهنده نه‌تنها توانایی DPA برای افزایش تخصیص پورت، بلکه انتشار آن‌ها در زمانی که برای استفاده بالقوه توسط سایر نمونه‌های پشت همان NAT Gateway استفاده نمی‌شود.

9. قوانین Cloud NAT را با DPA آزمایش کنید

همچنین اخیراً عملکرد قوانین NAT را برای Cloud NAT منتشر کرده‌ایم که به مشتریان امکان می‌دهد قوانینی بنویسند که از IPهای NAT خاص برای مقاصد خارجی خاص استفاده می‌کنند. برای اطلاعات بیشتر، لطفاً به صفحه مستندات قوانین NAT مراجعه کنید.

در این تمرین، تعامل بین قوانین DPA و NAT را مشاهده می کنیم. اجازه دهید ابتدا یک قانون NAT برای استفاده از nat-address-2 هنگام دسترسی به producer-address-2 تعریف کنیم.

دستور gcloud زیر را اجرا کنید که با استفاده از قانون NAT ایجاد می کند

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

توجه داشته باشید که اکنون پورت های اضافی (همچنین در 64، حداقل مشخص شده) به طور خاص برای nat-address-2 تحت سلسله مراتب ruleMappings اختصاص داده شده است.

پس چه اتفاقی می افتد اگر یک نمونه اتصالات زیادی را به مقصد مشخص شده توسط قانون NAT باز کند؟ بیایید دریابیم.

بیایید به 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"`

و حالا بیایید این بار حلقه curl را در مقابل producerip2 دوباره اجرا کنیم

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

همانطور که در بالا مشاهده می کنید، IP پیش فرض NAT consumer-instance-1 (IP برای nat-address-1 ) هنوز فقط 64 پورت اختصاص داده شده است، اما IP قانون NAT (IP برای nat-address-2 ) دارای 1024 پورت است. اختصاص داده شده است. در تمام مدت consumer-instance-2 تخصیص پیش‌فرض ۶۴ پورت خود را برای تمام IP‌های NAT حفظ کرد.

به عنوان یک تمرین، می توانید حالت معکوس را آزمایش کنید. اجازه دهید Cloud NAT همه پورت‌های اضافی را اختصاص دهد، سپس حلقه curl را در مقابل producerip1 اجرا کنید و اثرات آن را روی خروجی get-nat-mapping-info مشاهده کنید.

10. مراحل پاکسازی

برای جلوگیری از شارژ مجدد، باید تمام منابع مرتبط با این کد لبه را حذف کنید.

ابتدا تمام نمونه ها را حذف کنید.

از 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 را تکمیل کرده اید!

آنچه شما پوشش داده اید

  • نحوه راه اندازی یک دروازه NAT Cloud در آماده سازی برای DPA.
  • نحوه بازرسی تخصیص پورت بدون DPA
  • چگونه DPA را برای دروازه NAT فعال و پیکربندی کنیم.
  • نحوه مشاهده اثرات DPA با اجرای اتصالات خروجی موازی
  • چگونه قوانین NAT را با فعال بودن DPA به دروازه NAT اضافه کنیم.
  • نحوه مشاهده رفتار DPA با قوانین با اجرای اتصالات خروجی به مقصدهای متعدد.

مراحل بعدی

©Google، Inc. یا شرکت های وابسته به آن. تمامی حقوق محفوظ است. توزیع نکنید.