שימוש בהקצאה של יציאות דינמיות ב-Cloud NAT

1. סקירה כללית

הקצאה דינמית של יציאות (DPA) היא תכונה חדשה ב-Cloud NAT. כשהתכונה הזו מופעלת, Cloud NAT משנה את הקצאות היציאות למופעים באופן דינמי בהתאם לצורך שלהם. ה-DPA מוגדר עם מגבלות מינימליות ומקסימליות של יציאות, כך שהוא אף פעם לא מצמצם את מספר היציאות מתחת למינימום או מגדיל את מספר היציאות מעבר למקסימום. האפשרות הזו מאפשרת לחלק מהמכונות שמאחורי שערי NAT להגדיל באופן דינמי את מספר החיבורים שלהן, בלי להקצות יותר יציאות לכל המכונות שמאחורי Cloud NAT.

בלי DPA, לכל המכונות שמאחורי Cloud NAT מוקצה אותו מספר יציאות, ללא קשר לשימוש, כפי שמוגדר בפרמטר minPortsPerVm .

מידע נוסף מופיע בקטע בנושא NAT DPA .

מה תלמדו

  • איך מגדירים שער Cloud NAT לקראת DPA.
  • איך בודקים הקצאות של ניודים בלי DPA.
  • איך מפעילים ומגדירים DPA בשער NAT.
  • איך בודקים את ההשפעות של DPA על ידי הפעלת חיבורים מקבילים ליציאה.
  • איך מוסיפים כללי NAT ל-NAT Gateway עם DPA מופעל.
  • איך רואים את ההתנהגות של DPA עם כללים על ידי הפעלת חיבורי יציאה לכמה יעדים.

הדרישות

  • ידע בסיסי ב-Google Compute Engine
  • ידע בסיסי ברישות וב-TCP/IP
  • ידע בסיסי בשורת הפקודה של Unix/Linux
  • מומלץ להשלים סיור מודרך ב-Networking in Google Cloud, כמו המעבדה Networking in Google Cloud.
  • פרויקט בענן של Google עם 'גישת אלפא' מופעלת.
  • הבנה של היסודות של Cloud NAT.

2. שימוש ב-Google Cloud Console וב-Cloud Shell

במהלך שיעור ה-Lab הזה נשתמש גם במסוף Google Cloud וגם ב-Cloud Shell כדי ליצור אינטראקציה עם GCP.

Google Cloud Console

אפשר להיכנס למסוף Cloud בכתובת https://console.cloud.google.com.

75eef5f6fd6d7e41.png

הגדרת סביבה בקצב אישי

  1. נכנסים ל-מסוף Google Cloud ויוצרים פרויקט חדש או משתמשים בפרויקט קיים. אם עדיין אין לכם חשבון Gmail או Google Workspace, אתם צריכים ליצור חשבון.

96a9c957bc475304.pngb9a10ebdf5b5a448.pnga1e3c01a38fa61c2.png

  • שם הפרויקט הוא השם המוצג למשתתפים בפרויקט. זו מחרוזת של תווים שלא נמצאת בשימוש ב-Google APIs, ואפשר לעדכן אותה בכל שלב.
  • מזהה הפרויקט חייב להיות ייחודי לכל הפרויקטים ב-Google Cloud, והוא קבוע (אי אפשר לשנות אותו אחרי שהוא מוגדר). מסוף Cloud יוצר באופן אוטומטי מחרוזת ייחודית. בדרך כלל לא צריך לדעת מה היא. ברוב סדנאות ה-Codelab, תצטרכו להפנות למזהה הפרויקט (ובדרך כלל הוא מזוהה כ-PROJECT_ID), אז אם אתם לא אוהבים אותו, תוכלו ליצור מזהה אקראי אחר, או לנסות ליצור מזהה משלכם ולראות אם הוא זמין. אחרי שהפרויקט נוצר, הוא 'קפוא'.
  • יש ערך שלישי, מספר פרויקט, שמשמש חלק מממשקי ה-API. מידע נוסף על שלושת הערכים האלה מופיע במאמרי העזרה.
  1. בשלב הבא, תצטרכו להפעיל את החיוב במסוף Cloud כדי להשתמש במשאבי Cloud או בממשקי API. העלות של התרגול הזה לא אמורה להיות גבוהה, ואולי לא תהיה עלות בכלל. כדי לכבות את המשאבים ולא לחייב אתכם מעבר למה שמוסבר במדריך הזה, צריך לפעול לפי ההוראות לניקוי שמופיעות בסוף ה-Codelab. משתמשים חדשים ב-Google Cloud זכאים לתוכנית תקופת ניסיון בחינם בשווי 300$.

מפעילים את Cloud Shell

אפשר להפעיל את Google Cloud מרחוק מהמחשב הנייד, אבל ב-Codelab הזה נשתמש ב-Google Cloud Shell, סביבת שורת פקודה שפועלת בענן.

ב-GCP Console, לוחצים על סמל Cloud Shell בסרגל הכלים שבפינה הימנית העליונה:

bce75f34b2c53987.png

הקצאת המשאבים והחיבור לסביבה יימשכו רק כמה רגעים. בסיום התהליך, אמור להופיע משהו כזה:

f6ef2b5f13479f3a.png

המכונה הווירטואלית הזו כוללת את כל הכלים שדרושים למפתחים. יש בה ספריית בית בנפח מתמיד של 5GB והיא פועלת ב-Google Cloud, מה שמשפר מאוד את הביצועים והאימות ברשת. אפשר לבצע את כל העבודה ב-Lab הזה רק באמצעות דפדפן.

3. הגדרת מעבדה

בשיעור ה-Lab הזה תשתמשו בפרויקט ותיצרו שתי רשתות VPC עם תת-רשת בכל אחת מהן. תשמרו כתובות IP חיצוניות, ואז תיצרו ותגדירו שער Cloud NAT (עם Cloud Router), שני מופעים של יצרן ושני מופעים של צרכן. אחרי שתאמתו את התנהגות ברירת המחדל של Cloud NAT, תפעילו הקצאה של יציאות דינמית ותאמתו את ההתנהגות שלה. לבסוף, תגדירו גם כללי NAT ותבחנו את האינטראקציה בין DPA לבין כללי NAT.

סקירה כללית של ארכיטקטורת הרשת:

a21caa6c333909d8.png

4. שמירת כתובות IP חיצוניות

בואו נשמור את כל כתובות ה-IP החיצוניות שבהן נשתמש בשיעור ה-Lab הזה. כך תוכלו לכתוב את כל כללי ה-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

השלב הבא הוא ליצור את שני מופעי היצרן.

במופעי ה-Producer יופעל פריסת proxy פשוטה של 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 ואת תת-הרשת, מוסיפים כלל פשוט של חומת אש לתעבורת נתונים נכנסת כדי לאפשר ל-IAP טווחי כתובות IP של מקור TCP. כך נוכל לבצע SSH ישירות למכונות הצרכן באמצעות gcloud.

לאחר מכן ניצור שער 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 להגיע למופעי הצרכן ביציאה 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.

שימו לב: כברירת מחדל, שער Cloud NAT נוצר עם minPortsPerVm שמוגדר ל-64

יוצרים את מופעי הבדיקה של הצרכנים. אנחנו מאכלסים כאן את כתובות ה-IP השמורות של המפיק כדי שנוכל להתייחס אליהן במופע מאוחר יותר. מתוך Cloud Shell:

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

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

פלט:

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

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

7. אימות התנהגות ברירת המחדל של Cloud NAT

בשלב הזה, המופעים של הלקוח משתמשים בהתנהגות ברירת המחדל של Cloud NAT, שבה נעשה שימוש באותה כתובת IP שמורה nat-address-1 לתקשורת עם כל הכתובות החיצוניות. גם ב-Cloud NAT עדיין לא הופעל DPA.

כדי לבדוק אילו יציאות הוקצו למופעי הצרכן שלנו על ידי Cloud NAT, מריצים את הפקודה הבאה

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

פלט לדוגמה

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

כפי שאפשר לראות בפלט שלמעלה, ‏Cloud NAT הקצה 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 בשני מופעי ה-producer כדי לוודא שאפשר להגיע אליהם בהצלחה.

<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 דקות. לכן, כל עוד אנחנו יכולים לעבור על כל ניסיונות החיבור תוך 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, מגדירה את הקצאת היציאות המינימלית לכל מכונה וירטואלית ל-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 מקרים של פסק זמן לחיבור לפני שאנחנו משלימים בהצלחה את שאר ניסיונות החיבור.

הגדרנו פסק זמן אגרסיבי ל-curl (5 שניות), אבל אפליקציות עם פסק זמן ארוך יותר אמורות להצליח להשלים את החיבורים בזמן שהקצאות היציאות גדלות.

התנהגות ההגדלה הזו נראית בצורה ברורה יותר כשמריצים את הלולאה ל-1,024 ניסיונות חיבור, כמו בדוגמה הבאה

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 עם מספר גבוה מ-1,024 (אחרי שמחכים 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 יציאות לכל מכונה וירטואלית.

אם נצא מסשן ה-SSH ונריץ את get-nat-mapping-info שוב מספיק מהר, נוכל לראות את היציאות הנוספות שהוקצו

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

שימו לב לפלט הבא

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

שימו לב של-consumer-instance-1 הוקצו 1,024 יציאות, אבל ל-consumer-instance-2 הוקצו רק 64 יציאות. לפני DPA, לא הייתה אפשרות כזו בקלות, וזה בדיוק מה שממחיש את העוצמה של DPA עבור Cloud NAT.

אם תחכו 2 דקות לפני שתריצו מחדש את הפקודה get-nat-mapping-info, תראו ש-consumer-instance-1 חזר לערך המינימלי שלו, כלומר הוקצו רק 64 יציאות. הדוגמה הזו ממחישה לא רק את היכולת של DPA להגדיל את הקצאות היציאות, אלא גם לשחרר אותן כשהן לא בשימוש, כדי שמופעים אחרים מאחורי אותו שער NAT יוכלו להשתמש בהן.

9. בדיקת כללי NAT של 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) מוקצים 1,024 פורטים. במהלך התהליך, consumer-instance-2 שמר על הקצאות ברירת המחדל של 64 יציאות לכל כתובות ה-IP של NAT.

כדי להתאמן, אפשר לבדוק את המקרה ההפוך. מאפשרים ל-Cloud NAT לבטל את ההקצאה של כל היציאות הנוספות, ואז מריצים את לולאת ה-curl מול producerip1 ומתבוננים בהשפעות על הפלט של get-nat-mapping-info

10. שלבי הניקוי

כדי להימנע מחיובים חוזרים, צריך למחוק את כל המשאבים שמשויכים ל-codelab הזה.

קודם צריך למחוק את כל המופעים.

מתוך Cloud Shell:

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

הפלט הצפוי :

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

לאחר מכן מוחקים את Cloud Router. מתוך Cloud Shell:

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

הפלט הבא אמור להתקבל :

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

הסרת כל כתובות ה-IP החיצוניות. מתוך Cloud Shell:

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

הפלט הבא אמור להתקבל :

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

מחיקת הכללים של חומת האש ב-VPC. מתוך Cloud Shell:

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

הפלט הבא אמור להתקבל :

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

מחיקת תת-רשתות. מתוך Cloud Shell:

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

הפלט הבא אמור להתקבל :

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

לבסוף, נמחק את רשתות ה-VPC. מתוך Cloud Shell:

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

הפלט הבא אמור להתקבל :

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

‫11. מעולה!

סיימתם את שיעור ה-Lab בנושא Cloud NAT DPA.

מה מכוסה

  • איך מגדירים שער Cloud NAT לקראת DPA.
  • איך בודקים הקצאות של ניודים בלי DPA.
  • איך מפעילים ומגדירים DPA בשער NAT.
  • איך בודקים את ההשפעות של DPA על ידי הפעלת חיבורים מקבילים ליציאה.
  • איך מוסיפים כללי NAT ל-NAT Gateway עם DPA מופעל.
  • איך רואים את ההתנהגות של DPA עם כללים על ידי הפעלת חיבורי יציאה לכמה יעדים.

השלבים הבאים

‫©Google, Inc. או השותפים העצמאיים שלה. כל הזכויות שמורות. אין להפיץ.