استخدام تخصيص منفذ ديناميكي NAT في السحابة الإلكترونية

1. نظرة عامة

تخصيص المنافذ الديناميكي (DPA) هو ميزة جديدة في Cloud NAT. عند تفعيل هذه الميزة، تعمل Cloud NAT على زيادة أو تقليل عمليات تخصيص المنافذ بشكل ديناميكي للمثيلات استنادًا إلى احتياجاتها. يتم إعداد DPA باستخدام حدود دنيا وقصوى للمنافذ حتى لا يتم تقليل عدد المنافذ إلى أقل من الحد الأدنى أو زيادته إلى أكثر من الحد الأقصى. يتيح ذلك لبعض الأجهزة الافتراضية التي تستخدم بوابات NAT توسيع عدد الاتصالات بشكل ديناميكي بدون الحاجة إلى تخصيص المزيد من المنافذ لجميع الأجهزة الافتراضية التي تستخدم Cloud NAT.

بدون DPA، يتم تخصيص العدد نفسه من المنافذ لجميع مثيلات Cloud NAT بغض النظر عن الاستخدام، وذلك على النحو المحدّد في المَعلمة minPortsPerVm .

لمزيد من المعلومات، يُرجى مراجعة قسم المستندات حول اتفاقية معالجة البيانات في NAT .

ما ستتعلمه

  • كيفية إعداد بوابة Cloud NAT استعدادًا لـ DPA
  • كيفية فحص عمليات تخصيص المنافذ بدون DPA
  • كيفية تفعيل DPA وإعدادها لبوابة NAT
  • كيفية مراقبة تأثيرات DPA من خلال تشغيل اتصالات خروج متوازية
  • كيفية إضافة قواعد NAT إلى NAT Gateway مع تفعيل DPA
  • كيفية الاطّلاع على سلوك "معالجة البيانات الآلية" باستخدام "القواعد" من خلال تنفيذ عمليات ربط خروج إلى وجهات متعددة

المتطلبات

  • معرفة أساسية بخدمة Google Compute Engine
  • معرفة أساسية بالشبكات وبروتوكول TCP/IP
  • معرفة أساسية بسطر الأوامر في نظامَي Unix وLinux
  • من المفيد أن تكون قد أكملت جولة في الاتصال بالشبكات في Google Cloud، مثل تجربة الاتصال بالشبكات في Google Cloud.
  • مشروع على Google Cloud تم تفعيل "إصدار تجريبي" فيه
  • فهم أساسيات Cloud NAT

2. استخدام Google Cloud Console وCloud Shell

للتفاعل مع Google Cloud Platform، سنستخدم كلاً من Google Cloud Console وCloud Shell خلال هذا الدرس التطبيقي.

Google Cloud Console

يمكن الوصول إلى Cloud Console على https://console.cloud.google.com.

75eef5f6fd6d7e41.png

إعداد البيئة بالسرعة التي تناسبك

  1. سجِّل الدخول إلى Google Cloud Console وأنشِئ مشروعًا جديدًا أو أعِد استخدام مشروع حالي. إذا لم يكن لديك حساب على Gmail أو Google Workspace، عليك إنشاء حساب.

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

  • اسم المشروع هو الاسم المعروض للمشاركين في هذا المشروع. وهي سلسلة من الأحرف لا تستخدمها Google APIs، ويمكنك تعديلها في أي وقت.
  • يجب أن يكون رقم تعريف المشروع فريدًا في جميع مشاريع Google Cloud، كما أنّه غير قابل للتغيير (لا يمكن تغييره بعد ضبطه). تنشئ Cloud Console تلقائيًا سلسلة فريدة، ولا يهمّك عادةً ما هي. في معظم دروس الترميز، عليك الرجوع إلى رقم تعريف المشروع (ويتم تحديده عادةً على أنّه PROJECT_ID)، لذا إذا لم يعجبك، يمكنك إنشاء رقم آخر عشوائي، أو يمكنك تجربة رقمك الخاص ومعرفة ما إذا كان متاحًا. ثم يتم "تجميده" بعد إنشاء المشروع.
  • هناك قيمة ثالثة، وهي رقم المشروع الذي تستخدمه بعض واجهات برمجة التطبيقات. يمكنك الاطّلاع على مزيد من المعلومات عن كل هذه القيم الثلاث في المستندات.
  1. بعد ذلك، عليك تفعيل الفوترة في Cloud Console من أجل استخدام موارد/واجهات برمجة تطبيقات Cloud. لن تكلفك تجربة هذا الدرس التطبيقي حول الترميز الكثير من المال، إن لم تكلفك شيئًا على الإطلاق. لإيقاف الموارد كي لا يتم تحصيل رسوم منك بعد هذا الدرس التطبيقي حول الترميز، اتّبِع أي تعليمات "تنظيف" واردة في نهاية الدرس. يمكن لمستخدمي Google Cloud الجدد الاستفادة من برنامج الفترة التجريبية المجانية بقيمة 300 دولار أمريكي.

بدء Cloud Shell

على الرغم من إمكانية تشغيل Google Cloud عن بُعد من الكمبيوتر المحمول، ستستخدم في هذا الدرس العملي Google Cloud Shell، وهي بيئة سطر أوامر تعمل في السحابة الإلكترونية.

من وحدة تحكّم Google Cloud Platform، انقر على رمز Cloud Shell في شريط الأدوات العلوي الأيسر:

bce75f34b2c53987.png

لن يستغرق توفير البيئة والاتصال بها سوى بضع لحظات. عند الانتهاء، من المفترض أن يظهر لك ما يلي:

f6ef2b5f13479f3a.png

يتم تحميل هذه الآلة الافتراضية مزوّدة بكل أدوات التطوير التي ستحتاج إليها. توفّر هذه الخدمة دليلًا منزليًا ثابتًا بسعة 5 غيغابايت، وتعمل على Google Cloud، ما يؤدي إلى تحسين أداء الشبكة والمصادقة بشكل كبير. يمكن إكمال جميع المهام في هذا التمرين المعملي باستخدام متصفّح فقط.

3- إعداد الدرس التطبيقي

في هذا التمرين العملي، ستستخدم مشروعًا وتنشئ شبكتَي VPC مع شبكة فرعية في كل منهما. ستحجز عناوين IP خارجية، ثم ستنشئ بوابة Cloud NAT وتضبطها (باستخدام Cloud Router)، بالإضافة إلى إنشاء مثيلَين للمنتج ومثيلَين للمستهلك. بعد التحقّق من صحة السلوك التلقائي لخدمة Cloud NAT، عليك تفعيل ميزة "تخصيص المنافذ الديناميكي" والتحقّق من سلوكها. أخيرًا، ستعمل أيضًا على إعداد قواعد NAT ومراقبة التفاعل بين DPA وقواعد NAT.

نظرة عامة على بنية الشبكات:

a21caa6c333909d8.png

4. حجز عناوين IP خارجية

لنحجز جميع عناوين IP الخارجية التي سيتم استخدامها في هذا الدرس التطبيقي. سيساعدك ذلك في كتابة جميع قواعد NAT وجدار الحماية ذات الصلة في كل من شبكة VPC الخاصة بالمستهلك وشبكة 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. إعداد شبكة VPC للمستهلك وCloud NAT والآلات الافتراضية

بعد إنشاء خدمة المنتج، حان الوقت الآن لإنشاء شبكة VPC للمستهلك وبوابة Cloud NAT الخاصة بها.

بعد إنشاء شبكة VPC والشبكة الفرعية، سنضيف قاعدة بسيطة لجدار الحماية الوارد للسماح بنطاقات عناوين IP المصدر لبروتوكول TCP في خدمة IAP. سيسمح لنا ذلك بالاتصال بمثيلات المستهلكين مباشرةً باستخدام gcloud.

بعد ذلك، سننشئ بوابة 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 أولاً (نستخدم رقم نظام مستقل خاص، ولكنّه غير ذي صلة بأنشطة هذا المختبر). من 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 بعد.

لنتأكّد من المنافذ التي خصّصتها خدمة 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"`

بعد ذلك، حاوِل استخدام 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

من المفترض أن تتمكّن من فتح 64 اتصالاً متوازيًا بنجاح، وأن يعرض النص البرمجي ما يلي:

Connection # 64 successful

Loop Done, Sleeping for 150s
Connection # 64 successful

Loop Done, Sleeping for 150s

للتأكّد من أنّه لا يمكننا تجاوز 64 عملية ربط متوازية، عليك الانتظار أولاً لمدة دقيقتَين للسماح بإغلاق جميع المقابس القديمة. بعد ذلك، عدِّل السطر نفسه إلى ما يلي وأعِد تنفيذه

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 ويضبط الحدّ الأدنى لتخصيص المنافذ لكل آلة افتراضية على 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 من تخصيص المنافذ عند زيادة استخدامها، ولكن يستغرق ذلك بعض الوقت ليتم برمجته في جميع أنحاء طبقة الشبكة. لذلك، نرى مهلات اتصال تتراوح بين دقيقة واحدة و3 دقائق قبل أن نكمل بقية محاولات الاتصال بنجاح.

لقد حدّدنا مهلة قصيرة لبرنامج curl (5 ثوانٍ)، ولكن يجب أن تتمكّن التطبيقات التي تتضمّن مهلات أطول من إكمال عمليات الربط بنجاح أثناء زيادة "تخصيص المنافذ الديناميكي" لعمليات تخصيص المنافذ.

يمكن ملاحظة سلوك الزيادة هذا بشكل أكثر وضوحًا عند تشغيل الحلقة لـ 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 اتصالاً. يمكننا اختبار ذلك من خلال إعادة تشغيل حلقة curl بعدد أكبر من 1024 (بعد الانتظار لمدة دقيقتَين لإعادة ضبط المنافذ القديمة).

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

لاحظ كيف تم تخصيص 1024 منفذًا لـ consumer-instance-1، بينما تم تخصيص 64 منفذًا فقط لـ consumer-instance-2. لم يكن ذلك ممكنًا بسهولة قبل DPA، ويوضّح ذلك تمامًا قوة DPA في Cloud NAT.

إذا انتظرت لمدة دقيقتَين قبل إعادة تنفيذ الأمر get-nat-mapping-info، ستلاحظ أنّ 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 الخاص بقاعدة ترجمة عناوين الشبكة (عنوان IP الخاص بـ nat-address-2) يتضمّن 1024 منفذًا. في الوقت نفسه، احتفظت consumer-instance-2 بعمليات التخصيص التلقائية التي تبلغ 64 منفذًا لجميع عناوين IP التي تستخدم ترجمة عناوين الشبكة.

كتمرين، يمكنك اختبار الحالة العكسية. اسمح لخدمة 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 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.

المواضيع التي تناولتها

  • كيفية إعداد بوابة Cloud NAT استعدادًا لـ DPA
  • كيفية فحص عمليات تخصيص المنافذ بدون DPA
  • كيفية تفعيل DPA وإعدادها لبوابة NAT
  • كيفية مراقبة تأثيرات DPA من خلال تشغيل اتصالات خروج متوازية
  • كيفية إضافة قواعد NAT إلى NAT Gateway مع تفعيل DPA
  • كيفية الاطّلاع على سلوك "معالجة البيانات الآلية" باستخدام "القواعد" من خلال تنفيذ عمليات ربط خروج إلى وجهات متعددة

الخطوات التالية

‫©Google, Inc. ‎ أو الشركات التابعة لها. جميع الحقوق محفوظة. يُرجى عدم توزيعها.