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

۱. مرور کلی

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

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

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

آنچه یاد خواهید گرفت

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

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

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

۲. استفاده از کنسول ابری گوگل و کلود شل

برای تعامل با GCP، در طول این آزمایش از هر دو کنسول ابری گوگل و پوسته ابری استفاده خواهیم کرد.

کنسول ابری گوگل

کنسول ابری از طریق آدرس https://console.cloud.google.com قابل دسترسی است.

75eef5f6fd6d7e41.png

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

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

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

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

شروع پوسته ابری

اگرچه می‌توان از راه دور و از طریق لپ‌تاپ، گوگل کلود را مدیریت کرد، اما در این آزمایشگاه کد، از گوگل کلود شل ، یک محیط خط فرمان که در فضای ابری اجرا می‌شود، استفاده خواهید کرد.

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

bce75f34b2c53987.png

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

f6ef2b5f13479f3a.png

این ماشین مجازی مجهز به تمام ابزارهای توسعه مورد نیاز شماست. این ماشین یک دایرکتوری خانگی دائمی ۵ گیگابایتی ارائه می‌دهد و روی فضای ابری گوگل اجرا می‌شود که عملکرد شبکه و احراز هویت را تا حد زیادی بهبود می‌بخشد. تمام کارهای شما در این آزمایشگاه را می‌توان به سادگی با یک مرورگر انجام داد.

۳. چیدمان آزمایشگاه

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

مروری بر معماری شبکه:

a21caa6c333909d8.png

۴. رزرو آدرس‌های IP خارجی

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

از کلود شل:

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>

۵. تنظیمات 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 بتوانند به نمونه‌های تولیدکننده روی پورت ۸۰۸۰ دسترسی پیدا کنند.

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

۶. راه‌اندازی VPC مصرف‌کننده، Cloud NAT و Instances

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

پس از ایجاد VPC و زیرشبکه، یک قانون فایروال ورودی ساده اضافه خواهیم کرد تا به IAP برای محدوده‌های IP منبع TCP اجازه دسترسی بدهد. این به ما امکان می‌دهد تا مستقیماً با استفاده از 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

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

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

نمونه‌های آزمایشی مصرف‌کننده را ایجاد کنید. ما 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

۷. رفتار پیش‌فرض 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 اختصاص داده است.

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

دستور زیر را در جلسه 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

انتظار می‌رود که بتوانید با موفقیت ۶۴ اتصال موازی را باز کنید و اسکریپت باید موارد زیر را چاپ کند

Connection # 64 successful

Loop Done, Sleeping for 150s
Connection # 64 successful

Loop Done, Sleeping for 150s

برای اینکه ببینیم نمی‌توانیم از ۶۴ اتصال موازی فراتر برویم، ابتدا ۲ دقیقه صبر کنید تا تمام سوکت‌های قدیمی پاک شوند. سپس همان کد تک‌خطی را به صورت زیر تغییر دهید و دوباره اجرا کنید.

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

این نشان می‌دهد که در حالی که ۶۴ اتصال اول موفقیت‌آمیز بوده‌اند، ۶ اتصال باقی‌مانده به دلیل در دسترس نبودن پورت‌ها با شکست مواجه شده‌اند.

پس بیایید کاری در مورد آن انجام دهیم، از پوسته SSH خارج شویم و DPA را در بخش بعدی فعال کنیم.

۸. فعال کردن DPA و اعتبارسنجی رفتار آن

دستور gcloud زیر را اجرا کنید، که DPA را فعال می‌کند، حداقل پورت اختصاص داده شده به هر ماشین مجازی را روی ۶۴ و حداکثر پورت اختصاص داده شده را روی ۱۰۲۴ تنظیم می‌کند.

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 دوباره اجرا کنیم تا مطمئن شویم که هر دو نمونه هنوز فقط ۶۴ پورت اختصاص داده شده‌اند.

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 با افزایش استفاده از پورت، تخصیص پورت را افزایش می‌دهد، اما برنامه‌ریزی این کار در سراسر لایه شبکه کمی زمان می‌برد. از این رو، قبل از اینکه بقیه تلاش‌های اتصال را با موفقیت انجام دهیم، ۱ تا ۳ بار وقفه اتصال را مشاهده می‌کنیم.

ما یک زمان وقفه تهاجمی (۵ ثانیه) برای curl تعیین کرده‌ایم، اما برنامه‌هایی با زمان وقفه طولانی‌تر باید بتوانند در حالی که DPA تخصیص پورت‌ها را افزایش می‌دهد، اتصالات را با موفقیت تکمیل کنند.

این رفتار افزایش سرعت را می‌توان با اجرای حلقه برای ۱۰۲۴ تلاش اتصال به صورت زیر، واضح‌تر مشاهده کرد.

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 پورت‌ها را با توان‌های ۲ اختصاص می‌دهد، اساساً تخصیص‌ها را در هر مرحله دو برابر می‌کند، می‌بینیم که زمان‌های اتصال در حدود توان‌های ۲ بین ۶۴ تا ۱۰۲۴ هایلایت شده‌اند.

از آنجایی که maxPortsPerVM روی ۱۰۲۴ تنظیم کرده‌ایم، انتظار نداریم بتوانیم بیش از ۱۰۲۴ اتصال برقرار کنیم. می‌توانیم این را با اجرای مجدد حلقه curl با تعداد بالاتر از ۱۰۲۴ (پس از ۲ دقیقه انتظار برای تنظیم مجدد پورت‌های قدیمی) آزمایش کنیم.

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

و همانطور که انتظار می‌رفت، خروجی نشان می‌دهد که اتصالات فراتر از ۱۰۲۴ شروع به از کار افتادن می‌کنند.

<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 روی ۱۰۲۴، به Cloud NAT دستور داده‌ایم که هرگز تخصیص پورت‌ها را فراتر از ۱۰۲۴ برای هر ماشین مجازی مقیاس‌بندی نکند.

اگر از جلسه 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 به مدت ۲ دقیقه صبر کنید، متوجه خواهید شد که consumer-instance-1 به حداقل مقدار خود یعنی فقط ۶۴ پورت اختصاص داده شده، بازگشته است. این نشان می‌دهد که DPA نه تنها توانایی افزایش تخصیص پورت‌ها را دارد، بلکه آنها را در صورت عدم استفاده برای استفاده بالقوه توسط سایر نمونه‌های پشت همان NAT Gateway نیز آزاد می‌کند.

۹. تست قوانین Cloud NAT با DPA

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

در این تمرین، ما تعامل بین DPA و قوانین NAT را مشاهده می‌کنیم. ابتدا بیایید یک قانون NAT تعریف کنیم تا هنگام دسترسی به producer-address-2 nat-address-2 -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

توجه کنید که اکنون پورت‌های اضافی (همچنین ۶۴، حداقل مقدار مشخص شده) به طور خاص برای 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 تخصیص‌های پیش‌فرض 64 پورت خود را برای همه IPهای NAT حفظ کرده است.

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

۱۰. مراحل پاکسازی

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

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

از کلود شل:

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].

۱۱. تبریک می‌گویم!

شما آزمایشگاه Cloud NAT DPA را تکمیل کرده‌اید!

آنچه را که پوشش دادید

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

مراحل بعدی

©شرکت گوگل یا شرکت‌های وابسته به آن. تمامی حقوق محفوظ است. توزیع نکنید.